From 62a8a5cd76a7dd33887af32d98cc07b39fae9ae8 Mon Sep 17 00:00:00 2001 From: robekras Date: Mon, 24 Dec 2012 16:44:28 +0100 Subject: [PATCH 1/1] 1) Fixed issue #215: Escaping Strings Signed-off-by: robekras --- .../phpeclipse/phpeditor/PHPUnitEditor.java | 426 +++++++++++--------- 1 files changed, 240 insertions(+), 186 deletions(-) diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java index f56b6d9..d79be69 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java @@ -374,9 +374,9 @@ public class PHPUnitEditor extends PHPEditor { // implements protected void customizeDocumentCommand(DocumentCommand command) { super.customizeDocumentCommand(command); if (!fIgnoreTextConverters && fTextConverters != null) { - for (Iterator e = fTextConverters.iterator(); e.hasNext();) - ((ITextConverter) e.next()).customizeDocumentCommand( - getDocument(), command); + for (Iterator e = fTextConverters.iterator(); e.hasNext();) { + ((ITextConverter) e.next()).customizeDocumentCommand (getDocument(), command); + } } } @@ -434,13 +434,11 @@ public class PHPUnitEditor extends PHPEditor { // implements // fCorrectionAssistant = new // JavaCorrectionAssistant(CompilationUnitEditor.this); // fCorrectionAssistant.install(this); - IAutoEditStrategy smartSemi = new SmartSemicolonAutoEditStrategy( - IPHPPartitions.PHP_PARTITIONING); + IAutoEditStrategy smartSemi = new SmartSemicolonAutoEditStrategy (IPHPPartitions.PHP_PARTITIONING); prependAutoEditStrategy(smartSemi, IDocument.DEFAULT_CONTENT_TYPE); prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_DQ); prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_SQ); - prependAutoEditStrategy(smartSemi, - IPHPPartitions.PHP_STRING_HEREDOC); + prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_HEREDOC); fUndoManager.setMaximalUndoLevel (this.getUndoHistorySize ()); // Set every editor to the global 'Undo history size' } @@ -984,8 +982,7 @@ public class PHPUnitEditor extends PHPEditor { // implements // LinkedPositionUI fEditor; // }; - private class BracketInserter implements VerifyKeyListener, - LinkedPositionUI.ExitListener { + private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener { private boolean fCloseBracketsPHP = true; private boolean fCloseStringsPHPDQ = true; @@ -1008,16 +1005,26 @@ public class PHPUnitEditor extends PHPEditor { // implements fCloseStringsPHPSQ = enabled; } - private boolean hasIdentifierToTheRight(IDocument document, int offset) { + /** + * Check whether there is a possible identifier to the right + * + * @param document The source file which the user is currently modifying + * @param offset The position we want to check whether there is a possible identifier to the right + * @return + */ + private boolean hasIdentifierToTheRight (IDocument document, int offset) { try { - int end = offset; - IRegion endLine = document.getLineInformationOfOffset(end); - int maxEnd = endLine.getOffset() + endLine.getLength(); - while (end != maxEnd - && Character.isWhitespace(document.getChar(end))) - ++end; - return end != maxEnd - && Scanner.isPHPIdentifierPart(document.getChar(end)); + int posToCheck = offset; + IRegion endLine = document.getLineInformationOfOffset(posToCheck); + int endOfLine = endLine.getOffset() + endLine.getLength(); + + while ((posToCheck != endOfLine) && // As long as we are at the current line + (Character.isWhitespace(document.getChar (posToCheck)))) { // and the character is a white space + ++posToCheck; // Go for the next position to check + } + + return (posToCheck != endOfLine) && // If it not the end of line + Scanner.isPHPIdentifierPart(document.getChar(posToCheck)); // and it could be a identifier } catch (BadLocationException e) { // be conservative return true; @@ -1033,38 +1040,38 @@ public class PHPUnitEditor extends PHPEditor { // implements // && Character.isWhitespace(document.getChar(start - 1))) // --start; // return start != minStart -// && Scanner.isPHPIdentifierPart(document -// .getChar(start - 1)); +// && Scanner.isPHPIdentifierPart(document.getChar(start - 1)); // } catch (BadLocationException e) { // return true; // } // } - private boolean hasCharacterToTheLeft(IDocument document, int offset, - char character) { + private boolean hasCharacterToTheLeft (IDocument document, int offset, char character) { try { int start = offset; IRegion startLine = document.getLineInformationOfOffset(start); int minStart = startLine.getOffset(); - while (start != minStart - && Character.isWhitespace(document.getChar(start - 1))) + + while (start != minStart && Character.isWhitespace(document.getChar(start - 1))) { --start; - return start != minStart - && document.getChar(start - 1) == character; + } + + return start != minStart && document.getChar(start - 1) == character; } catch (BadLocationException e) { return false; } } - private boolean hasCharacterToTheRight(IDocument document, int offset, - char character) { + private boolean hasCharacterToTheRight (IDocument document, int offset, char character) { try { int end = offset; IRegion endLine = document.getLineInformationOfOffset(end); int maxEnd = endLine.getOffset() + endLine.getLength(); - while (end != maxEnd - && Character.isWhitespace(document.getChar(end))) + + while (end != maxEnd && Character.isWhitespace(document.getChar(end))) { ++end; + } + return end != maxEnd && document.getChar(end) == character; } catch (BadLocationException e) { // be conservative @@ -1072,170 +1079,216 @@ public class PHPUnitEditor extends PHPEditor { // implements } } + private boolean hasEscapeCharToTheLeft (IDocument document, int offset) { + try { + int posToCheck = offset; + IRegion currentLine = document.getLineInformationOfOffset (posToCheck); + int startOfLine = currentLine.getOffset (); + int numberOfEscapes = 0; + + posToCheck--; // Set to the previous character + + while (posToCheck > startOfLine) { // while we are within the current line + if (document.getChar (posToCheck) == '\\') { // If the character is a escape char + numberOfEscapes++; // Count it + } + else { // If we found the first non escape char + break; // Leave counting + } + + posToCheck--; // Go for the next previous character + } + + if ((numberOfEscapes % 2) == 1) { // If we have a odd number of escape characters, + return true; // the current character is escaped. + } + + return false; + } catch (BadLocationException e) { + // be conservative + return true; + } + } + /* * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent) */ public void verifyKey(VerifyEvent event) { if (!event.doit) return; + final ISourceViewer sourceViewer = getSourceViewer(); IDocument document = sourceViewer.getDocument(); final Point selection = sourceViewer.getSelectedRange(); final int offset = selection.x; final int length = selection.y; + try { ITypedRegion partition = document.getPartition(offset); String type = partition.getType(); - if (type.equals(IPHPPartitions.PHP_PARTITIONING) - || type.equals(IDocument.DEFAULT_CONTENT_TYPE)) { - // you will get IDocument.DEFAULT_CONTENT_TYPE for both PHP - // and HTML area + + if (type.equals(IPHPPartitions.PHP_PARTITIONING) || type.equals(IDocument.DEFAULT_CONTENT_TYPE)) { + // you will get IDocument.DEFAULT_CONTENT_TYPE for both PHP and HTML area switch (event.character) { - case '(': - if (hasCharacterToTheRight(document, offset + length, - '(')) - return; - // fall through - case '[': - if (!fCloseBracketsPHP) - return; - if (hasIdentifierToTheRight(document, offset + length)) - return; - // fall through - case '{': - if (!fCloseBracketsPHP) - return; - if (hasIdentifierToTheRight(document, offset + length)) - return; - // fall through - case '"': - if (event.character == '"') { - if (!fCloseStringsPHPDQ) + case '(': + if (hasCharacterToTheRight (document, offset + length, '(')) return; - // changed for statements like echo "" print "" - // if (hasIdentifierToTheLeft(document, offset) - // || - // hasIdentifierToTheRight(document, offset + - // length)) - if (hasIdentifierToTheRight(document, offset - + length)) + // fall through + case '[': + if (!fCloseBracketsPHP) return; - } - // ITypedRegion partition= - // document.getPartition(offset); - // if (! - // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) - // && - // (partition.getOffset() != offset)) - // return; - final char characterDQ = event.character; - final char closingCharacterDQ = getPeerCharacter(characterDQ); - final StringBuffer bufferDQ = new StringBuffer(); - bufferDQ.append(characterDQ); - bufferDQ.append(closingCharacterDQ); - document.replace(offset, length, bufferDQ.toString()); - LinkedPositionManager managerDQ = new LinkedPositionManager( - document); - managerDQ.addPosition(offset + 1, 0); - fOffset = offset; - fLength = 2; - LinkedPositionUI editorDQ = new LinkedPositionUI( - sourceViewer, managerDQ); - editorDQ.setCancelListener(this); - editorDQ.setExitPolicy(new ExitPolicy( - closingCharacterDQ)); - editorDQ.setFinalCaretOffset(offset + 2); - editorDQ.enter(); - IRegion newSelectionDQ = editorDQ.getSelectedRegion(); - sourceViewer.setSelectedRange(newSelectionDQ - .getOffset(), newSelectionDQ.getLength()); - event.doit = false; - break; - case '\'': - if (event.character == '\'') { - if (!fCloseStringsPHPSQ) + if (hasIdentifierToTheRight (document, offset + length)) return; - // changed for statements like echo "" print "" - // if (hasIdentifierToTheLeft(document, offset) - // || - // hasIdentifierToTheRight(document, offset + - // length)) - if (hasIdentifierToTheRight(document, offset - + length)) + // fall through + case '{': + if (!fCloseBracketsPHP) return; - } - // ITypedRegion partition= - // document.getPartition(offset); - // if (! - // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) - // && - // (partition.getOffset() != offset)) - // return; - final char characterSQ = event.character; - final char closingCharacterSQ = getPeerCharacter(characterSQ); - final StringBuffer bufferSQ = new StringBuffer(); - bufferSQ.append(characterSQ); - bufferSQ.append(closingCharacterSQ); - document.replace(offset, length, bufferSQ.toString()); - LinkedPositionManager managerSQ = new LinkedPositionManager( - document); - managerSQ.addPosition(offset + 1, 0); - fOffset = offset; - fLength = 2; - LinkedPositionUI editorSQ = new LinkedPositionUI( - sourceViewer, managerSQ); - editorSQ.setCancelListener(this); - editorSQ.setExitPolicy(new ExitPolicy( - closingCharacterSQ)); - editorSQ.setFinalCaretOffset(offset + 2); - editorSQ.enter(); - IRegion newSelectionSQ = editorSQ.getSelectedRegion(); - sourceViewer.setSelectedRange(newSelectionSQ - .getOffset(), newSelectionSQ.getLength()); - event.doit = false; - case '\r': { // insert linebreaks and new closing brace - // after brace and return - if (!fCloseBracketsPHP) { - return; - } - if (hasCharacterToTheLeft(document, offset, '{') - && hasCharacterToTheRight(document, offset, '}')) { - String lineDelimiter = StubUtility - .getLineDelimiterFor(document); - int caretPos = sourceViewer.getTextWidget() - .getCaretOffset(); - final StringBuffer buffer = new StringBuffer( - lineDelimiter); - // get indentation - IRegion line = document - .getLineInformationOfOffset(offset); - String currentLine = document.get(line.getOffset(), - line.getLength()); - int index = 0; - int max = currentLine.length(); - StringBuffer indent = new StringBuffer(); - while (index < max - && Character.isWhitespace(currentLine - .charAt(index))) { - indent.append(currentLine.charAt(index)); - index++; + if (hasIdentifierToTheRight (document, offset + length)) + return; + // fall through + case '"': + if (event.character == '"') { + if (!fCloseStringsPHPDQ) { + return; + } + + // changed for statements like echo "" print "" + // if (hasIdentifierToTheLeft(document, offset) + // || + // hasIdentifierToTheRight(document, offset + + // length)) + + if (hasIdentifierToTheRight (document, offset + length)) { + return; + } + + // We should check here whether the previous character of the typed '"' is a '\'. + // In this case we should not issue a closing " + + if (hasEscapeCharToTheLeft (document, offset + length)) { + return; + } } - buffer.append(indent); - JavaHeuristicScanner scanner = new JavaHeuristicScanner( - document); - JavaIndenter indenter = new JavaIndenter(document, - scanner); - buffer.append(indenter.createIndent(1)); - int cursorPos = buffer.length(); - buffer.append(lineDelimiter); - buffer.append(indent); - document.replace(offset, length, buffer.toString()); - sourceViewer.getTextWidget().setCaretOffset( - caretPos + cursorPos); + + // ITypedRegion partition= + // document.getPartition(offset); + // if (! + // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) + // && + // (partition.getOffset() != offset)) + // return; + + final char characterDQ = event.character; + final char closingCharacterDQ = getPeerCharacter (characterDQ); + final StringBuffer bufferDQ = new StringBuffer (); + + bufferDQ.append (characterDQ); + bufferDQ.append (closingCharacterDQ); + document.replace (offset, length, bufferDQ.toString ()); + LinkedPositionManager managerDQ = new LinkedPositionManager (document); + managerDQ.addPosition (offset + 1, 0); + + fOffset = offset; + fLength = 2; + + LinkedPositionUI editorDQ = new LinkedPositionUI (sourceViewer, managerDQ); + editorDQ.setCancelListener (this); + editorDQ.setExitPolicy (new ExitPolicy (closingCharacterDQ)); + editorDQ.setFinalCaretOffset (offset + 2); + editorDQ.enter (); + + IRegion newSelectionDQ = editorDQ.getSelectedRegion (); + sourceViewer.setSelectedRange (newSelectionDQ.getOffset(), newSelectionDQ.getLength()); event.doit = false; + break; + + case '\'': + if (event.character == '\'') { + if (!fCloseStringsPHPSQ) { + return; + } + + // changed for statements like echo "" print "" + // if (hasIdentifierToTheLeft(document, offset) + // || + // hasIdentifierToTheRight(document, offset + + // length)) + if (hasIdentifierToTheRight(document, offset + length)) { + return; + } + + // We should check here whether the previous character of the typed '"' is a '\'. + // In this case we should not issue a closing " + + if (hasEscapeCharToTheLeft (document, offset + length)) { + return; + } + } + // ITypedRegion partition= + // document.getPartition(offset); + // if (! + // IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) + // && + // (partition.getOffset() != offset)) + // return; + final char characterSQ = event.character; + final char closingCharacterSQ = getPeerCharacter (characterSQ); + final StringBuffer bufferSQ = new StringBuffer (); + + bufferSQ.append (characterSQ); + bufferSQ.append (closingCharacterSQ); + document.replace (offset, length, bufferSQ.toString ()); + + LinkedPositionManager managerSQ = new LinkedPositionManager (document); + managerSQ.addPosition (offset + 1, 0); + + fOffset = offset; + fLength = 2; + + LinkedPositionUI editorSQ = new LinkedPositionUI (sourceViewer, managerSQ); + editorSQ.setCancelListener (this); + editorSQ.setExitPolicy (new ExitPolicy (closingCharacterSQ)); + editorSQ.setFinalCaretOffset (offset + 2); + editorSQ.enter (); + + IRegion newSelectionSQ = editorSQ.getSelectedRegion (); + sourceViewer.setSelectedRange (newSelectionSQ.getOffset(), newSelectionSQ.getLength()); + event.doit = false; + case '\r': { // insert linebreaks and new closing brace after brace and return + if (!fCloseBracketsPHP) { + return; + } + + if (hasCharacterToTheLeft(document, offset, '{') && hasCharacterToTheRight(document, offset, '}')) { + String lineDelimiter = StubUtility.getLineDelimiterFor(document); + int caretPos = sourceViewer.getTextWidget().getCaretOffset(); + final StringBuffer buffer = new StringBuffer(lineDelimiter); + // get indentation + IRegion line = document.getLineInformationOfOffset(offset); + String currentLine = document.get(line.getOffset(),line.getLength()); + int index = 0; + int max = currentLine.length(); + StringBuffer indent = new StringBuffer(); + + while (index < max + && Character.isWhitespace(currentLine.charAt(index))) { + indent.append(currentLine.charAt(index)); + index++; + } + + buffer.append(indent); + JavaHeuristicScanner scanner = new JavaHeuristicScanner(document); + JavaIndenter indenter = new JavaIndenter(document,scanner); + buffer.append(indenter.createIndent(1)); + int cursorPos = buffer.length(); + buffer.append(lineDelimiter); + buffer.append(indent); + document.replace(offset, length, buffer.toString()); + sourceViewer.getTextWidget().setCaretOffset( caretPos + cursorPos); + event.doit = false; + } } } - } } } catch (BadLocationException e) { } @@ -1756,8 +1809,8 @@ public class PHPUnitEditor extends PHPEditor { // implements // fPaintManager = new PaintManager(getSourceViewer()); LinePainter linePainter; linePainter = new LinePainter(getSourceViewer()); - linePainter.setHighlightColor(new Color(Display.getCurrent(), 225, 235, - 224)); + linePainter.setHighlightColor(new Color(Display.getCurrent(), 225, 235, 224)); + // fPaintManager.addPainter(linePainter); // if (isBracketHighlightingEnabled()) // startBracketHighlighting(); @@ -1771,8 +1824,9 @@ public class PHPUnitEditor extends PHPEditor { // implements // if (isAnnotationIndicationEnabled(type)) // startAnnotationIndication(type); // } - if (isTabConversionEnabled()) + if (isTabConversionEnabled ()) { startTabConversion(); + } // if (isOverviewRulerVisible()) // showOverviewRuler(); // @@ -1780,19 +1834,19 @@ public class PHPUnitEditor extends PHPEditor { // implements // PHPeclipsePlugin.getDefault().getPluginPreferences(); // preferences.addPropertyChangeListener(fPropertyChangeListener); IPreferenceStore preferenceStore = getPreferenceStore(); - boolean closeBracketsPHP = preferenceStore - .getBoolean(CLOSE_BRACKETS_PHP); - boolean closeStringsPHPDQ = preferenceStore - .getBoolean(CLOSE_STRINGS_DQ_PHP); - boolean closeStringsPHPSQ = preferenceStore - .getBoolean(CLOSE_STRINGS_SQ_PHP); - fBracketInserter.setCloseBracketsPHPEnabled(closeBracketsPHP); - fBracketInserter.setCloseStringsPHPDQEnabled(closeStringsPHPDQ); - fBracketInserter.setCloseStringsPHPSQEnabled(closeStringsPHPSQ); + boolean closeBracketsPHP = preferenceStore.getBoolean (CLOSE_BRACKETS_PHP); + boolean closeStringsPHPDQ = preferenceStore.getBoolean (CLOSE_STRINGS_DQ_PHP); + boolean closeStringsPHPSQ = preferenceStore.getBoolean (CLOSE_STRINGS_SQ_PHP); + + fBracketInserter.setCloseBracketsPHPEnabled (closeBracketsPHP); + fBracketInserter.setCloseStringsPHPDQEnabled (closeStringsPHPDQ); + fBracketInserter.setCloseStringsPHPSQEnabled (closeStringsPHPSQ); + ISourceViewer sourceViewer = getSourceViewer(); - if (sourceViewer instanceof ITextViewerExtension) - ((ITextViewerExtension) sourceViewer) - .prependVerifyKeyListener(fBracketInserter); + + if (sourceViewer instanceof ITextViewerExtension) { + ((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter); + } } private static char getPeerCharacter(char character) { -- 1.7.1