Search in sources :

Example 1 with ITextRegionCollection

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection in project webtools.sourceediting by eclipse.

the class AbstractLineStyleProvider method prepareTextRegion.

/**
 * @param region
 * @param start
 * @param length
 * @param holdResults
 * @return
 */
private boolean prepareTextRegion(ITextRegionCollection blockedRegion, int partitionStartOffset, int partitionLength, Collection holdResults) {
    boolean handled = false;
    final int partitionEndOffset = partitionStartOffset + partitionLength - 1;
    ITextRegion region = null;
    ITextRegionList regions = blockedRegion.getRegions();
    int nRegions = regions.size();
    StyleRange styleRange = null;
    for (int i = 0; i < nRegions; i++) {
        region = regions.get(i);
        TextAttribute attr = null;
        TextAttribute previousAttr = null;
        if (blockedRegion.getStartOffset(region) > partitionEndOffset)
            break;
        if (blockedRegion.getEndOffset(region) <= partitionStartOffset)
            continue;
        if (region instanceof ITextRegionCollection) {
            handled = prepareTextRegion((ITextRegionCollection) region, partitionStartOffset, partitionLength, holdResults);
        } else {
            attr = getAttributeFor(blockedRegion, region);
            if (attr != null) {
                handled = true;
                // regions correctly
                if ((styleRange != null) && (previousAttr != null) && (previousAttr.equals(attr))) {
                    styleRange.length += region.getLength();
                } else {
                    styleRange = createStyleRange(blockedRegion, region, attr, partitionStartOffset, partitionLength);
                    holdResults.add(styleRange);
                    // technically speaking, we don't need to update
                    // previousAttr
                    // in the other case, because the other case is when
                    // it hasn't changed
                    previousAttr = attr;
                }
            } else {
                previousAttr = null;
            }
        }
    }
    return handled;
}
Also used : ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) TextAttribute(org.eclipse.jface.text.TextAttribute) StyleRange(org.eclipse.swt.custom.StyleRange) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection)

Example 2 with ITextRegionCollection

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection in project webtools.sourceediting by eclipse.

the class JsTranslator method translateJSNode.

/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#translateJSNode(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)
	 */
public void translateJSNode(IStructuredDocumentRegion container) {
    if (container == null)
        return;
    ITextRegionCollection containerRegion = container;
    Iterator regions = containerRegion.getRegions().iterator();
    ITextRegion region = null;
    char[] spaces = Util.getPad(container.getStartOffset() - scriptOffset);
    for (int i = 0; i < spaces.length; i++) {
        try {
            char c = fStructuredDocument.getChar(scriptOffset + i);
            if (c == '\n' || c == '\r' || c == '\t')
                spaces[i] = c;
        } catch (BadLocationException e) {
            Logger.logException(e);
        }
    }
    fScriptText.append(spaces);
    scriptOffset = container.getStartOffset();
    if (container.getType() != DOMRegionContext.BLOCK_TEXT && container.getType() != DOMRegionContext.XML_CDATA_TEXT) {
        // add place holder in position map (for formatting)
        appendAndTrack("", scriptOffset);
        return;
    }
    while (regions.hasNext() && !isCanceled()) {
        region = (ITextRegion) regions.next();
        String type = region.getType();
        // content assist was not showing up in JSP inside a javascript
        // region
        // System.out.println("Region text: " + container.getText().substring(region.getStart(), region.getEnd()));
        boolean isContainerRegion = region instanceof ITextRegionContainer;
        /* make sure its not a sub container region, probably JSP */
        if (type == DOMRegionContext.BLOCK_TEXT) {
            int scriptStartOffset = container.getStartOffset(region);
            int scriptTextLength = container.getLength();
            String regionText = container.getFullText(region);
            // regionText = StringUtils.replace(regionText, CDATA_START, CDATA_START_PAD);
            // regionText = StringUtils.replace(regionText, CDATA_END, CDATA_END_PAD);
            int regionLength = region.getLength();
            spaces = Util.getPad(scriptStartOffset - scriptOffset);
            for (int i = 0; i < spaces.length; i++) {
                try {
                    char c = fStructuredDocument.getChar(scriptOffset + i);
                    if (c == '\n' || c == '\r' || c == '\t')
                        spaces[i] = c;
                } catch (BadLocationException e) {
                    Logger.logException(e);
                }
            }
            fScriptText.append(spaces);
            // skip over XML/HTML comment starts
            if (regionText.indexOf(XML_COMMENT_START) >= 0) {
                int index = regionText.indexOf(XML_COMMENT_START);
                boolean replaceCommentStart = true;
                for (int i = 0; i < index; i++) {
                    /*
						 * replace the comment start in the translation when
						 * it's preceded only by white space or '/'
						 */
                    replaceCommentStart = replaceCommentStart && (Character.isWhitespace(regionText.charAt(i)) || '/' == regionText.charAt(i));
                }
                if (replaceCommentStart) {
                    IRegion line;
                    int end;
                    int length;
                    try {
                        /*
							 * try to find where the line with the comment
							 * ends (it is the end of what we'll replace)
							 */
                        line = container.getParentDocument().getLineInformationOfOffset(index + scriptStartOffset);
                        end = line.getOffset() + line.getLength() - scriptStartOffset;
                        if (end > regionText.length()) {
                            end = regionText.length();
                        }
                        length = end - index;
                    } catch (BadLocationException e) {
                        // $NON-NLS-1$
                        Logger.logException("Could not get web page's comment line information", e);
                        end = index + XML_COMMENT_START.length();
                        length = XML_COMMENT_START.length();
                    }
                    scriptStartOffset += end;
                    regionText = regionText.substring(end);
                    appendAndTrack(new String(Util.getPad(end)), fScriptText.length());
                }
            }
            /*
				 * Fix for
				 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=284774
				 * end of last valid JS source, start of next content to
				 * skip
				 */
            // last offset of valid JS source, after which there's server-side stuff
            int validJSend = 0;
            // start of next valid JS source, last offset of content that was skipped
            int validJSstart = 0;
            Matcher matcher = fClientSideTagPattern.matcher(regionText);
            // note the start of a HTML tag if one's present
            int clientMatchStart = matcher.find() ? matcher.start() : -1;
            StringBuffer generatedContent = new StringBuffer();
            int serverSideStart = -1;
            int serverSideDelimiter = 0;
            // find any instance of server code blocks in the region text
            for (int i = 0; i < fServerSideDelimiters.length; i++) {
                int index = regionText.indexOf(fServerSideDelimiters[i][0]);
                if (serverSideStart < 0) {
                    serverSideStart = index;
                    serverSideDelimiter = i;
                } else if (index >= 0) {
                    serverSideStart = Math.min(serverSideStart, index);
                    if (serverSideStart == index) {
                        serverSideDelimiter = i;
                    }
                }
            }
            // contains something other than pure JavaScript
            while (serverSideStart > -1 || clientMatchStart > -1) {
                // $NON-NLS-1$
                validJSend = validJSstart;
                boolean biasClient = false;
                boolean biasServer = false;
                // update the start of content to skip
                if (clientMatchStart > -1 && serverSideStart > -1) {
                    validJSend = Math.min(clientMatchStart, serverSideStart);
                    biasClient = validJSend == clientMatchStart;
                    biasServer = validJSend == serverSideStart;
                } else if (clientMatchStart > -1 && serverSideStart < 0) {
                    validJSend = clientMatchStart;
                    biasClient = true;
                } else if (clientMatchStart < 0 && serverSideStart > -1) {
                    validJSend = serverSideStart;
                    biasServer = true;
                }
                // append if there's something we want to include
                if (-1 < validJSstart && -1 < validJSend) {
                    // append what we want to include
                    appendAndTrack(regionText.substring(validJSstart, validJSend), scriptStartOffset + validJSstart);
                    // change the skipped content to a valid variable name and append it as a placeholder
                    int startOffset = scriptStartOffset + validJSend;
                    String serverEnd = fServerSideDelimiters[serverSideDelimiter][1];
                    int serverSideEnd = (regionLength > validJSend + serverEnd.length()) ? regionText.indexOf(serverEnd, validJSend + fServerSideDelimiters[serverSideDelimiter][1].length()) : -1;
                    if (serverSideEnd > -1)
                        serverSideEnd += serverEnd.length();
                    int clientMatchEnd = matcher.find(validJSend) ? matcher.end() : -1;
                    // update end of what we skipped
                    validJSstart = -1;
                    if (clientMatchEnd > validJSend && serverSideEnd > validJSend) {
                        if (biasClient)
                            validJSstart = clientMatchEnd;
                        else if (biasServer)
                            validJSstart = serverSideEnd;
                        else
                            validJSstart = Math.min(clientMatchEnd, serverSideEnd);
                    }
                    if (clientMatchEnd >= validJSend && serverSideEnd < 0)
                        validJSstart = matcher.end();
                    if (clientMatchEnd < 0 && serverSideEnd >= validJSend)
                        validJSstart = serverSideEnd;
                    /*
						 * the substitution text length much match original
						 * length exactly, generate text of the right length
						 */
                    int start = scriptStartOffset + validJSend;
                    int end = scriptStartOffset + validJSstart;
                    generatedContent.append('_');
                    for (int i = validJSend + 1; i < validJSstart; i++) {
                        switch(i - validJSend) {
                            case 1:
                                generatedContent.append('$');
                                break;
                            case 2:
                                generatedContent.append('t');
                                break;
                            case 3:
                                generatedContent.append('a');
                                break;
                            case 4:
                                generatedContent.append('g');
                                break;
                            default:
                                generatedContent.append('_');
                        }
                    }
                    /*
						 * Remember this source range, it may be needed to
						 * find the original contents for which we're
						 * placeholding
						 */
                    fGeneratedRanges.add(new Region(start, end - start));
                    appendAndTrack(generatedContent.toString(), start);
                    // reset now that it's been appended
                    generatedContent.setLength(0);
                }
                // set up to end while if no end for valid
                if (validJSstart > 0) {
                    int serverSideStartGuess = -1;
                    for (int i = 0; i < fServerSideDelimiters.length; i++) {
                        int index = regionText.indexOf(fServerSideDelimiters[i][0], validJSstart);
                        if (serverSideStartGuess < 0) {
                            serverSideStartGuess = index;
                            serverSideDelimiter = i;
                        } else if (index >= 0) {
                            serverSideStartGuess = Math.min(serverSideStartGuess, index);
                            if (serverSideStartGuess == index) {
                                serverSideDelimiter = i;
                            }
                        }
                    }
                    serverSideStart = validJSstart < regionLength - fShortestServerSideDelimiterPairLength ? serverSideStartGuess : -1;
                    clientMatchStart = validJSstart < regionLength ? (matcher.find(validJSstart) ? matcher.start() : -1) : -1;
                } else {
                    serverSideStart = clientMatchStart = -1;
                }
            }
            if (validJSstart >= 0) {
                appendAndTrack(regionText.substring(validJSstart), scriptStartOffset + validJSstart);
                Position inHtml = new Position(scriptStartOffset + validJSstart, regionText.length() - validJSstart);
                scriptLocationInHtml.add(inHtml);
            } else {
                appendAndTrack(regionText, scriptStartOffset);
                Position inHtml = new Position(scriptStartOffset, regionText.length());
                scriptLocationInHtml.add(inHtml);
            }
            scriptOffset = fScriptText.length();
        }
    }
    IStructuredDocumentRegion endTag = container.getNext();
    if (endTag == null) {
        missingEndTagRegionStart = container.getStartOffset();
    } else if (endTag != null) {
        NodeHelper nh = new NodeHelper(endTag);
        String name = nh.getTagName();
        if (name == null || !name.trim().equalsIgnoreCase("script") || !nh.isEndTag()) {
            // $NON-NLS-1$
            missingEndTagRegionStart = container.getStartOffset();
        }
    }
}
Also used : IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) Matcher(java.util.regex.Matcher) Position(org.eclipse.jface.text.Position) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer) IRegion(org.eclipse.jface.text.IRegion) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Iterator(java.util.Iterator) Region(org.eclipse.jface.text.Region) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) IRegion(org.eclipse.jface.text.IRegion) IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) BadLocationException(org.eclipse.jface.text.BadLocationException)

Example 3 with ITextRegionCollection

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection in project webtools.sourceediting by eclipse.

the class JSPTranslator method translateRegionContainer.

/**
 * translates a region container (and XML JSP container, or <% JSP
 * container)
 *
 * This method should only be called in this class and for containers in
 * the primary structured document as all buffer appends will be direct
 */
protected void translateRegionContainer(ITextRegionCollection container, int JSPType) {
    ITextRegionCollection containerRegion = container;
    Iterator regions = containerRegion.getRegions().iterator();
    ITextRegion region = null;
    while (regions.hasNext()) {
        region = (ITextRegion) regions.next();
        String type = region.getType();
        // content assist was not showing up in JSP inside a javascript region
        if (DOMRegionContext.BLOCK_TEXT == type) {
            // check if it's nested jsp in a script tag...
            if (region instanceof ITextRegionContainer) {
                // pass in block text's container & iterator
                Iterator regionIterator = ((ITextRegionCollection) region).getRegions().iterator();
                translateJSPNode(region, regionIterator, type, EMBEDDED_JSP);
            } else {
                // be sure to combine all of the text from the block region
                StringBuffer fullText = new StringBuffer(containerRegion.getFullText(region));
                while (regions.hasNext()) {
                    region = (ITextRegion) regions.next();
                    // Do not immediately translate container regions, since they may use variables declared within the full text
                    if (region.getType() == DOMRegionContext.BLOCK_TEXT) {
                        fullText.append(containerRegion.getFullText(region));
                    } else {
                        // update type for when we exit if statement for BLOCK_TEXT
                        type = region.getType();
                        break;
                    }
                }
                /**
                 * LIMITATION - Normally the script content within a
                 * script tag is a single document region with a single
                 * BLOCK_TEXT text region within it. Any JSP scripting
                 * will be within its own region container (for the sake
                 * of keeping the scripting open/content/end as a group)
                 * also of BLOCK_TEXT. That ignores custom tags that might
                 * be in there, though, as they require proper scoping and
                 * variable declaration to be performed even though
                 * they're not proper nodes in the DOM. The only way to
                 * really do this is to treat the entire script content as
                 * JSP content on its own, akin to an included segment.
                 * Further complicating this solution is that tagdependent
                 * custom tags have their comment marked as BLOCK_TEXT as
                 * well, so there's no clear way to tell the two cases
                 * apart.
                 */
                // ////////////////////////////////////////////////////////////////////////////////
                // THIS EMBEDDED JSP TEXT WILL COME OUT LATER WHEN
                // PARTITIONING HAS
                // SUPPORT FOR NESTED XML-JSP
                // CMVC 241882
                decodeScriptBlock(fullText.toString(), containerRegion.getStartOffset());
            // ////////////////////////////////////////////////////////////////////////////////
            }
        }
        // }
        if (// <%, <%=, <%!, <%@
        type != null && isJSP(type)) {
            // translateJSPNode(region, regions, type, JSPType);
            translateJSPNode(containerRegion, regions, type, JSPType);
        } else if (type != null && (type == DOMRegionContext.XML_TAG_OPEN || type == DOMRegionContext.XML_END_TAG_OPEN)) {
            translateXMLNode(containerRegion, regions);
        } else if (type != null && type == DOMRegionContext.XML_CONTENT && region instanceof ITextRegionContainer) {
            // this case was put in to parse EL that is not in an attribute
            translateXMLContent((ITextRegionContainer) region);
        } else // the end tags of these regions are "translated" in a sense
        if (type == DOMJSPRegionContexts.JSP_DIRECTIVE_CLOSE || type == DOMJSPRegionContexts.JSP_CLOSE) {
            this.fCodeTranslated = true;
        }
    }
}
Also used : ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Iterator(java.util.Iterator) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection) ITextRegionContainer(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer)

Example 4 with ITextRegionCollection

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection in project webtools.sourceediting by eclipse.

the class JSPELValidator method validateRegionContainer.

protected void validateRegionContainer(ITextRegionCollection container, IReporter reporter, IFile file) {
    ITextRegionCollection containerRegion = container;
    Iterator regions = containerRegion.getRegions().iterator();
    ITextRegion region = null;
    while (regions.hasNext() && !reporter.isCancelled()) {
        region = (ITextRegion) regions.next();
        String type = region.getType();
        if (type != null && region instanceof ITextRegionCollection) {
            ITextRegionCollection parentRegion = ((ITextRegionCollection) region);
            Iterator childRegions = parentRegion.getRegions().iterator();
            while (childRegions.hasNext() && !reporter.isCancelled()) {
                ITextRegion childRegion = (ITextRegion) childRegions.next();
                /* [136795] Validate everything in the EL container, not just JSP_EL_CONTENT */
                if (childRegion.getType() == DOMJSPRegionContexts.JSP_EL_OPEN)
                    validateELContent(parentRegion, childRegion, childRegions, reporter, file);
            }
        }
    }
}
Also used : ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) Iterator(java.util.Iterator) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection)

Example 5 with ITextRegionCollection

use of org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection in project webtools.sourceediting by eclipse.

the class JSPDirectiveValidator method reportTaglibDuplicatePrefixes.

private void reportTaglibDuplicatePrefixes(IFile file, IReporter reporter, IStructuredDocument document) {
    if (fSeverityTaglibDuplicatePrefixWithDifferentURIs == ValidationMessage.IGNORE && fSeverityTaglibDuplicatePrefixWithSameURIs == ValidationMessage.IGNORE)
        return;
    String[] prefixes = (String[]) fTaglibPrefixesInUse.keySet().toArray(new String[0]);
    for (int prefixNumber = 0; prefixNumber < prefixes.length; prefixNumber++) {
        int severity = fSeverityTaglibDuplicatePrefixWithSameURIs;
        Object o = fTaglibPrefixesInUse.get(prefixes[prefixNumber]);
        /*
			 * Only care if it's a List (because there was more than one
			 * directive with that prefix) and if we're supposed to report
			 * duplicates
			 */
        if (o instanceof List) {
            List valueRegions = (List) o;
            String uri = null;
            for (int regionNumber = 0; regionNumber < valueRegions.size(); regionNumber++) {
                ITextRegionCollection documentRegion = (ITextRegionCollection) fPrefixValueRegionToDocumentRegionMap.get(valueRegions.get(regionNumber));
                ITextRegion uriValueRegion = getAttributeValueRegion(documentRegion, JSP11Namespace.ATTR_NAME_URI);
                if (uriValueRegion == null) {
                    uriValueRegion = getAttributeValueRegion(documentRegion, JSP20Namespace.ATTR_NAME_TAGDIR);
                }
                if (uriValueRegion != null) {
                    String uri2 = StringUtils.stripQuotes(documentRegion.getText(uriValueRegion));
                    if (uri == null) {
                        uri = uri2;
                    } else {
                        if (collator.compare(uri, uri2) != 0) {
                            severity = fSeverityTaglibDuplicatePrefixWithDifferentURIs;
                        }
                    }
                }
            }
            if (severity != ValidationMessage.IGNORE) {
                // $NON-NLS-2$ //$NON-NLS-1$
                String msgText = NLS.bind(JSPCoreMessages.JSPDirectiveValidator_2, prefixes[prefixNumber]);
                // Report an error in all directives using this prefix
                for (int regionNumber = 0; regionNumber < valueRegions.size(); regionNumber++) {
                    ITextRegion valueRegion = (ITextRegion) valueRegions.get(regionNumber);
                    ITextRegionCollection documentRegion = (ITextRegionCollection) fPrefixValueRegionToDocumentRegionMap.get(valueRegion);
                    LocalizedMessage message = (file == null ? new LocalizedMessage(severity, msgText) : new LocalizedMessage(severity, msgText, file));
                    // if there's a message, there was an error found
                    int start = documentRegion.getStartOffset(valueRegion);
                    int length = valueRegion.getTextLength();
                    int lineNo = document.getLineOfOffset(start);
                    message.setLineNo(lineNo + 1);
                    message.setOffset(start);
                    message.setLength(length);
                    reporter.addMessage(fMessageOriginator, message);
                }
            }
        }
    }
}
Also used : ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) List(java.util.List) ArrayList(java.util.ArrayList) ITextRegionCollection(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection)

Aggregations

ITextRegionCollection (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection)20 ITextRegion (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion)16 ITextRegionList (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList)8 Iterator (java.util.Iterator)7 TextAttribute (org.eclipse.jface.text.TextAttribute)4 StyleRange (org.eclipse.swt.custom.StyleRange)4 IStructuredDocumentRegion (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)3 IStructuredDocumentRegionList (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList)3 ITextRegionContainer (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 BadLocationException (org.eclipse.jface.text.BadLocationException)2 Enumeration (java.util.Enumeration)1 HashMap (java.util.HashMap)1 Matcher (java.util.regex.Matcher)1 IExtensionPoint (org.eclipse.core.runtime.IExtensionPoint)1 IRegion (org.eclipse.jface.text.IRegion)1 Position (org.eclipse.jface.text.Position)1 Region (org.eclipse.jface.text.Region)1 ZeroStructuredDocumentRegion (org.eclipse.jst.jsp.core.internal.util.ZeroStructuredDocumentRegion)1