From: jsurfer Date: Thu, 2 Sep 2004 18:32:47 +0000 (+0000) Subject: new PartitionScanner version X-Git-Url: http://git.phpeclipse.com new PartitionScanner version --- diff --git a/net.sourceforge.phpeclipse/plugin.xml b/net.sourceforge.phpeclipse/plugin.xml index dc3e02e..9b3a053 100644 --- a/net.sourceforge.phpeclipse/plugin.xml +++ b/net.sourceforge.phpeclipse/plugin.xml @@ -34,6 +34,9 @@ + + + - @@ -177,11 +180,11 @@ - + - + --> - - + --> @@ -1364,14 +1367,14 @@ extensions="php,php3,php4,php5,module,inc,phtml" class="net.sourceforge.phpeclipse.phpeditor.JavaDocumentSetupParticipant"> - - + --> @@ -1523,7 +1527,7 @@ id="net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider"> - - + --> boolean This parameter is used to optimize the * literals or leave them as they are in the source. If you put - * true, "Hello" + " world" will be converted to "Hello world". + * true, "Hello" . " world" will be converted to "Hello world". */ public Compiler(INameEnvironment environment, IErrorHandlingPolicy policy, Map settings, final ICompilerRequestor requestor, diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index f30009d..939f999 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -2467,13 +2467,15 @@ public class Parser //extends PHPParserSuperclass //| static_member '(' function_call_parameter_list ')' //| variable_without_objects '(' function_call_parameter_list ')' char[] defineName = null; + char[] ident = null; int startPos=0; int endPos=0; if (Scanner.TRACE) { System.out.println("TRACE: function_call()"); } if (token == TokenNameIdentifier) { - defineName = scanner.getCurrentIdentifierSource(); + ident = scanner.getCurrentIdentifierSource(); + defineName = ident; startPos = scanner.getCurrentTokenStartPosition(); endPos = scanner.getCurrentTokenEndPosition(); getNextToken(); @@ -2545,7 +2547,13 @@ public class Parser //extends PHPParserSuperclass } non_empty_function_call_parameter_list(); if (token != TokenNameRPAREN) { - throwSyntaxError("')' expected in function call."); + String functionName; + if (ident==null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + throwSyntaxError("')' expected in function call ("+functionName+")."); } getNextToken(); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocCharArrayCommentReader.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocCharArrayCommentReader.java index 4816997..5a06b54 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocCharArrayCommentReader.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocCharArrayCommentReader.java @@ -46,7 +46,7 @@ public class PHPDocCharArrayCommentReader extends SingleCharReader { if (fWasNewLine) { do { ch = fCharArray[fCurrPos++]; - } while (fCurrPos < fEndPos && Character.isWhitespace(ch)); + } while (fCurrPos < fEndPos &&Character.isWhitespace(ch)); if (ch == '*') { if (fCurrPos < fEndPos) { do { diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocUtil.java index 900d535..1ef819f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocUtil.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocUtil.java @@ -33,7 +33,7 @@ public class PHPDocUtil { phpFileReader.read(phpDocDeclarationCharArray, 0, location.getPHPDocLength()); PHPDocCharArrayCommentReader phpdocConverter = new PHPDocCharArrayCommentReader(phpDocDeclarationCharArray); hoverInfoBuffer.append(phpdocConverter.getString()); - hoverInfoBuffer.append("

"); +// hoverInfoBuffer.append("

"); phpFileReader.close(); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java index 87340b4..6bd996e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java @@ -54,7 +54,11 @@ public abstract class SingleCharReader extends Reader { StringBuffer buf= new StringBuffer(); int ch; while ((ch= read()) != -1) { - buf.append((char)ch); + if (ch=='\n'||ch=='\r') { + buf.append("
"); + } else { + buf.append((char)ch); + } } return buf.toString(); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java index e4ec3cf..420ed30 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java @@ -9,6 +9,7 @@ * IBM Corporation - initial API and implementation ******************************************************************************/ package net.sourceforge.phpdt.internal.formatter; + import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; @@ -31,85 +32,107 @@ import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.formatter.IContentFormatterExtension; import org.eclipse.jface.text.formatter.IFormattingContext; + /** *

How to format a piece of code ?

*
    *
  • Create an instance of CodeFormatter - *
  • Use the method void format(aString) on this instance to - * format aString. It will return the formatted string. + *
  • Use the method void format(aString) on this instance to format aString. It will return the + * formatted string. *
*/ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { - // IContentFormatterExtension { + // IContentFormatterExtension { public FormatterOptions options; + /** * Represents a block in the constructions stack. */ public static final int BLOCK = ITerminalSymbols.TokenNameLBRACE; + /** - * Represents a block following a control statement in the constructions - * stack. + * Represents a block following a control statement in the constructions stack. */ public static final int NONINDENT_BLOCK = -100; + /** * Contains the formatted output. */ StringBuffer formattedSource; + /** * Contains the current line.
* Will be dumped at the next "newline" */ StringBuffer currentLineBuffer; + /** * Used during the formatting to get each token. */ Scanner scanner; + /** - * Contains the tokens responsible for the current indentation level and the - * blocks not closed yet. + * Contains the tokens responsible for the current indentation level and the blocks not closed yet. */ private int[] constructions; + /** * Index in the constructions array. */ private int constructionsCount; + /** - * Level of indentation of the current token (number of tab char put in front - * of it). + * Level of indentation of the current token (number of tab char put in front of it). */ private int indentationLevel; + /** * Regular level of indentation of all the lines */ private int initialIndentationLevel; + /** * Used to split a line. */ Scanner splitScanner; + /** - * To remember the offset between the beginning of the line and the beginning - * of the comment. + * To remember the offset between the beginning of the line and the beginning of the comment. */ int currentCommentOffset; + int currentLineIndentationLevel; + int maxLineSize = 30; + private boolean containsOpenCloseBraces; + private int indentationLevelForOpenCloseBraces; + /** * Collections of positions to map */ private int[] positionsToMap; + /** * Collections of mapped positions */ private int[] mappedPositions; + private int indexToMap; + private int indexInMap; + private int globalDelta; + private int lineDelta; + private int splitDelta; + private int beginningOfLineIndex; + private int multipleLineCommentCounter; + /** * Creates a new instance of Code Formatter using the given settings. * @@ -118,15 +141,16 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { public CodeFormatter(ConfigurableOption[] settings) { this(convertConfigurableOptions(settings)); } + /** - * Creates a new instance of Code Formatter using the FormattingOptions - * object given as argument + * Creates a new instance of Code Formatter using the FormattingOptions object given as argument * * @deprecated Use CodeFormatter(ConfigurableOption[]) instead */ public CodeFormatter() { this((Map) null); } + /** * Creates a new instance of Code Formatter using the given settings. */ @@ -156,20 +180,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { currentLineBuffer = new StringBuffer(); this.options = new FormatterOptions(settings); } + /** - * Returns true if a lineSeparator has to be inserted before operator - * false otherwise. + * Returns true if a lineSeparator has to be inserted before operator false otherwise. */ private static boolean breakLineBeforeOperator(int operator) { switch (operator) { - case TokenNameCOMMA : - case TokenNameSEMICOLON : - case TokenNameEQUAL : - return false; - default : - return true; + case TokenNameCOMMA: + case TokenNameSEMICOLON: + case TokenNameEQUAL: + return false; + default: + return true; } } + /** * @deprecated backport 1.0 internal functionality */ @@ -180,40 +205,30 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { String optionName = settings[i].getOptionName(); int valueIndex = settings[i].getCurrentValueIndex(); if (optionName.equals("newline.openingBrace")) { //$NON-NLS-1$ - options.put( - "net.sourceforge.phpdt.core.formatter.newline.openingBrace", - valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options.put("net.sourceforge.phpdt.core.formatter.newline.openingBrace", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("newline.controlStatement")) { //$NON-NLS-1$ - options.put( - "net.sourceforge.phpdt.core.formatter.newline.controlStatement", - valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options + .put("net.sourceforge.phpdt.core.formatter.newline.controlStatement", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("newline.clearAll")) { //$NON-NLS-1$ - options.put("net.sourceforge.phpdt.core.formatter.newline.clearAll", - valueIndex == 0 ? "clear all" : "preserve one"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options.put("net.sourceforge.phpdt.core.formatter.newline.clearAll", valueIndex == 0 ? "clear all" : "preserve one"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("newline.elseIf")) { //$NON-NLS-1$ - options.put("net.sourceforge.phpdt.core.formatter.newline.elseIf", - valueIndex == 0 ? "do not insert" : "insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options.put("net.sourceforge.phpdt.core.formatter.newline.elseIf", valueIndex == 0 ? "do not insert" : "insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("newline.emptyBlock")) { //$NON-NLS-1$ - options.put( - "net.sourceforge.phpdt.core.formatter.newline.emptyBlock", - valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options.put("net.sourceforge.phpdt.core.formatter.newline.emptyBlock", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("lineSplit")) { //$NON-NLS-1$ - options.put("net.sourceforge.phpdt.core.formatter.lineSplit", String - .valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$ + options.put("net.sourceforge.phpdt.core.formatter.lineSplit", String.valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$ } else if (optionName.equals("style.assignment")) { //$NON-NLS-1$ - options.put("net.sourceforge.phpdt.core.formatter.style.assignment", - valueIndex == 0 ? "compact" : "normal"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options.put("net.sourceforge.phpdt.core.formatter.style.assignment", valueIndex == 0 ? "compact" : "normal"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("tabulation.char")) { //$NON-NLS-1$ - options.put("net.sourceforge.phpdt.core.formatter.tabulation.char", - valueIndex == 0 ? "tab" : "space"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + options.put("net.sourceforge.phpdt.core.formatter.tabulation.char", valueIndex == 0 ? "tab" : "space"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if (optionName.equals("tabulation.size")) { //$NON-NLS-1$ - options.put("net.sourceforge.phpdt.core.formatter.tabulation.size", - String.valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$ + options.put("net.sourceforge.phpdt.core.formatter.tabulation.size", String.valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$ } } } return options; } + /** * Returns the end of the source code. */ @@ -227,9 +242,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } return (bufr.toString()); } + /** - * Inserts tabCount tab character or their equivalent number - * of spaces. + * Inserts tabCount tab character or their equivalent number of spaces. */ private void dumpTab(int tabCount) { if (options.indentWithTab) { @@ -244,6 +259,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } } } + /** * Dumps currentLineBuffer into the formatted string. */ @@ -253,17 +269,14 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { beginningOfLineIndex = formattedSource.length(); if (containsOpenCloseBraces) { containsOpenCloseBraces = false; - outputLine(currentString, false, indentationLevelForOpenCloseBraces, 0, - -1, null, 0); + outputLine(currentString, false, indentationLevelForOpenCloseBraces, 0, -1, null, 0); indentationLevelForOpenCloseBraces = currentLineIndentationLevel; } else { - outputLine(currentString, false, currentLineIndentationLevel, 0, -1, - null, 0); + outputLine(currentString, false, currentLineIndentationLevel, 0, -1, null, 0); } int scannerSourceLength = scanner.source.length; if (scannerSourceLength > 2) { - if (scanner.source[scannerSourceLength - 1] == '\n' - && scanner.source[scannerSourceLength - 2] == '\r') { + if (scanner.source[scannerSourceLength - 1] == '\n' && scanner.source[scannerSourceLength - 2] == '\r') { formattedSource.append(options.lineSeparatorSequence); increaseGlobalDelta(options.lineSeparatorSequence.length - 2); } else if (scanner.source[scannerSourceLength - 1] == '\n') { @@ -276,6 +289,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } updateMappedPositions(scanner.startPosition); } + /** * Formats the input string. */ @@ -332,22 +346,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { if (Scanner.DEBUG) { int currentEndPosition = scanner.getCurrentTokenEndPosition(); int currentStartPosition = scanner.getCurrentTokenStartPosition(); - System.out.print(currentStartPosition + "," + currentEndPosition - + ": "); + System.out.print(currentStartPosition + "," + currentEndPosition + ": "); System.out.println(scanner.toStringAction(token)); } // Patch for line comment // See PR http://dev.eclipse.org/bugs/show_bug.cgi?id=23096 if (token == ITerminalSymbols.TokenNameCOMMENT_LINE) { int length = scanner.currentPosition; - loop : for (int index = length - 1; index >= 0; index--) { + loop: for (int index = length - 1; index >= 0; index--) { switch (scanner.source[index]) { - case '\r' : - case '\n' : - scanner.currentPosition--; - break; - default : - break loop; + case '\r': + case '\n': + scanner.currentPosition--; + break; + default: + break loop; } } } @@ -360,8 +373,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { if (token == Scanner.TokenNameEOF) break; /* - * ## MODIFYING the indentation level before generating new lines and - * indentation in the output string + * ## MODIFYING the indentation level before generating new lines and indentation in the output string */ // Removes all the indentations made by statements not followed by a // block @@ -369,27 +381,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // switch/case if (clearNonBlockIndents && (token != Scanner.TokenNameWHITESPACE)) { switch (token) { - case TokenNameelse : - if (constructionsCount > 0 - && constructions[constructionsCount - 1] == TokenNameelse) { - pendingNewLines = 1; - specialElse = true; - } - indentationLevel += popInclusiveUntil(TokenNameif); + case TokenNameelse: + if (constructionsCount > 0 && constructions[constructionsCount - 1] == TokenNameelse) { + pendingNewLines = 1; + specialElse = true; + } + indentationLevel += popInclusiveUntil(TokenNameif); + break; + // case TokenNamecatch : + // indentationLevel += popInclusiveUntil(TokenNamecatch); + // break; + // case TokenNamefinally : + // indentationLevel += popInclusiveUntil(TokenNamecatch); + // break; + case TokenNamewhile: + if (nlicsToken == TokenNamedo) { + indentationLevel += pop(TokenNamedo); break; - // case TokenNamecatch : - // indentationLevel += popInclusiveUntil(TokenNamecatch); - // break; - // case TokenNamefinally : - // indentationLevel += popInclusiveUntil(TokenNamecatch); - // break; - case TokenNamewhile : - if (nlicsToken == TokenNamedo) { - indentationLevel += pop(TokenNamedo); - break; - } - default : - indentationLevel += popExclusiveUntilBlockOrCase(); + } + default: + indentationLevel += popExclusiveUntilBlockOrCase(); // clear until a CASE, DEFAULT or BLOCK is encountered. // Thus, the indentationLevel is correctly cleared either // in a switch/case statement or in any other situation. @@ -404,8 +415,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // if (token == Scanner.TokenNamethrows) { // inThrowsClause = true; // } - if ((token == Scanner.TokenNameclass || token == Scanner.TokenNameinterface) - && previousToken != Scanner.TokenNameDOT) { + if ((token == Scanner.TokenNameclass || token == Scanner.TokenNameinterface) && previousToken != Scanner.TokenNameDOT) { inClassOrInterfaceHeader = true; } /* @@ -438,21 +448,17 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // previous token is a close paren. // add a new line if a parenthesis belonging to a for() statement // has been closed and the current token is not an opening brace - if (token != TokenNameLBRACE - && !isComment(token) - // to avoid adding new line between else and a comment - && token != TokenNameDOT - && !(previousCompilableToken == TokenNameRPAREN && token == TokenNameSEMICOLON)) { + if (token != TokenNameLBRACE && !isComment(token) + // to avoid adding new line between else and a comment + && token != TokenNameDOT && !(previousCompilableToken == TokenNameRPAREN && token == TokenNameSEMICOLON)) { newLine(1); currentLineIndentationLevel = indentationLevel; pendingNewLines = 0; pendingSpace = false; } else { - if (token == TokenNameLBRACE - && options.newLineBeforeOpeningBraceMode) { + if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode) { newLine(1); - if (constructionsCount > 0 - && constructions[constructionsCount - 1] != BLOCK + if (constructionsCount > 0 && constructions[constructionsCount - 1] != BLOCK && constructions[constructionsCount - 1] != NONINDENT_BLOCK) { currentLineIndentationLevel = indentationLevel - 1; } else { @@ -463,8 +469,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } } } - if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode - && constructionsCount > 0 + if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode && constructionsCount > 0 && constructions[constructionsCount - 1] == TokenNamedo) { newLine(1); currentLineIndentationLevel = indentationLevel - 1; @@ -502,53 +507,42 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { && token != Scanner.TokenNameWHITESPACE) { // Do not add newline & indent between an adjoining close brace and // close paren. Anonymous inner classes may use this form. - boolean closeBraceAndCloseParen = previousToken == TokenNameRBRACE - && token == TokenNameRPAREN; + boolean closeBraceAndCloseParen = previousToken == TokenNameRBRACE && token == TokenNameRPAREN; // OPTION (NewLineInCompoundStatement): do not add newline & indent // between close brace and else, (do) while, catch, and finally if // newlineInCompoundStatement is true. boolean nlicsOption = previousToken == TokenNameRBRACE && !options.newlineInControlStatementMode - && (token == TokenNameelse - || (token == TokenNamewhile && nlicsToken == TokenNamedo) - || token == TokenNamecatch || token == TokenNamefinally); + && (token == TokenNameelse || (token == TokenNamewhile && nlicsToken == TokenNamedo) || token == TokenNamecatch || token == TokenNamefinally); // Do not add a newline & indent between a close brace and // semi-colon. - boolean semiColonAndCloseBrace = previousToken == TokenNameRBRACE - && token == TokenNameSEMICOLON; + boolean semiColonAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameSEMICOLON; // Do not add a new line & indent between a multiline comment and a // opening brace - boolean commentAndOpenBrace = previousToken == Scanner.TokenNameCOMMENT_BLOCK - && token == TokenNameLBRACE; + boolean commentAndOpenBrace = previousToken == Scanner.TokenNameCOMMENT_BLOCK && token == TokenNameLBRACE; // Do not add a newline & indent between a close brace and a colon // (in array assignments, for example). - boolean commaAndCloseBrace = previousToken == TokenNameRBRACE - && token == TokenNameCOMMA; + boolean commaAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameCOMMA; // Add a newline and indent, if appropriate. if (specialElse - || (!commentAndOpenBrace && !closeBraceAndCloseParen - && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) { + || (!commentAndOpenBrace && !closeBraceAndCloseParen && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) { // if clearAllBlankLinesMode=false, leaves the blank lines // inserted by the user // if clearAllBlankLinesMode=true, removes all of then // and insert only blank lines required by the formatting. if (!options.clearAllBlankLinesMode) { // (isComment(token)) - pendingNewLines = (pendingNewLines < newLinesInWhitespace) - ? newLinesInWhitespace - : pendingNewLines; + pendingNewLines = (pendingNewLines < newLinesInWhitespace) ? newLinesInWhitespace : pendingNewLines; pendingNewLines = (pendingNewLines > 2) ? 2 : pendingNewLines; } - if (previousCompilableToken == TokenNameLBRACE - && token == TokenNameRBRACE) { + if (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE) { containsOpenCloseBraces = true; indentationLevelForOpenCloseBraces = currentLineIndentationLevel; if (isComment(previousToken)) { newLine(pendingNewLines); } else { /* - * if (!(constructionsCount > 1 && - * constructions[constructionsCount-1] == NONINDENT_BLOCK && + * if (!(constructionsCount > 1 && constructions[constructionsCount-1] == NONINDENT_BLOCK && * (constructions[constructionsCount-2] == TokenNamefor */ if (options.newLineInEmptyBlockMode) { @@ -567,8 +561,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { newLine(pendingNewLines); } } - if (((previousCompilableToken == TokenNameSEMICOLON) - || (previousCompilableToken == TokenNameLBRACE) + if (((previousCompilableToken == TokenNameSEMICOLON) || (previousCompilableToken == TokenNameLBRACE) || (previousCompilableToken == TokenNameRBRACE) || (isComment(previousToken))) && (token == TokenNameRBRACE)) { indentationOffset = -1; @@ -578,8 +571,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // PR 1FI5IPO currentLineIndentationLevel++; } else { - currentLineIndentationLevel = indentationLevel - + indentationOffset; + currentLineIndentationLevel = indentationLevel + indentationOffset; } pendingSpace = false; indentationOffset = 0; @@ -591,120 +583,108 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { nlicsToken = 0; } } - boolean phpTagAndWhitespace = - previousToken == TokenNameINLINE_HTML && token == TokenNameWHITESPACE; + boolean phpTagAndWhitespace = previousToken == TokenNameINLINE_HTML && token == TokenNameWHITESPACE; switch (token) { - // case TokenNameDOLLAR : - // dollarBraceCount++; - // break; - case TokenNameelse : - // case TokenNamefinally : - expectingOpenBrace = true; - pendingNewlineAfterParen = true; - indentationLevel += pushControlStatement(token); - break; - case TokenNamecase : - case TokenNamedefault : - if (tokenBeforeColonCount == tokenBeforeColon.length) { - System.arraycopy(tokenBeforeColon, 0, - (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, - tokenBeforeColonCount); - } - tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase; - indentationLevel += pushControlStatement(TokenNamecase); - break; - case TokenNameQUESTION : - if (tokenBeforeColonCount == tokenBeforeColon.length) { - System.arraycopy(tokenBeforeColon, 0, - (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, - tokenBeforeColonCount); - } - tokenBeforeColon[tokenBeforeColonCount++] = token; - break; - case TokenNameswitch : - case TokenNamefor : - case TokenNameif : - case TokenNamewhile : - if (openParenthesisCount == openParenthesis.length) { - System.arraycopy(openParenthesis, 0, - (openParenthesis = new int[openParenthesisCount * 2]), 0, - openParenthesisCount); - } - openParenthesis[openParenthesisCount++] = 0; - expectingOpenBrace = true; - indentationLevel += pushControlStatement(token); - break; - case TokenNametry : - pendingNewlineAfterParen = true; - case TokenNamecatch : - // several CATCH statements can be contiguous. - // a CATCH is encountered pop until first CATCH (if a CATCH - // follows a TRY it works the same way, - // as CATCH and TRY are the same token in the stack). - expectingOpenBrace = true; - indentationLevel += pushControlStatement(TokenNamecatch); - break; - case TokenNamedo : - expectingOpenBrace = true; - indentationLevel += pushControlStatement(token); - nlicsToken = token; - break; - case TokenNamenew : - break; - case TokenNameLPAREN : - // if (previousToken == TokenNamesynchronized) { - // indentationLevel += pushControlStatement(previousToken); - // } else { - // Put a space between the previous and current token if the - // previous token was not a keyword, open paren, logical - // compliment (eg: !), semi-colon, open brace, close brace, - // super, or this. - if (previousCompilableToken != TokenNameLBRACKET - && previousToken != TokenNameIdentifier && previousToken != 0 - && previousToken != TokenNameNOT - && previousToken != TokenNameLPAREN - && previousToken != TokenNameTWIDDLE - && previousToken != TokenNameSEMICOLON - && previousToken != TokenNameLBRACE - && previousToken != TokenNameRBRACE - && previousToken != TokenNamesuper) { - // && previousToken != TokenNamethis) { - space(); - } - // If in a for/if/while statement, increase the parenthesis count - // for the current openParenthesisCount - // else increase the count for stand alone parenthesis. - if (openParenthesisCount > 0) - openParenthesis[openParenthesisCount - 1]++; - else - openParenthesis[0]++; - pendingSpace = false; - //S } - break; - case TokenNameRPAREN : - // Decrease the parenthesis count - // if there is no more unclosed parenthesis, - // a new line and indent may be append (depending on the next - // token). - if ((openParenthesisCount > 1) - && (openParenthesis[openParenthesisCount - 1] > 0)) { - openParenthesis[openParenthesisCount - 1]--; - if (openParenthesis[openParenthesisCount - 1] <= 0) { - pendingNewlineAfterParen = true; - inAssignment = false; - openParenthesisCount--; - } - } else { - openParenthesis[0]--; + // case TokenNameDOLLAR : + // dollarBraceCount++; + // break; + case TokenNameelse: + // case TokenNamefinally : + expectingOpenBrace = true; + pendingNewlineAfterParen = true; + indentationLevel += pushControlStatement(token); + break; + case TokenNamecase: + case TokenNamedefault: + if (tokenBeforeColonCount == tokenBeforeColon.length) { + System + .arraycopy(tokenBeforeColon, 0, (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, tokenBeforeColonCount); + } + tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase; + indentationLevel += pushControlStatement(TokenNamecase); + break; + case TokenNameQUESTION: + if (tokenBeforeColonCount == tokenBeforeColon.length) { + System + .arraycopy(tokenBeforeColon, 0, (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, tokenBeforeColonCount); + } + tokenBeforeColon[tokenBeforeColonCount++] = token; + break; + case TokenNameswitch: + case TokenNamefor: + case TokenNameif: + case TokenNamewhile: + if (openParenthesisCount == openParenthesis.length) { + System.arraycopy(openParenthesis, 0, (openParenthesis = new int[openParenthesisCount * 2]), 0, openParenthesisCount); + } + openParenthesis[openParenthesisCount++] = 0; + expectingOpenBrace = true; + indentationLevel += pushControlStatement(token); + break; + case TokenNametry: + pendingNewlineAfterParen = true; + case TokenNamecatch: + // several CATCH statements can be contiguous. + // a CATCH is encountered pop until first CATCH (if a CATCH + // follows a TRY it works the same way, + // as CATCH and TRY are the same token in the stack). + expectingOpenBrace = true; + indentationLevel += pushControlStatement(TokenNamecatch); + break; + case TokenNamedo: + expectingOpenBrace = true; + indentationLevel += pushControlStatement(token); + nlicsToken = token; + break; + case TokenNamenew: + break; + case TokenNameLPAREN: + // if (previousToken == TokenNamesynchronized) { + // indentationLevel += pushControlStatement(previousToken); + // } else { + // Put a space between the previous and current token if the + // previous token was not a keyword, open paren, logical + // compliment (eg: !), semi-colon, open brace, close brace, + // super, or this. + if (previousCompilableToken != TokenNameLBRACKET && previousToken != TokenNameIdentifier && previousToken != 0 + && previousToken != TokenNameNOT && previousToken != TokenNameLPAREN && previousToken != TokenNameTWIDDLE + && previousToken != TokenNameSEMICOLON && previousToken != TokenNameLBRACE && previousToken != TokenNameRBRACE + && previousToken != TokenNamesuper) { + // && previousToken != TokenNamethis) { + space(); + } + // If in a for/if/while statement, increase the parenthesis count + // for the current openParenthesisCount + // else increase the count for stand alone parenthesis. + if (openParenthesisCount > 0) + openParenthesis[openParenthesisCount - 1]++; + else + openParenthesis[0]++; + pendingSpace = false; + //S } + break; + case TokenNameRPAREN: + // Decrease the parenthesis count + // if there is no more unclosed parenthesis, + // a new line and indent may be append (depending on the next + // token). + if ((openParenthesisCount > 1) && (openParenthesis[openParenthesisCount - 1] > 0)) { + openParenthesis[openParenthesisCount - 1]--; + if (openParenthesis[openParenthesisCount - 1] <= 0) { + pendingNewlineAfterParen = true; + inAssignment = false; + openParenthesisCount--; } - pendingSpace = false; - break; - case TokenNameLBRACE : - if (previousCompilableToken == TokenNameDOLLAR) { - dollarBraceCount++; - } else { - if ((previousCompilableToken == TokenNameRBRACKET) - || (previousCompilableToken == TokenNameEQUAL)) { + } else { + openParenthesis[0]--; + } + pendingSpace = false; + break; + case TokenNameLBRACE: + if (previousCompilableToken == TokenNameDOLLAR) { + dollarBraceCount++; + } else { + if ((previousCompilableToken == TokenNameRBRACKET) || (previousCompilableToken == TokenNameEQUAL)) { // if (previousCompilableToken == TokenNameRBRACKET) { inArrayAssignment = true; inAssignment = false; @@ -713,211 +693,198 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { indentationLevel += pushBlock(); } else { // Add new line and increase indentation level after open brace. - pendingNewLines = 1; - indentationLevel += pushBlock(); - } - } - break; - case TokenNameRBRACE : - if (dollarBraceCount > 0) { - dollarBraceCount--; - break; - } - if (previousCompilableToken == TokenNameRPAREN) { - pendingSpace = false; - } - if (inArrayAssignment) { - inArrayAssignment = false; - pendingNewLines = 1; - indentationLevel += popInclusiveUntilBlock(); - } else { pendingNewLines = 1; - indentationLevel += popInclusiveUntilBlock(); - if (previousCompilableToken == TokenNameRPAREN) { - // fix for 1FGDDV6: LFCOM:WIN98 - Weird splitting on message - // expression - currentLineBuffer.append(options.lineSeparatorSequence); - increaseLineDelta(options.lineSeparatorSequence.length); - } - if (constructionsCount > 0) { - switch (constructions[constructionsCount - 1]) { - case TokenNamefor : - //indentationLevel += popExclusiveUntilBlock(); - //break; - case TokenNameswitch : - case TokenNameif : - case TokenNameelse : - case TokenNametry : - case TokenNamecatch : - case TokenNamefinally : - case TokenNamewhile : - case TokenNamedo : - // case TokenNamesynchronized : - clearNonBlockIndents = true; - default : - break; - } - } + indentationLevel += pushBlock(); } + } + break; + case TokenNameRBRACE: + if (dollarBraceCount > 0) { + dollarBraceCount--; break; - case TokenNameLBRACKET : - openBracketCount++; - pendingSpace = false; - break; - case TokenNameRBRACKET : - openBracketCount -= (openBracketCount > 0) ? 1 : 0; - // if there is no left bracket to close, the right bracket is - // ignored. - pendingSpace = false; - break; - case TokenNameCOMMA : - case TokenNameDOT : - pendingSpace = false; - break; - case TokenNameSEMICOLON : - // Do not generate line terminators in the definition of - // the for statement. - // if not in this case, jump a line and reduce indentation after - // the brace - // if the block it closes belongs to a conditional statement (if, - // while, do...). - if (openParenthesisCount <= 1) { - pendingNewLines = 1; - if (expectingOpenBrace) { - clearNonBlockIndents = true; - expectingOpenBrace = false; - } - } - inAssignment = false; + } + if (previousCompilableToken == TokenNameRPAREN) { pendingSpace = false; - break; - case TokenNamePLUS_PLUS : - case TokenNameMINUS_MINUS : - // Do not put a space between a post-increment/decrement - // and the identifier being modified. - if (previousToken == TokenNameIdentifier - || previousToken == TokenNameRBRACKET) { - pendingSpace = false; - } - break; - case TokenNamePLUS : - // previously ADDITION - case TokenNameMINUS : - // Handle the unary operators plus and minus via a flag - if (!isLiteralToken(previousToken) - && previousToken != TokenNameIdentifier - && previousToken != TokenNameRPAREN - && previousToken != TokenNameRBRACKET) { - unarySignModifier = 1; + } + if (inArrayAssignment) { + inArrayAssignment = false; + pendingNewLines = 1; + indentationLevel += popInclusiveUntilBlock(); + } else { + pendingNewLines = 1; + indentationLevel += popInclusiveUntilBlock(); + if (previousCompilableToken == TokenNameRPAREN) { + // fix for 1FGDDV6: LFCOM:WIN98 - Weird splitting on message + // expression + currentLineBuffer.append(options.lineSeparatorSequence); + increaseLineDelta(options.lineSeparatorSequence.length); } - break; - case TokenNameCOLON : - // In a switch/case statement, add a newline & indent - // when a colon is encountered. - if (tokenBeforeColonCount > 0) { - if (tokenBeforeColon[tokenBeforeColonCount - 1] == TokenNamecase) { - pendingNewLines = 1; + if (constructionsCount > 0) { + switch (constructions[constructionsCount - 1]) { + case TokenNamefor: + //indentationLevel += popExclusiveUntilBlock(); + //break; + case TokenNameswitch: + case TokenNameif: + case TokenNameelse: + case TokenNametry: + case TokenNamecatch: + case TokenNamefinally: + case TokenNamewhile: + case TokenNamedo: + // case TokenNamesynchronized : + clearNonBlockIndents = true; + default: + break; } - tokenBeforeColonCount--; } - break; - case TokenNameEQUAL : - inAssignment = true; - break; - case Scanner.TokenNameCOMMENT_LINE : + } + break; + case TokenNameLBRACKET: + openBracketCount++; + pendingSpace = false; + break; + case TokenNameRBRACKET: + openBracketCount -= (openBracketCount > 0) ? 1 : 0; + // if there is no left bracket to close, the right bracket is + // ignored. + pendingSpace = false; + break; + case TokenNameCOMMA: + case TokenNameDOT: + pendingSpace = false; + break; + case TokenNameSEMICOLON: + // Do not generate line terminators in the definition of + // the for statement. + // if not in this case, jump a line and reduce indentation after + // the brace + // if the block it closes belongs to a conditional statement (if, + // while, do...). + if (openParenthesisCount <= 1) { pendingNewLines = 1; - if (inAssignment) { - currentLineIndentationLevel++; + if (expectingOpenBrace) { + clearNonBlockIndents = true; + expectingOpenBrace = false; } - break; // a line is always inserted after a one-line comment - case Scanner.TokenNameCOMMENT_PHPDOC : - case Scanner.TokenNameCOMMENT_BLOCK : - currentCommentOffset = getCurrentCommentOffset(); - pendingNewLines = 1; - break; - case Scanner.TokenNameWHITESPACE : - if (!phpTagAndWhitespace) { - // Count the number of line terminators in the whitespace so - // line spacing can be preserved near comments. - char[] source = scanner.source; - newLinesInWhitespace = 0; - for (int i = scanner.startPosition, max = scanner.currentPosition; i < max; i++) { - if (source[i] == '\r') { - if (i < max - 1) { - if (source[++i] == '\n') { - newLinesInWhitespace++; - } else { - newLinesInWhitespace++; - } + } + inAssignment = false; + pendingSpace = false; + break; + case TokenNamePLUS_PLUS: + case TokenNameMINUS_MINUS: + // Do not put a space between a post-increment/decrement + // and the identifier being modified. + if (previousToken == TokenNameIdentifier || previousToken == TokenNameRBRACKET) { + pendingSpace = false; + } + break; + case TokenNamePLUS: + // previously ADDITION + case TokenNameMINUS: + // Handle the unary operators plus and minus via a flag + if (!isLiteralToken(previousToken) && previousToken != TokenNameIdentifier && previousToken != TokenNameRPAREN + && previousToken != TokenNameRBRACKET) { + unarySignModifier = 1; + } + break; + case TokenNameCOLON: + // In a switch/case statement, add a newline & indent + // when a colon is encountered. + if (tokenBeforeColonCount > 0) { + if (tokenBeforeColon[tokenBeforeColonCount - 1] == TokenNamecase) { + pendingNewLines = 1; + } + tokenBeforeColonCount--; + } + break; + case TokenNameEQUAL: + inAssignment = true; + break; + case Scanner.TokenNameCOMMENT_LINE: + pendingNewLines = 1; + if (inAssignment) { + currentLineIndentationLevel++; + } + break; // a line is always inserted after a one-line comment + case Scanner.TokenNameCOMMENT_PHPDOC: + case Scanner.TokenNameCOMMENT_BLOCK: + currentCommentOffset = getCurrentCommentOffset(); + pendingNewLines = 1; + break; + case Scanner.TokenNameWHITESPACE: + if (!phpTagAndWhitespace) { + // Count the number of line terminators in the whitespace so + // line spacing can be preserved near comments. + char[] source = scanner.source; + newLinesInWhitespace = 0; + for (int i = scanner.startPosition, max = scanner.currentPosition; i < max; i++) { + if (source[i] == '\r') { + if (i < max - 1) { + if (source[++i] == '\n') { + newLinesInWhitespace++; } else { newLinesInWhitespace++; } - } else if (source[i] == '\n') { + } else { newLinesInWhitespace++; } + } else if (source[i] == '\n') { + newLinesInWhitespace++; } - increaseLineDelta(scanner.startPosition - scanner.currentPosition); - break; - } - // case TokenNameHTML : - // // Add the next token to the formatted source string. - // // outputCurrentToken(token); - // int startPosition = scanner.startPosition; - // flushBuffer(); - // for (int i = startPosition, max = scanner.currentPosition; i < - // max; i++) { - // char currentCharacter = scanner.source[i]; - // updateMappedPositions(i); - // currentLineBuffer.append(currentCharacter); - // } - // break; - default : - if ((token == TokenNameIdentifier) || isLiteralToken(token) - || token == TokenNamesuper) { - // || token == TokenNamethis) { - // Do not put a space between a unary operator - // (eg: ++, --, +, -) and the identifier being modified. - if (previousToken == TokenNamePLUS_PLUS - || previousToken == TokenNameMINUS_MINUS - || (previousToken == TokenNameMINUS_GREATER && options.compactDereferencingMode) // -> - || (previousToken == TokenNamePLUS && unarySignModifier > 0) - || (previousToken == TokenNameMINUS && unarySignModifier > 0)) { - pendingSpace = false; - } - unarySignModifier = 0; } + increaseLineDelta(scanner.startPosition - scanner.currentPosition); break; + } + // case TokenNameHTML : + // // Add the next token to the formatted source string. + // // outputCurrentToken(token); + // int startPosition = scanner.startPosition; + // flushBuffer(); + // for (int i = startPosition, max = scanner.currentPosition; i < + // max; i++) { + // char currentCharacter = scanner.source[i]; + // updateMappedPositions(i); + // currentLineBuffer.append(currentCharacter); + // } + // break; + default: + if ((token == TokenNameIdentifier) || isLiteralToken(token) || token == TokenNamesuper) { + // || token == TokenNamethis) { + // Do not put a space between a unary operator + // (eg: ++, --, +, -) and the identifier being modified. + if (previousToken == TokenNamePLUS_PLUS || previousToken == TokenNameMINUS_MINUS + || (previousToken == TokenNameMINUS_GREATER && options.compactDereferencingMode) // -> + || (previousToken == TokenNamePLUS && unarySignModifier > 0) + || (previousToken == TokenNameMINUS && unarySignModifier > 0)) { + pendingSpace = false; + } + unarySignModifier = 0; + } + break; } // Do not output whitespace tokens. if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) { /* - * Add pending space to the formatted source string. Do not output a - * space under the following circumstances: 1) this is the first pass 2) - * previous token is an open paren 3) previous token is a period 4) - * previous token is the logical compliment (eg: !) 5) previous token - * is the bitwise compliment (eg: ~) 6) previous token is the open - * bracket (eg: [) 7) in an assignment statement, if the previous - * token is an open brace or the current token is a close brace 8) - * previous token is a single line comment 9) current token is a '->' + * Add pending space to the formatted source string. Do not output a space under the following circumstances: 1) this is + * the first pass 2) previous token is an open paren 3) previous token is a period 4) previous token is the logical + * compliment (eg: !) 5) previous token is the bitwise compliment (eg: ~) 6) previous token is the open bracket (eg: [) 7) + * in an assignment statement, if the previous token is an open brace or the current token is a close brace 8) previous + * token is a single line comment 9) current token is a '->' */ - if (token == TokenNameMINUS_GREATER - && options.compactDereferencingMode) + if (token == TokenNameMINUS_GREATER && options.compactDereferencingMode) pendingSpace = false; - - boolean openAndCloseBrace = previousCompilableToken == TokenNameLBRACE - && token == TokenNameRBRACE; - if (pendingSpace - && insertSpaceAfter(previousToken) + + boolean openAndCloseBrace = previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE; + if (pendingSpace && insertSpaceAfter(previousToken) && !(inAssignment && (previousToken == TokenNameLBRACE || token == TokenNameRBRACE)) && previousToken != Scanner.TokenNameCOMMENT_LINE) { - if ((!(options.compactAssignmentMode && token == TokenNameEQUAL)) - && !openAndCloseBrace) + if ((!(options.compactAssignmentMode && token == TokenNameEQUAL)) && !openAndCloseBrace) space(); } // Add the next token to the formatted source string. outputCurrentToken(token); - if (token == Scanner.TokenNameCOMMENT_LINE - && openParenthesisCount > 1) { + if (token == Scanner.TokenNameCOMMENT_LINE && openParenthesisCount > 1) { pendingNewLines = 0; currentLineBuffer.append(options.lineSeparatorSequence); increaseLineDelta(options.lineSeparatorSequence.length); @@ -927,8 +894,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // Whitespace tokens do not need to be remembered. if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) { previousToken = token; - if (token != Scanner.TokenNameCOMMENT_BLOCK - && token != Scanner.TokenNameCOMMENT_LINE + if (token != Scanner.TokenNameCOMMENT_BLOCK && token != Scanner.TokenNameCOMMENT_LINE && token != Scanner.TokenNameCOMMENT_PHPDOC) { previousCompilableToken = token; } @@ -943,9 +909,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // dump the last token of the source in the formatted output. } } + /** - * Formats the char array sourceString, and returns a string - * containing the formatted version. + * Formats the char array sourceString, and returns a string containing the formatted version. * * @return the formatted ouput. */ @@ -956,37 +922,37 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { format(); return formattedSource.toString(); } + /** - * Formats the char array sourceString, and returns a string - * containing the formatted version. + * Formats the char array sourceString, and returns a string containing the formatted version. * * @param string - * the string to format + * the string to format * @param indentationLevel - * the initial indentation level + * the initial indentation level * @return the formatted ouput. */ public String format(String string, int indentationLevel) { return format(string, indentationLevel, (int[]) null); } + /** - * Formats the char array sourceString, and returns a string - * containing the formatted version. The positions array is modified to - * contain the mapped positions. + * Formats the char array sourceString, and returns a string containing the formatted version. The positions array + * is modified to contain the mapped positions. * * @param string - * the string to format + * the string to format * @param indentationLevel - * the initial indentation level + * the initial indentation level * @param positions - * the array of positions to map + * the array of positions to map * @return the formatted ouput. */ public String format(String string, int indentationLevel, int[] positions) { return this.format(string, indentationLevel, positions, null); } - public String format(String string, int indentationLevel, int[] positions, - String lineSeparator) { + + public String format(String string, int indentationLevel, int[] positions, String lineSeparator) { if (lineSeparator != null) { this.options.setLineSeparator(lineSeparator); } @@ -1002,32 +968,32 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { return this.formatSourceString(string); } } + /** - * Formats the char array sourceString, and returns a string - * containing the formatted version. The initial indentation level is 0. + * Formats the char array sourceString, and returns a string containing the formatted version. The initial + * indentation level is 0. * * @param string - * the string to format + * the string to format * @return the formatted ouput. */ public String format(String string) { return this.format(string, 0, (int[]) null); } + /** - * Formats a given source string, starting indenting it at a particular depth - * and using the given options + * Formats a given source string, starting indenting it at a particular depth and using the given options * * @deprecated backport 1.0 internal functionality */ - public static String format(String sourceString, int initialIndentationLevel, - ConfigurableOption[] options) { + public static String format(String sourceString, int initialIndentationLevel, ConfigurableOption[] options) { CodeFormatter formatter = new CodeFormatter(options); formatter.setInitialIndentationLevel(initialIndentationLevel); return formatter.formatSourceString(sourceString); } + /** - * Returns the number of characters and tab char between the beginning of the - * line and the beginning of the comment. + * Returns the number of characters and tab char between the beginning of the line and the beginning of the comment. */ private int getCurrentCommentOffset() { int linePtr = scanner.linePtr; @@ -1050,61 +1016,54 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { for (int i = currentStartPosition - 1; i >= beginningOfLine; i--) { char currentCharacter = source[i]; switch (currentCharacter) { - case '\t' : - offset += options.tabSize; - break; - case ' ' : - offset++; - break; - case '\r' : - case '\n' : - break; - default : - return offset; + case '\t': + offset += options.tabSize; + break; + case ' ': + offset++; + break; + case '\r': + case '\n': + break; + default: + return offset; } } return offset; } + /** - * Returns an array of descriptions for the configurable options. The - * descriptions may be changed and passed back to a different compiler. + * Returns an array of descriptions for the configurable options. The descriptions may be changed and passed back to a different + * compiler. * * @deprecated backport 1.0 internal functionality */ public static ConfigurableOption[] getDefaultOptions(Locale locale) { String componentName = CodeFormatter.class.getName(); FormatterOptions options = new FormatterOptions(); - return new ConfigurableOption[]{ - new ConfigurableOption(componentName, "newline.openingBrace", locale, - options.newLineBeforeOpeningBraceMode ? 0 : 1), + return new ConfigurableOption[] { + new ConfigurableOption(componentName, "newline.openingBrace", locale, options.newLineBeforeOpeningBraceMode ? 0 : 1), //$NON-NLS-1$ - new ConfigurableOption(componentName, "newline.controlStatement", - locale, options.newlineInControlStatementMode ? 0 : 1), + new ConfigurableOption(componentName, "newline.controlStatement", locale, options.newlineInControlStatementMode ? 0 : 1), //$NON-NLS-1$ - new ConfigurableOption(componentName, "newline.clearAll", locale, - options.clearAllBlankLinesMode ? 0 : 1), + new ConfigurableOption(componentName, "newline.clearAll", locale, options.clearAllBlankLinesMode ? 0 : 1), //$NON-NLS-1$ // new ConfigurableOption(componentName, "newline.elseIf", locale, // options.compactElseIfMode ? 0 : 1), //$NON-NLS-1$ - new ConfigurableOption(componentName, "newline.emptyBlock", locale, - options.newLineInEmptyBlockMode ? 0 : 1), + new ConfigurableOption(componentName, "newline.emptyBlock", locale, options.newLineInEmptyBlockMode ? 0 : 1), //$NON-NLS-1$ - new ConfigurableOption(componentName, "line.split", locale, - options.maxLineLength), + new ConfigurableOption(componentName, "line.split", locale, options.maxLineLength), //$NON-NLS-1$ - new ConfigurableOption(componentName, "style.compactAssignment", - locale, options.compactAssignmentMode ? 0 : 1), + new ConfigurableOption(componentName, "style.compactAssignment", locale, options.compactAssignmentMode ? 0 : 1), //$NON-NLS-1$ - new ConfigurableOption(componentName, "tabulation.char", locale, - options.indentWithTab ? 0 : 1), + new ConfigurableOption(componentName, "tabulation.char", locale, options.indentWithTab ? 0 : 1), //$NON-NLS-1$ - new ConfigurableOption(componentName, "tabulation.size", locale, - options.tabSize) //$NON-NLS-1$ + new ConfigurableOption(componentName, "tabulation.size", locale, options.tabSize) //$NON-NLS-1$ }; } + /** - * Returns the array of mapped positions. Returns null is no positions have - * been set. + * Returns the array of mapped positions. Returns null is no positions have been set. * * @return int[] * @deprecated There is no need to retrieve the mapped positions anymore. @@ -1112,174 +1071,180 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { public int[] getMappedPositions() { return mappedPositions; } + /** * Returns the priority of the token given as argument
* The most prioritary the token is, the smallest the return value is. * * @return the priority of token * @param token - * the token of which the priority is requested + * the token of which the priority is requested */ private static int getTokenPriority(int token) { switch (token) { - case TokenNameextends : - // case TokenNameimplements : - // case TokenNamethrows : - return 10; - case TokenNameSEMICOLON : - // ; - return 20; - case TokenNameCOMMA : - // , - return 25; - case TokenNameEQUAL : - // = - return 30; - case TokenNameAND_AND : - // && - case TokenNameOR_OR : - // || - return 40; - case TokenNameQUESTION : - // ? - case TokenNameCOLON : - // : - return 50; // it's better cutting on ?: than on ; - case TokenNameEQUAL_EQUAL : - // == - case TokenNameEQUAL_EQUAL_EQUAL : - // === - case TokenNameNOT_EQUAL : + case TokenNameextends: + // case TokenNameimplements : + // case TokenNamethrows : + return 10; + case TokenNameSEMICOLON: + // ; + return 20; + case TokenNameCOMMA: + // , + return 25; + case TokenNameEQUAL: + // = + return 30; + case TokenNameAND_AND: + // && + case TokenNameOR_OR: + // || + return 40; + case TokenNameQUESTION: + // ? + case TokenNameCOLON: + // : + return 50; // it's better cutting on ?: than on ; + case TokenNameEQUAL_EQUAL: + // == + case TokenNameEQUAL_EQUAL_EQUAL: + // === + case TokenNameNOT_EQUAL: + // != + case TokenNameNOT_EQUAL_EQUAL: // != - case TokenNameNOT_EQUAL_EQUAL : - // != - return 60; - case TokenNameLESS : - // < - case TokenNameLESS_EQUAL : - // <= - case TokenNameGREATER : - // > - case TokenNameGREATER_EQUAL : - // >= - // case TokenNameinstanceof : // instanceof - return 70; - case TokenNamePLUS : - // + - case TokenNameMINUS : - // - - return 80; - case TokenNameMULTIPLY : - // * - case TokenNameDIVIDE : - // / - case TokenNameREMAINDER : - // % - return 90; - case TokenNameLEFT_SHIFT : - // << - case TokenNameRIGHT_SHIFT : - // >> - // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> - return 100; - case TokenNameAND : - // & - case TokenNameOR : - // | - case TokenNameXOR : - // ^ - return 110; - case TokenNameMULTIPLY_EQUAL : - // *= - case TokenNameDIVIDE_EQUAL : - // /= - case TokenNameREMAINDER_EQUAL : - // %= - case TokenNamePLUS_EQUAL : - // += - case TokenNameMINUS_EQUAL : - // -= - case TokenNameLEFT_SHIFT_EQUAL : - // <<= - case TokenNameRIGHT_SHIFT_EQUAL : - // >>= - // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= - case TokenNameAND_EQUAL : - // &= - case TokenNameXOR_EQUAL : - // ^= - case TokenNameOR_EQUAL : - // |= - return 120; - case TokenNameDOT : - // . - return 130; - default : - return Integer.MAX_VALUE; + return 60; + case TokenNameLESS: + // < + case TokenNameLESS_EQUAL: + // <= + case TokenNameGREATER: + // > + case TokenNameGREATER_EQUAL: + // >= + // case TokenNameinstanceof : // instanceof + return 70; + case TokenNamePLUS: + // + + case TokenNameMINUS: + // - + return 80; + case TokenNameMULTIPLY: + // * + case TokenNameDIVIDE: + // / + case TokenNameREMAINDER: + // % + return 90; + case TokenNameLEFT_SHIFT: + // << + case TokenNameRIGHT_SHIFT: + // >> + // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> + return 100; + case TokenNameAND: + // & + case TokenNameOR: + // | + case TokenNameXOR: + // ^ + return 110; + case TokenNameMULTIPLY_EQUAL: + // *= + case TokenNameDIVIDE_EQUAL: + // /= + case TokenNameREMAINDER_EQUAL: + // %= + case TokenNamePLUS_EQUAL: + // += + case TokenNameMINUS_EQUAL: + // -= + case TokenNameLEFT_SHIFT_EQUAL: + // <<= + case TokenNameRIGHT_SHIFT_EQUAL: + // >>= + // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= + case TokenNameAND_EQUAL: + // &= + case TokenNameXOR_EQUAL: + // ^= + case TokenNameOR_EQUAL: + // .= + case TokenNameDOT_EQUAL: + // |= + return 120; + case TokenNameDOT: + // . + return 130; + default: + return Integer.MAX_VALUE; } } + /** - * Handles the exception raised when an invalid token is encountered. Returns - * true if the exception has been handled, false otherwise. + * Handles the exception raised when an invalid token is encountered. Returns true if the exception has been handled, false + * otherwise. */ private boolean handleInvalidToken(Exception e) { - if (e.getMessage().equals(Scanner.INVALID_CHARACTER_CONSTANT) - || e.getMessage().equals(Scanner.INVALID_CHAR_IN_STRING) + if (e.getMessage().equals(Scanner.INVALID_CHARACTER_CONSTANT) || e.getMessage().equals(Scanner.INVALID_CHAR_IN_STRING) || e.getMessage().equals(Scanner.INVALID_ESCAPE)) { return true; } return false; } + private final void increaseGlobalDelta(int offset) { globalDelta += offset; } + private final void increaseLineDelta(int offset) { lineDelta += offset; } + private final void increaseSplitDelta(int offset) { splitDelta += offset; } + /** - * Returns true if a space has to be inserted after operator - * false otherwise. + * Returns true if a space has to be inserted after operator false otherwise. */ private boolean insertSpaceAfter(int token) { switch (token) { - case TokenNameLPAREN : - case TokenNameNOT : - case TokenNameTWIDDLE : - case TokenNameDOT : - case 0 : - // no token - case TokenNameWHITESPACE : - case TokenNameLBRACKET : - case TokenNameDOLLAR : - case Scanner.TokenNameCOMMENT_LINE : - return false; - default : - return true; + case TokenNameLPAREN: + case TokenNameNOT: + case TokenNameTWIDDLE: + case TokenNameDOT: + case 0: + // no token + case TokenNameWHITESPACE: + case TokenNameLBRACKET: + case TokenNameDOLLAR: + case Scanner.TokenNameCOMMENT_LINE: + return false; + default: + return true; } } + /** - * Returns true if a space has to be inserted before operator - * false otherwise.
- * Cannot be static as it uses the code formatter options (to know if the - * compact assignment mode is on). + * Returns true if a space has to be inserted before operator false otherwise.
+ * Cannot be static as it uses the code formatter options (to know if the compact assignment mode is on). */ private boolean insertSpaceBefore(int token) { switch (token) { - case TokenNameEQUAL : - return (!options.compactAssignmentMode); - default : - return false; + case TokenNameEQUAL: + return (!options.compactAssignmentMode); + default: + return false; } } + private static boolean isComment(int token) { - boolean result = token == Scanner.TokenNameCOMMENT_BLOCK - || token == Scanner.TokenNameCOMMENT_LINE + boolean result = token == Scanner.TokenNameCOMMENT_BLOCK || token == Scanner.TokenNameCOMMENT_LINE || token == Scanner.TokenNameCOMMENT_PHPDOC; return result; } + private static boolean isLiteralToken(int token) { boolean result = token == TokenNameIntegerLiteral // || token == TokenNameLongLiteral @@ -1289,12 +1254,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { || token == TokenNameStringDoubleQuote; return result; } + /** - * If the length of oneLineBuffer exceeds maxLineLength, - * it is split and the result is dumped in formattedSource + * If the length of oneLineBuffer exceeds maxLineLength, it is split and the result is dumped in + * formattedSource * * @param newLineCount - * the number of new lines to append + * the number of new lines to append */ private void newLine(int newLineCount) { // format current line @@ -1303,12 +1269,10 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { String currentLine = currentLineBuffer.toString(); if (containsOpenCloseBraces) { containsOpenCloseBraces = false; - outputLine(currentLine, false, indentationLevelForOpenCloseBraces, 0, -1, - null, 0); + outputLine(currentLine, false, indentationLevelForOpenCloseBraces, 0, -1, null, 0); indentationLevelForOpenCloseBraces = currentLineIndentationLevel; } else { - outputLine(currentLine, false, currentLineIndentationLevel, 0, -1, null, - 0); + outputLine(currentLine, false, currentLineIndentationLevel, 0, -1, null, 0); } // dump line break(s) for (int i = 0; i < newLineCount; i++) { @@ -1317,150 +1281,153 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } // reset formatter for next line int currentLength = currentLine.length(); - currentLineBuffer = new StringBuffer(currentLength > maxLineSize - ? maxLineSize = currentLength - : maxLineSize); + currentLineBuffer = new StringBuffer(currentLength > maxLineSize ? maxLineSize = currentLength : maxLineSize); increaseGlobalDelta(splitDelta); increaseGlobalDelta(lineDelta); lineDelta = 0; currentLineIndentationLevel = initialIndentationLevel; } + private String operatorString(int operator) { switch (operator) { - case TokenNameextends : - return "extends"; //$NON-NLS-1$ - // case TokenNameimplements : - // return "implements"; //$NON-NLS-1$ - // - // case TokenNamethrows : - // return "throws"; //$NON-NLS-1$ - case TokenNameSEMICOLON : - // ; - return ";"; //$NON-NLS-1$ - case TokenNameCOMMA : - // , - return ","; //$NON-NLS-1$ - case TokenNameEQUAL : - // = - return "="; //$NON-NLS-1$ - case TokenNameAND_AND : - // && (15.22) - return "&&"; //$NON-NLS-1$ - case TokenNameOR_OR : - // || (15.23) - return "||"; //$NON-NLS-1$ - case TokenNameQUESTION : - // ? (15.24) - return "?"; //$NON-NLS-1$ - case TokenNameCOLON : - // : (15.24) - return ":"; //$NON-NLS-1$ - case TokenNamePAAMAYIM_NEKUDOTAYIM : - // : (15.24) - return "::"; //$NON-NLS-1$ - case TokenNameEQUAL_EQUAL : - // == (15.20, 15.20.1, 15.20.2, 15.20.3) - return "=="; //$NON-NLS-1$ - case TokenNameEQUAL_EQUAL_EQUAL : - // == (15.20, 15.20.1, 15.20.2, 15.20.3) - return "==="; //$NON-NLS-1$ - case TokenNameEQUAL_GREATER : - // -= (15.25.2) - return "=>"; //$NON-NLS-1$ - case TokenNameNOT_EQUAL : - // != (15.20, 15.20.1, 15.20.2, 15.20.3) - return "!="; //$NON-NLS-1$ - case TokenNameNOT_EQUAL_EQUAL : - // != (15.20, 15.20.1, 15.20.2, 15.20.3) - return "!=="; //$NON-NLS-1$ - case TokenNameLESS : - // < (15.19.1) - return "<"; //$NON-NLS-1$ - case TokenNameLESS_EQUAL : - // <= (15.19.1) - return "<="; //$NON-NLS-1$ - case TokenNameGREATER : - // > (15.19.1) - return ">"; //$NON-NLS-1$ - case TokenNameGREATER_EQUAL : - // >= (15.19.1) - return ">="; //$NON-NLS-1$ - // case TokenNameinstanceof : // instanceof - // return "instanceof"; //$NON-NLS-1$ - case TokenNamePLUS : - // + (15.17, 15.17.2) - return "+"; //$NON-NLS-1$ - case TokenNameMINUS : - // - (15.17.2) - return "-"; //$NON-NLS-1$ - case TokenNameMULTIPLY : - // * (15.16.1) - return "*"; //$NON-NLS-1$ - case TokenNameDIVIDE : - // / (15.16.2) - return "/"; //$NON-NLS-1$ - case TokenNameREMAINDER : - // % (15.16.3) - return "%"; //$NON-NLS-1$ - case TokenNameLEFT_SHIFT : - // << (15.18) - return "<<"; //$NON-NLS-1$ - case TokenNameRIGHT_SHIFT : - // >> (15.18) - return ">>"; //$NON-NLS-1$ - // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18) - // return ">>>"; //$NON-NLS-1$ - case TokenNameAND : - // & (15.21, 15.21.1, 15.21.2) - return "&"; //$NON-NLS-1$ - case TokenNameOR : - // | (15.21, 15.21.1, 15.21.2) - return "|"; //$NON-NLS-1$ - case TokenNameXOR : - // ^ (15.21, 15.21.1, 15.21.2) - return "^"; //$NON-NLS-1$ - case TokenNameMULTIPLY_EQUAL : - // *= (15.25.2) - return "*="; //$NON-NLS-1$ - case TokenNameDIVIDE_EQUAL : - // /= (15.25.2) - return "/="; //$NON-NLS-1$ - case TokenNameREMAINDER_EQUAL : - // %= (15.25.2) - return "%="; //$NON-NLS-1$ - case TokenNamePLUS_EQUAL : - // += (15.25.2) - return "+="; //$NON-NLS-1$ - case TokenNameMINUS_EQUAL : - // -= (15.25.2) - return "-="; //$NON-NLS-1$ - case TokenNameMINUS_GREATER : - // -= (15.25.2) - return "->"; //$NON-NLS-1$ - case TokenNameLEFT_SHIFT_EQUAL : - // <<= (15.25.2) - return "<<="; //$NON-NLS-1$ - case TokenNameRIGHT_SHIFT_EQUAL : - // >>= (15.25.2) - return ">>="; //$NON-NLS-1$ - // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2) - // return ">>>="; //$NON-NLS-1$ - case TokenNameAND_EQUAL : - // &= (15.25.2) - return "&="; //$NON-NLS-1$ - case TokenNameXOR_EQUAL : - // ^= (15.25.2) - return "^="; //$NON-NLS-1$ - case TokenNameOR_EQUAL : - // |= (15.25.2) - return "|="; //$NON-NLS-1$ - case TokenNameDOT : - // . - return "."; //$NON-NLS-1$ - default : - return ""; //$NON-NLS-1$ + case TokenNameextends: + return "extends"; //$NON-NLS-1$ + // case TokenNameimplements : + // return "implements"; //$NON-NLS-1$ + // + // case TokenNamethrows : + // return "throws"; //$NON-NLS-1$ + case TokenNameSEMICOLON: + // ; + return ";"; //$NON-NLS-1$ + case TokenNameCOMMA: + // , + return ","; //$NON-NLS-1$ + case TokenNameEQUAL: + // = + return "="; //$NON-NLS-1$ + case TokenNameAND_AND: + // && (15.22) + return "&&"; //$NON-NLS-1$ + case TokenNameOR_OR: + // || (15.23) + return "||"; //$NON-NLS-1$ + case TokenNameQUESTION: + // ? (15.24) + return "?"; //$NON-NLS-1$ + case TokenNameCOLON: + // : (15.24) + return ":"; //$NON-NLS-1$ + case TokenNamePAAMAYIM_NEKUDOTAYIM: + // : (15.24) + return "::"; //$NON-NLS-1$ + case TokenNameEQUAL_EQUAL: + // == (15.20, 15.20.1, 15.20.2, 15.20.3) + return "=="; //$NON-NLS-1$ + case TokenNameEQUAL_EQUAL_EQUAL: + // == (15.20, 15.20.1, 15.20.2, 15.20.3) + return "==="; //$NON-NLS-1$ + case TokenNameEQUAL_GREATER: + // -= (15.25.2) + return "=>"; //$NON-NLS-1$ + case TokenNameNOT_EQUAL: + // != (15.20, 15.20.1, 15.20.2, 15.20.3) + return "!="; //$NON-NLS-1$ + case TokenNameNOT_EQUAL_EQUAL: + // != (15.20, 15.20.1, 15.20.2, 15.20.3) + return "!=="; //$NON-NLS-1$ + case TokenNameLESS: + // < (15.19.1) + return "<"; //$NON-NLS-1$ + case TokenNameLESS_EQUAL: + // <= (15.19.1) + return "<="; //$NON-NLS-1$ + case TokenNameGREATER: + // > (15.19.1) + return ">"; //$NON-NLS-1$ + case TokenNameGREATER_EQUAL: + // >= (15.19.1) + return ">="; //$NON-NLS-1$ + // case TokenNameinstanceof : // instanceof + // return "instanceof"; //$NON-NLS-1$ + case TokenNamePLUS: + // + (15.17, 15.17.2) + return "+"; //$NON-NLS-1$ + case TokenNameMINUS: + // - (15.17.2) + return "-"; //$NON-NLS-1$ + case TokenNameMULTIPLY: + // * (15.16.1) + return "*"; //$NON-NLS-1$ + case TokenNameDIVIDE: + // / (15.16.2) + return "/"; //$NON-NLS-1$ + case TokenNameREMAINDER: + // % (15.16.3) + return "%"; //$NON-NLS-1$ + case TokenNameLEFT_SHIFT: + // << (15.18) + return "<<"; //$NON-NLS-1$ + case TokenNameRIGHT_SHIFT: + // >> (15.18) + return ">>"; //$NON-NLS-1$ + // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18) + // return ">>>"; //$NON-NLS-1$ + case TokenNameAND: + // & (15.21, 15.21.1, 15.21.2) + return "&"; //$NON-NLS-1$ + case TokenNameOR: + // | (15.21, 15.21.1, 15.21.2) + return "|"; //$NON-NLS-1$ + case TokenNameXOR: + // ^ (15.21, 15.21.1, 15.21.2) + return "^"; //$NON-NLS-1$ + case TokenNameMULTIPLY_EQUAL: + // *= (15.25.2) + return "*="; //$NON-NLS-1$ + case TokenNameDIVIDE_EQUAL: + // /= (15.25.2) + return "/="; //$NON-NLS-1$ + case TokenNameREMAINDER_EQUAL: + // %= (15.25.2) + return "%="; //$NON-NLS-1$ + case TokenNamePLUS_EQUAL: + // += (15.25.2) + return "+="; //$NON-NLS-1$ + case TokenNameMINUS_EQUAL: + // -= (15.25.2) + return "-="; //$NON-NLS-1$ + case TokenNameMINUS_GREATER: + // -= (15.25.2) + return "->"; //$NON-NLS-1$ + case TokenNameLEFT_SHIFT_EQUAL: + // <<= (15.25.2) + return "<<="; //$NON-NLS-1$ + case TokenNameRIGHT_SHIFT_EQUAL: + // >>= (15.25.2) + return ">>="; //$NON-NLS-1$ + // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2) + // return ">>>="; //$NON-NLS-1$ + case TokenNameAND_EQUAL: + // &= (15.25.2) + return "&="; //$NON-NLS-1$ + case TokenNameXOR_EQUAL: + // ^= (15.25.2) + return "^="; //$NON-NLS-1$ + case TokenNameOR_EQUAL: + // |= (15.25.2) + return "|="; //$NON-NLS-1$ + case TokenNameDOT_EQUAL: + // .= + return ".="; //$NON-NLS-1$ + case TokenNameDOT: + // . + return "."; //$NON-NLS-1$ + default: + return ""; //$NON-NLS-1$ } } + /** * Appends stringToOutput to the formatted output.
* If it contains \n, append a LINE_SEPARATOR and indent after it. @@ -1474,111 +1441,112 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } } } + /** * Appends token to the formatted output.
- * If it contains \n, append a LINE_SEPARATOR and indent - * after it. + * If it contains \n, append a LINE_SEPARATOR and indent after it. */ private void outputCurrentToken(int token) { char[] source = scanner.source; int startPosition = scanner.startPosition; switch (token) { - case Scanner.TokenNameCOMMENT_PHPDOC : - case Scanner.TokenNameCOMMENT_BLOCK : - case Scanner.TokenNameCOMMENT_LINE : - boolean endOfLine = false; - int currentCommentOffset = getCurrentCommentOffset(); - int beginningOfLineSpaces = 0; - endOfLine = false; - currentCommentOffset = getCurrentCommentOffset(); - beginningOfLineSpaces = 0; - boolean pendingCarriageReturn = false; - for (int i = startPosition, max = scanner.currentPosition; i < max; i++) { - char currentCharacter = source[i]; - updateMappedPositions(i); - switch (currentCharacter) { - case '\r' : - pendingCarriageReturn = true; - endOfLine = true; - break; - case '\n' : - if (pendingCarriageReturn) { - increaseGlobalDelta(options.lineSeparatorSequence.length - 2); - } else { - increaseGlobalDelta(options.lineSeparatorSequence.length - 1); - } - pendingCarriageReturn = false; - currentLineBuffer.append(options.lineSeparatorSequence); - beginningOfLineSpaces = 0; - endOfLine = true; - break; - case '\t' : - if (pendingCarriageReturn) { - pendingCarriageReturn = false; - increaseGlobalDelta(options.lineSeparatorSequence.length - 1); - currentLineBuffer.append(options.lineSeparatorSequence); - beginningOfLineSpaces = 0; - endOfLine = true; - } - if (endOfLine) { - // we remove a maximum of currentCommentOffset characters (tabs - // are converted to space numbers). - beginningOfLineSpaces += options.tabSize; - if (beginningOfLineSpaces > currentCommentOffset) { - currentLineBuffer.append(currentCharacter); - } else { - increaseGlobalDelta(-1); - } - } else { - currentLineBuffer.append(currentCharacter); - } - break; - case ' ' : - if (pendingCarriageReturn) { - pendingCarriageReturn = false; - increaseGlobalDelta(options.lineSeparatorSequence.length - 1); - currentLineBuffer.append(options.lineSeparatorSequence); - beginningOfLineSpaces = 0; - endOfLine = true; - } - if (endOfLine) { - // we remove a maximum of currentCommentOffset characters (tabs - // are converted to space numbers). - beginningOfLineSpaces++; - if (beginningOfLineSpaces > currentCommentOffset) { - currentLineBuffer.append(currentCharacter); - } else { - increaseGlobalDelta(-1); - } - } else { - currentLineBuffer.append(currentCharacter); - } - break; - default : - if (pendingCarriageReturn) { - pendingCarriageReturn = false; - increaseGlobalDelta(options.lineSeparatorSequence.length - 1); - currentLineBuffer.append(options.lineSeparatorSequence); - beginningOfLineSpaces = 0; - endOfLine = true; - } else { - beginningOfLineSpaces = 0; - currentLineBuffer.append(currentCharacter); - endOfLine = false; - } + case Scanner.TokenNameCOMMENT_PHPDOC: + case Scanner.TokenNameCOMMENT_BLOCK: + case Scanner.TokenNameCOMMENT_LINE: + boolean endOfLine = false; + int currentCommentOffset = getCurrentCommentOffset(); + int beginningOfLineSpaces = 0; + endOfLine = false; + currentCommentOffset = getCurrentCommentOffset(); + beginningOfLineSpaces = 0; + boolean pendingCarriageReturn = false; + for (int i = startPosition, max = scanner.currentPosition; i < max; i++) { + char currentCharacter = source[i]; + updateMappedPositions(i); + switch (currentCharacter) { + case '\r': + pendingCarriageReturn = true; + endOfLine = true; + break; + case '\n': + if (pendingCarriageReturn) { + increaseGlobalDelta(options.lineSeparatorSequence.length - 2); + } else { + increaseGlobalDelta(options.lineSeparatorSequence.length - 1); + } + pendingCarriageReturn = false; + currentLineBuffer.append(options.lineSeparatorSequence); + beginningOfLineSpaces = 0; + endOfLine = true; + break; + case '\t': + if (pendingCarriageReturn) { + pendingCarriageReturn = false; + increaseGlobalDelta(options.lineSeparatorSequence.length - 1); + currentLineBuffer.append(options.lineSeparatorSequence); + beginningOfLineSpaces = 0; + endOfLine = true; + } + if (endOfLine) { + // we remove a maximum of currentCommentOffset characters (tabs + // are converted to space numbers). + beginningOfLineSpaces += options.tabSize; + if (beginningOfLineSpaces > currentCommentOffset) { + currentLineBuffer.append(currentCharacter); + } else { + increaseGlobalDelta(-1); + } + } else { + currentLineBuffer.append(currentCharacter); + } + break; + case ' ': + if (pendingCarriageReturn) { + pendingCarriageReturn = false; + increaseGlobalDelta(options.lineSeparatorSequence.length - 1); + currentLineBuffer.append(options.lineSeparatorSequence); + beginningOfLineSpaces = 0; + endOfLine = true; + } + if (endOfLine) { + // we remove a maximum of currentCommentOffset characters (tabs + // are converted to space numbers). + beginningOfLineSpaces++; + if (beginningOfLineSpaces > currentCommentOffset) { + currentLineBuffer.append(currentCharacter); + } else { + increaseGlobalDelta(-1); + } + } else { + currentLineBuffer.append(currentCharacter); + } + break; + default: + if (pendingCarriageReturn) { + pendingCarriageReturn = false; + increaseGlobalDelta(options.lineSeparatorSequence.length - 1); + currentLineBuffer.append(options.lineSeparatorSequence); + beginningOfLineSpaces = 0; + endOfLine = true; + } else { + beginningOfLineSpaces = 0; + currentLineBuffer.append(currentCharacter); + endOfLine = false; } } - updateMappedPositions(scanner.currentPosition - 1); - multipleLineCommentCounter++; - break; - default : - for (int i = startPosition, max = scanner.currentPosition; i < max; i++) { - char currentCharacter = source[i]; - updateMappedPositions(i); - currentLineBuffer.append(currentCharacter); - } + } + updateMappedPositions(scanner.currentPosition - 1); + multipleLineCommentCounter++; + break; + default: + for (int i = startPosition, max = scanner.currentPosition; i < max; i++) { + char currentCharacter = source[i]; + updateMappedPositions(i); + currentLineBuffer.append(currentCharacter); + } } } + /** * Outputs currentString:
*
    @@ -1587,17 +1555,16 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { *
* * @param currentString - * string to output + * string to output * @param preIndented - * whether the string to output was pre-indented + * whether the string to output was pre-indented * @param depth - * number of indentation to put in front of currentString + * number of indentation to put in front of currentString * @param operator - * value of the operator belonging to currentString. + * value of the operator belonging to currentString. */ - private void outputLine(String currentString, boolean preIndented, int depth, - int operator, int substringIndex, int[] startSubstringIndexes, - int offsetInGlobalLine) { + private void outputLine(String currentString, boolean preIndented, int depth, int operator, int substringIndex, + int[] startSubstringIndexes, int offsetInGlobalLine) { boolean emptyFirstSubString = false; String operatorString = operatorString(operator); boolean placeOperatorBehind = !breakLineBeforeOperator(operator); @@ -1615,9 +1582,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } formattedSource.append(operatorString); increaseSplitDelta(operatorString.length()); - if (insertSpaceAfter(operator) - && operator != TokenNameimplements - && operator != TokenNameextends) { + if (insertSpaceAfter(operator) && operator != TokenNameimplements && operator != TokenNameextends) { // && operator != TokenNamethrows) { formattedSource.append(' '); increaseSplitDelta(1); @@ -1625,15 +1590,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } } SplitLine splitLine = null; - if (options.maxLineLength == 0 - || getLength(currentString, depth) < options.maxLineLength + if (options.maxLineLength == 0 || getLength(currentString, depth) < options.maxLineLength || (splitLine = split(currentString, offsetInGlobalLine)) == null) { // depending on the type of operator, outputs new line before of after // dumping it // indent before postfix operator // indent also when the line cannot be split - if (operator == TokenNameextends - || operator == TokenNameimplements ) { + if (operator == TokenNameextends || operator == TokenNameimplements) { // || operator == TokenNamethrows) { formattedSource.append(' '); increaseSplitDelta(1); @@ -1646,13 +1609,11 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { int max = currentString.length(); if (multipleLineCommentCounter != 0) { try { - BufferedReader reader = new BufferedReader(new StringReader( - currentString)); + BufferedReader reader = new BufferedReader(new StringReader(currentString)); String line = reader.readLine(); while (line != null) { - updateMappedPositionsWhileSplitting(beginningOfLineIndex, - beginningOfLineIndex + line.length() - + options.lineSeparatorSequence.length); + updateMappedPositionsWhileSplitting(beginningOfLineIndex, beginningOfLineIndex + line.length() + + options.lineSeparatorSequence.length); formattedSource.append(line); beginningOfLineIndex = beginningOfLineIndex + line.length(); if ((line = reader.readLine()) != null) { @@ -1666,42 +1627,38 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { e.printStackTrace(); } } else { - updateMappedPositionsWhileSplitting(beginningOfLineIndex, - beginningOfLineIndex + max); + updateMappedPositionsWhileSplitting(beginningOfLineIndex, beginningOfLineIndex + max); for (int i = 0; i < max; i++) { char currentChar = currentString.charAt(i); switch (currentChar) { - case '\r' : - break; - case '\n' : - if (i != max - 1) { - // fix for 1FFYL5C: LFCOM:ALL - Incorrect indentation when - // split with a comment inside a condition - // a substring cannot end with a lineSeparatorSequence, - // except if it has been added by format() after a one-line - // comment - formattedSource.append(options.lineSeparatorSequence); - // 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression - dumpTab(depth - 1); - } - break; - default : - formattedSource.append(currentChar); + case '\r': + break; + case '\n': + if (i != max - 1) { + // fix for 1FFYL5C: LFCOM:ALL - Incorrect indentation when + // split with a comment inside a condition + // a substring cannot end with a lineSeparatorSequence, + // except if it has been added by format() after a one-line + // comment + formattedSource.append(options.lineSeparatorSequence); + // 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression + dumpTab(depth - 1); + } + break; + default: + formattedSource.append(currentChar); } } } // update positions inside the mappedPositions table if (substringIndex != -1) { if (multipleLineCommentCounter == 0) { - int startPosition = beginningOfLineIndex - + startSubstringIndexes[substringIndex]; - updateMappedPositionsWhileSplitting(startPosition, startPosition - + max); + int startPosition = beginningOfLineIndex + startSubstringIndexes[substringIndex]; + updateMappedPositionsWhileSplitting(startPosition, startPosition + max); } // compute the splitDelta resulting with the operator and blank removal if (substringIndex + 1 != startSubstringIndexes.length) { - increaseSplitDelta(startSubstringIndexes[substringIndex] + max - - startSubstringIndexes[substringIndex + 1]); + increaseSplitDelta(startSubstringIndexes[substringIndex] + max - startSubstringIndexes[substringIndex + 1]); } } // dump postfix operator? @@ -1721,8 +1678,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } // fix for 1FG0BA3: LFCOM:WIN98 - Weird splitting on interfaces // extends has to stand alone on a line when currentString has been split. - if (options.maxLineLength != 0 && splitLine != null - && (operator == TokenNameextends)) { + if (options.maxLineLength != 0 && splitLine != null && (operator == TokenNameextends)) { // || operator == TokenNameimplements // || operator == TokenNamethrows)) { formattedSource.append(options.lineSeparatorSequence); @@ -1759,10 +1715,8 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { int newDepth = (currentResult.startsWith("/*") //$NON-NLS-1$ || currentResult.startsWith("//")) //$NON-NLS-1$ ? indentationLevel - 1 : depth; - outputLine(currentResult, i == 0 || (i == 1 && emptyFirstSubString) - ? preIndented - : false, i == 0 ? newDepth : newDepth + 1, splitOperators[i], i, - splitLine.startSubstringsIndexes, currentString + outputLine(currentResult, i == 0 || (i == 1 && emptyFirstSubString) ? preIndented : false, + i == 0 ? newDepth : newDepth + 1, splitOperators[i], i, splitLine.startSubstringsIndexes, currentString .indexOf(currentResult)); if (i != max - 1) { formattedSource.append(options.lineSeparatorSequence); @@ -1784,8 +1738,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } formattedSource.append(lastOperatorString); increaseSplitDelta(lastOperatorString.length()); - if (insertSpaceAfter(lastOperator) && lastOperator != TokenNameimplements - && lastOperator != TokenNameextends) { + if (insertSpaceAfter(lastOperator) && lastOperator != TokenNameimplements && lastOperator != TokenNameextends) { // && lastOperator != TokenNamethrows) { formattedSource.append(' '); increaseSplitDelta(1); @@ -1802,21 +1755,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { //increaseSplitDelta(operatorString.length()); } } + /** * Pops the top statement of the stack if it is token */ private int pop(int token) { int delta = 0; - if ((constructionsCount > 0) - && (constructions[constructionsCount - 1] == token)) { + if ((constructionsCount > 0) && (constructions[constructionsCount - 1] == token)) { delta--; constructionsCount--; } return delta; } + /** - * Pops the top statement of the stack if it is a BLOCK or a - * NONINDENT_BLOCK. + * Pops the top statement of the stack if it is a BLOCK or a NONINDENT_BLOCK. */ private int popBlock() { int delta = 0; @@ -1828,13 +1781,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } return delta; } + /** - * Pops elements until the stack is empty or the top element is token. - *
+ * Pops elements until the stack is empty or the top element is token.
* Does not remove token from the stack. * * @param token - * the token to be left as the top of the stack + * the token to be left as the top of the stack */ private int popExclusiveUntil(int token) { int delta = 0; @@ -1846,44 +1799,43 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } return delta; } + /** - * Pops elements until the stack is empty or the top element is a BLOCK - * or a NONINDENT_BLOCK.
+ * Pops elements until the stack is empty or the top element is a BLOCK or a NONINDENT_BLOCK.
* Does not remove it from the stack. */ private int popExclusiveUntilBlock() { int startCount = constructionsCount; int delta = 0; - for (int i = startCount - 1; i >= 0 && constructions[i] != BLOCK - && constructions[i] != NONINDENT_BLOCK; i--) { + for (int i = startCount - 1; i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK; i--) { constructionsCount--; delta--; } return delta; } + /** - * Pops elements until the stack is empty or the top element is a BLOCK, - * a NONINDENT_BLOCK or a CASE.
+ * Pops elements until the stack is empty or the top element is a BLOCK, a NONINDENT_BLOCK or a + * CASE.
* Does not remove it from the stack. */ private int popExclusiveUntilBlockOrCase() { int startCount = constructionsCount; int delta = 0; - for (int i = startCount - 1; i >= 0 && constructions[i] != BLOCK - && constructions[i] != NONINDENT_BLOCK + for (int i = startCount - 1; i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK && constructions[i] != TokenNamecase; i--) { constructionsCount--; delta--; } return delta; } + /** - * Pops elements until the stack is empty or the top element is token. - *
+ * Pops elements until the stack is empty or the top element is token.
* Removes token from the stack too. * * @param token - * the token to remove from the stack + * the token to remove from the stack */ private int popInclusiveUntil(int token) { int startCount = constructionsCount; @@ -1900,16 +1852,15 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } return delta; } + /** - * Pops elements until the stack is empty or the top element is a BLOCK - * or a NONINDENT_BLOCK.
+ * Pops elements until the stack is empty or the top element is a BLOCK or a NONINDENT_BLOCK.
* Does not remove it from the stack. */ private int popInclusiveUntilBlock() { int startCount = constructionsCount; int delta = 0; - for (int i = startCount - 1; i >= 0 - && (constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK); i--) { + for (int i = startCount - 1; i >= 0 && (constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK); i--) { delta--; constructionsCount--; } @@ -1920,22 +1871,18 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } return delta; } + /** * Pushes a block in the stack.
- * Pushes a BLOCK if the stack is empty or if the top element - * is a BLOCK, pushes NONINDENT_BLOCK - * otherwise. Creates a new bigger array if the current one is full. + * Pushes a BLOCK if the stack is empty or if the top element is a BLOCK, pushes + * NONINDENT_BLOCK otherwise. Creates a new bigger array if the current one is full. */ private int pushBlock() { int delta = 0; if (constructionsCount == constructions.length) - System.arraycopy(constructions, 0, - (constructions = new int[constructionsCount * 2]), 0, - constructionsCount); - if ((constructionsCount == 0) - || (constructions[constructionsCount - 1] == BLOCK) - || (constructions[constructionsCount - 1] == NONINDENT_BLOCK) - || (constructions[constructionsCount - 1] == TokenNamecase)) { + System.arraycopy(constructions, 0, (constructions = new int[constructionsCount * 2]), 0, constructionsCount); + if ((constructionsCount == 0) || (constructions[constructionsCount - 1] == BLOCK) + || (constructions[constructionsCount - 1] == NONINDENT_BLOCK) || (constructions[constructionsCount - 1] == TokenNamecase)) { delta++; constructions[constructionsCount++] = BLOCK; } else { @@ -1943,33 +1890,31 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { } return delta; } + /** * Pushes token.
* Creates a new bigger array if the current one is full. */ private int pushControlStatement(int token) { if (constructionsCount == constructions.length) - System.arraycopy(constructions, 0, - (constructions = new int[constructionsCount * 2]), 0, - constructionsCount); + System.arraycopy(constructions, 0, (constructions = new int[constructionsCount * 2]), 0, constructionsCount); constructions[constructionsCount++] = token; return 1; } + private static boolean separateFirstArgumentOn(int currentToken) { //return (currentToken == TokenNameCOMMA || currentToken == // TokenNameSEMICOLON); - return currentToken != TokenNameif && currentToken != TokenNameLPAREN - && currentToken != TokenNameNOT && currentToken != TokenNamewhile - && currentToken != TokenNamefor && currentToken != TokenNameswitch; + return currentToken != TokenNameif && currentToken != TokenNameLPAREN && currentToken != TokenNameNOT + && currentToken != TokenNamewhile && currentToken != TokenNamefor && currentToken != TokenNameswitch; } + /** - * Set the positions to map. The mapped positions should be retrieved using - * the getMappedPositions() method. + * Set the positions to map. The mapped positions should be retrieved using the getMappedPositions() method. * * @param positions - * int[] - * @deprecated Set the positions to map using the format(String, int, int[]) - * method. + * int[] + * @deprecated Set the positions to map using the format(String, int, int[]) method. * * @see #getMappedPositions() */ @@ -1979,6 +1924,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { globalDelta = 0; mappedPositions = new int[positions.length]; } + /** * Appends a space character to the current line buffer. */ @@ -1986,29 +1932,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { currentLineBuffer.append(' '); increaseLineDelta(1); } + /** * Splits stringToSplit on the top level token
- * If there are several identical token at the same level, the string is cut - * into many pieces. + * If there are several identical token at the same level, the string is cut into many pieces. * - * @return an object containing the operator and all the substrings or null - * if the string cannot be split + * @return an object containing the operator and all the substrings or null if the string cannot be split */ public SplitLine split(String stringToSplit) { return split(stringToSplit, 0); } + /** * Splits stringToSplit on the top level token
- * If there are several identical token at the same level, the string is cut - * into many pieces. + * If there are several identical token at the same level, the string is cut into many pieces. * - * @return an object containing the operator and all the substrings or null - * if the string cannot be split + * @return an object containing the operator and all the substrings or null if the string cannot be split */ public SplitLine split(String stringToSplit, int offsetInGlobalLine) { /* - * See http://dev.eclipse.org/bugs/show_bug.cgi?id=12540 and - * http://dev.eclipse.org/bugs/show_bug.cgi?id=14387 + * See http://dev.eclipse.org/bugs/show_bug.cgi?id=12540 and http://dev.eclipse.org/bugs/show_bug.cgi?id=14387 */ if (stringToSplit.indexOf("//$NON-NLS") != -1) { //$NON-NLS-1$ return null; @@ -2016,475 +1959,477 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { // split doesn't work correct for PHP return null; // local variables -// int currentToken = 0; -// int splitTokenType = 0; -// int splitTokenDepth = Integer.MAX_VALUE; -// int splitTokenPriority = Integer.MAX_VALUE; -// int[] substringsStartPositions = new int[10]; -// // contains the start position of substrings -// int[] substringsEndPositions = new int[10]; -// // contains the start position of substrings -// int substringsCount = 1; // index in the substringsStartPosition array -// int[] splitOperators = new int[10]; -// // contains the start position of substrings -// int splitOperatorsCount = 0; // index in the substringsStartPosition array -// int[] openParenthesisPosition = new int[10]; -// int openParenthesisPositionCount = 0; -// int position = 0; -// int lastOpenParenthesisPosition = -1; -// // used to remember the position of the 1st open parenthesis -// // needed for a pattern like: A.B(C); we want formatted like A.B( split C); -// // setup the scanner with a new source -// int lastCommentStartPosition = -1; -// // to remember the start position of the last comment -// int firstTokenOnLine = -1; -// // to remember the first token of the line -// int previousToken = -1; -// // to remember the previous token. -// splitScanner.setSource(stringToSplit.toCharArray()); -// try { -// // start the loop -// while (true) { -// // takes the next token -// try { -// if (currentToken != Scanner.TokenNameWHITESPACE) -// previousToken = currentToken; -// currentToken = splitScanner.getNextToken(); -// if (Scanner.DEBUG) { -// int currentEndPosition = splitScanner.getCurrentTokenEndPosition(); -// int currentStartPosition = splitScanner -// .getCurrentTokenStartPosition(); -// System.out.print(currentStartPosition + "," + currentEndPosition -// + ": "); -// System.out.println(scanner.toStringAction(currentToken)); -// } -// } catch (InvalidInputException e) { -// if (!handleInvalidToken(e)) -// throw e; -// currentToken = 0; -// // this value is not modify when an exception is raised. -// } -// if (currentToken == TokenNameEOF) -// break; -// if (firstTokenOnLine == -1) { -// firstTokenOnLine = currentToken; -// } -// switch (currentToken) { -// case TokenNameRBRACE : -// case TokenNameRPAREN : -// if (openParenthesisPositionCount > 0) { -// if (openParenthesisPositionCount == 1 -// && lastOpenParenthesisPosition < openParenthesisPosition[0]) { -// lastOpenParenthesisPosition = openParenthesisPosition[0]; -// } else if ((splitTokenDepth == Integer.MAX_VALUE) -// || (splitTokenDepth > openParenthesisPositionCount && openParenthesisPositionCount == 1)) { -// splitTokenType = 0; -// splitTokenDepth = openParenthesisPositionCount; -// splitTokenPriority = Integer.MAX_VALUE; -// substringsStartPositions[0] = 0; -// // better token means the whole line until now is the first -// // substring -// substringsCount = 1; // resets the count of substrings -// substringsEndPositions[0] = openParenthesisPosition[0]; -// // substring ends on operator start -// position = openParenthesisPosition[0]; -// // the string mustn't be cut before the closing parenthesis but -// // after the opening one. -// splitOperatorsCount = 1; // resets the count of split operators -// splitOperators[0] = 0; -// } -// openParenthesisPositionCount--; -// } -// break; -// case TokenNameLBRACE : -// case TokenNameLPAREN : -// if (openParenthesisPositionCount == openParenthesisPosition.length) { -// System -// .arraycopy( -// openParenthesisPosition, -// 0, -// (openParenthesisPosition = new int[openParenthesisPositionCount * 2]), -// 0, openParenthesisPositionCount); -// } -// openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition; -// if (currentToken == TokenNameLPAREN -// && previousToken == TokenNameRPAREN) { -// openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition; -// } -// break; -// case TokenNameSEMICOLON : -// // ; -// case TokenNameCOMMA : -// // , -// case TokenNameEQUAL : -// // = -// if (openParenthesisPositionCount < splitTokenDepth -// || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) { -// // the current token is better than the one we currently have -// // (in level or in priority if same level) -// // reset the substringsCount -// splitTokenDepth = openParenthesisPositionCount; -// splitTokenType = currentToken; -// splitTokenPriority = getTokenPriority(currentToken); -// substringsStartPositions[0] = 0; -// // better token means the whole line until now is the first -// // substring -// if (separateFirstArgumentOn(firstTokenOnLine) -// && openParenthesisPositionCount > 0) { -// substringsCount = 2; // resets the count of substrings -// substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1]; -// substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1]; -// substringsEndPositions[1] = splitScanner.startPosition; -// splitOperatorsCount = 2; // resets the count of split operators -// splitOperators[0] = 0; -// splitOperators[1] = currentToken; -// position = splitScanner.currentPosition; -// // next substring will start from operator end -// } else { -// substringsCount = 1; // resets the count of substrings -// substringsEndPositions[0] = splitScanner.startPosition; -// // substring ends on operator start -// position = splitScanner.currentPosition; -// // next substring will start from operator end -// splitOperatorsCount = 1; // resets the count of split operators -// splitOperators[0] = currentToken; -// } -// } else { -// if ((openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken)) -// && splitTokenType != TokenNameEQUAL -// && currentToken != TokenNameEQUAL) { -// // fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after -// // split -// // take only the 1st = into account. -// // if another token with the same priority is found, -// // push the start position of the substring and -// // push the token into the stack. -// // create a new array object if the current one is full. -// if (substringsCount == substringsStartPositions.length) { -// System -// .arraycopy( -// substringsStartPositions, -// 0, -// (substringsStartPositions = new int[substringsCount * 2]), -// 0, substringsCount); -// System.arraycopy(substringsEndPositions, 0, -// (substringsEndPositions = new int[substringsCount * 2]), -// 0, substringsCount); -// } -// if (splitOperatorsCount == splitOperators.length) { -// System.arraycopy(splitOperators, 0, -// (splitOperators = new int[splitOperatorsCount * 2]), 0, -// splitOperatorsCount); -// } -// substringsStartPositions[substringsCount] = position; -// substringsEndPositions[substringsCount++] = splitScanner.startPosition; -// // substring ends on operator start -// position = splitScanner.currentPosition; -// // next substring will start from operator end -// splitOperators[splitOperatorsCount++] = currentToken; -// } -// } -// break; -// case TokenNameCOLON : -// // : (15.24) -// // see 1FK7C5R, we only split on a colon, when it is associated -// // with a question-mark. -// // indeed it might appear also behind a case statement, and we do -// // not to break at this point. -// if ((splitOperatorsCount == 0) -// || splitOperators[splitOperatorsCount - 1] != TokenNameQUESTION) { -// break; -// } -// case TokenNameextends : -// case TokenNameimplements : -// //case TokenNamethrows : -// case TokenNameDOT : -// // . -// case TokenNameMULTIPLY : -// // * (15.16.1) -// case TokenNameDIVIDE : -// // / (15.16.2) -// case TokenNameREMAINDER : -// // % (15.16.3) -// case TokenNamePLUS : -// // + (15.17, 15.17.2) -// case TokenNameMINUS : -// // - (15.17.2) -// case TokenNameLEFT_SHIFT : -// // << (15.18) -// case TokenNameRIGHT_SHIFT : -// // >> (15.18) -// // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18) -// case TokenNameLESS : -// // < (15.19.1) -// case TokenNameLESS_EQUAL : -// // <= (15.19.1) -// case TokenNameGREATER : -// // > (15.19.1) -// case TokenNameGREATER_EQUAL : -// // >= (15.19.1) -// // case TokenNameinstanceof : // instanceof -// case TokenNameEQUAL_EQUAL : -// // == (15.20, 15.20.1, 15.20.2, 15.20.3) -// case TokenNameEQUAL_EQUAL_EQUAL : -// // == (15.20, 15.20.1, 15.20.2, 15.20.3) -// case TokenNameNOT_EQUAL : -// // != (15.20, 15.20.1, 15.20.2, 15.20.3) -// case TokenNameNOT_EQUAL_EQUAL : -// // != (15.20, 15.20.1, 15.20.2, 15.20.3) -// case TokenNameAND : -// // & (15.21, 15.21.1, 15.21.2) -// case TokenNameOR : -// // | (15.21, 15.21.1, 15.21.2) -// case TokenNameXOR : -// // ^ (15.21, 15.21.1, 15.21.2) -// case TokenNameAND_AND : -// // && (15.22) -// case TokenNameOR_OR : -// // || (15.23) -// case TokenNameQUESTION : -// // ? (15.24) -// case TokenNameMULTIPLY_EQUAL : -// // *= (15.25.2) -// case TokenNameDIVIDE_EQUAL : -// // /= (15.25.2) -// case TokenNameREMAINDER_EQUAL : -// // %= (15.25.2) -// case TokenNamePLUS_EQUAL : -// // += (15.25.2) -// case TokenNameMINUS_EQUAL : -// // -= (15.25.2) -// case TokenNameLEFT_SHIFT_EQUAL : -// // <<= (15.25.2) -// case TokenNameRIGHT_SHIFT_EQUAL : -// // >>= (15.25.2) -// // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2) -// case TokenNameAND_EQUAL : -// // &= (15.25.2) -// case TokenNameXOR_EQUAL : -// // ^= (15.25.2) -// case TokenNameOR_EQUAL : -// // |= (15.25.2) -// if ((openParenthesisPositionCount < splitTokenDepth || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) -// && !((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS) && (previousToken == TokenNameLBRACE -// || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))) { -// // the current token is better than the one we currently have -// // (in level or in priority if same level) -// // reset the substringsCount -// splitTokenDepth = openParenthesisPositionCount; -// splitTokenType = currentToken; -// splitTokenPriority = getTokenPriority(currentToken); -// substringsStartPositions[0] = 0; -// // better token means the whole line until now is the first -// // substring -// if (separateFirstArgumentOn(firstTokenOnLine) -// && openParenthesisPositionCount > 0) { -// substringsCount = 2; // resets the count of substrings -// substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1]; -// substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1]; -// substringsEndPositions[1] = splitScanner.startPosition; -// splitOperatorsCount = 3; // resets the count of split operators -// splitOperators[0] = 0; -// splitOperators[1] = 0; -// splitOperators[2] = currentToken; -// position = splitScanner.currentPosition; -// // next substring will start from operator end -// } else { -// substringsCount = 1; // resets the count of substrings -// substringsEndPositions[0] = splitScanner.startPosition; -// // substring ends on operator start -// position = splitScanner.currentPosition; -// // next substring will start from operator end -// splitOperatorsCount = 2; // resets the count of split operators -// splitOperators[0] = 0; -// // nothing for first operand since operator will be inserted in -// // front of the second operand -// splitOperators[1] = currentToken; -// } -// } else { -// if (openParenthesisPositionCount == splitTokenDepth -// && splitTokenPriority == getTokenPriority(currentToken)) { -// // if another token with the same priority is found, -// // push the start position of the substring and -// // push the token into the stack. -// // create a new array object if the current one is full. -// if (substringsCount == substringsStartPositions.length) { -// System -// .arraycopy( -// substringsStartPositions, -// 0, -// (substringsStartPositions = new int[substringsCount * 2]), -// 0, substringsCount); -// System.arraycopy(substringsEndPositions, 0, -// (substringsEndPositions = new int[substringsCount * 2]), -// 0, substringsCount); -// } -// if (splitOperatorsCount == splitOperators.length) { -// System.arraycopy(splitOperators, 0, -// (splitOperators = new int[splitOperatorsCount * 2]), 0, -// splitOperatorsCount); -// } -// substringsStartPositions[substringsCount] = position; -// substringsEndPositions[substringsCount++] = splitScanner.startPosition; -// // substring ends on operator start -// position = splitScanner.currentPosition; -// // next substring will start from operator end -// splitOperators[splitOperatorsCount++] = currentToken; -// } -// } -// default : -// break; -// } -// if (isComment(currentToken)) { -// lastCommentStartPosition = splitScanner.startPosition; -// } else { -// lastCommentStartPosition = -1; -// } -// } -// } catch (InvalidInputException e) { -// return null; -// } -// // if the string cannot be split, return null. -// if (splitOperatorsCount == 0) -// return null; -// // ## SPECIAL CASES BEGIN -// if (((splitOperatorsCount == 2 && splitOperators[1] == TokenNameDOT -// && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1) -// || (splitOperatorsCount > 2 && splitOperators[1] == TokenNameDOT -// && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1 && lastOpenParenthesisPosition <= options.maxLineLength) || (separateFirstArgumentOn(firstTokenOnLine) -// && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1)) -// && (lastOpenParenthesisPosition < splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition] != ')')) { -// // fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should -// // not be broken on two lines -// // only one split on a top level . -// // or more than one split on . and substring before open parenthesis fits -// // one line. -// // or split inside parenthesis and first token is not a for/while/if -// SplitLine sl = split( -// stringToSplit.substring(lastOpenParenthesisPosition), -// lastOpenParenthesisPosition); -// if (sl == null || sl.operators[0] != TokenNameCOMMA) { -// // trim() is used to remove the extra blanks at the end of the -// // substring. See PR 1FGYPI1 -// return new SplitLine(new int[]{0, 0}, new String[]{ -// stringToSplit.substring(0, lastOpenParenthesisPosition).trim(), -// stringToSplit.substring(lastOpenParenthesisPosition)}, new int[]{ -// offsetInGlobalLine, -// lastOpenParenthesisPosition + offsetInGlobalLine}); -// } else { -// // right substring can be split and is split on comma -// // copy substrings and operators -// // except if the 1st string is empty. -// int startIndex = (sl.substrings[0].length() == 0) ? 1 : 0; -// int subStringsLength = sl.substrings.length + 1 - startIndex; -// String[] result = new String[subStringsLength]; -// int[] startIndexes = new int[subStringsLength]; -// int operatorsLength = sl.operators.length + 1 - startIndex; -// int[] operators = new int[operatorsLength]; -// result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition); -// operators[0] = 0; -// System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes, -// 1, subStringsLength - 1); -// for (int i = subStringsLength - 1; i >= 0; i--) { -// startIndexes[i] += offsetInGlobalLine; -// } -// System.arraycopy(sl.substrings, startIndex, result, 1, -// subStringsLength - 1); -// System.arraycopy(sl.operators, startIndex, operators, 1, -// operatorsLength - 1); -// return new SplitLine(operators, result, startIndexes); -// } -// } -// // if the last token is a comment and the substring before the comment fits -// // on a line, -// // split before the comment and return the result. -// if (lastCommentStartPosition > -1 -// && lastCommentStartPosition < options.maxLineLength -// && splitTokenPriority > 50) { -// int end = lastCommentStartPosition; -// int start = lastCommentStartPosition; -// if (stringToSplit.charAt(end - 1) == ' ') { -// end--; -// } -// if (start != end && stringToSplit.charAt(start) == ' ') { -// start++; -// } -// return new SplitLine(new int[]{0, 0}, new String[]{ -// stringToSplit.substring(0, end), stringToSplit.substring(start)}, -// new int[]{0, start}); -// } -// if (position != stringToSplit.length()) { -// if (substringsCount == substringsStartPositions.length) { -// System.arraycopy(substringsStartPositions, 0, -// (substringsStartPositions = new int[substringsCount * 2]), 0, -// substringsCount); -// System.arraycopy(substringsEndPositions, 0, -// (substringsEndPositions = new int[substringsCount * 2]), 0, -// substringsCount); -// } -// // avoid empty extra substring, e.g. line terminated with a semi-colon -// substringsStartPositions[substringsCount] = position; -// substringsEndPositions[substringsCount++] = stringToSplit.length(); -// } -// if (splitOperatorsCount == splitOperators.length) { -// System.arraycopy(splitOperators, 0, -// (splitOperators = new int[splitOperatorsCount * 2]), 0, -// splitOperatorsCount); -// } -// splitOperators[splitOperatorsCount] = 0; -// // the last element of the stack is the position of the end of -// // StringToSPlit -// // +1 because the substring method excludes the last character -// String[] result = new String[substringsCount]; -// for (int i = 0; i < substringsCount; i++) { -// int start = substringsStartPositions[i]; -// int end = substringsEndPositions[i]; -// if (stringToSplit.charAt(start) == ' ') { -// start++; -// substringsStartPositions[i]++; -// } -// if (end != start && stringToSplit.charAt(end - 1) == ' ') { -// end--; -// } -// result[i] = stringToSplit.substring(start, end); -// substringsStartPositions[i] += offsetInGlobalLine; -// } -// if (splitOperatorsCount > substringsCount) { -// System.arraycopy(substringsStartPositions, 0, -// (substringsStartPositions = new int[splitOperatorsCount]), 0, -// substringsCount); -// System.arraycopy(substringsEndPositions, 0, -// (substringsEndPositions = new int[splitOperatorsCount]), 0, -// substringsCount); -// for (int i = substringsCount; i < splitOperatorsCount; i++) { -// substringsStartPositions[i] = position; -// substringsEndPositions[i] = position; -// } -// System.arraycopy(splitOperators, 0, -// (splitOperators = new int[splitOperatorsCount]), 0, -// splitOperatorsCount); -// } else { -// System.arraycopy(substringsStartPositions, 0, -// (substringsStartPositions = new int[substringsCount]), 0, -// substringsCount); -// System.arraycopy(substringsEndPositions, 0, -// (substringsEndPositions = new int[substringsCount]), 0, -// substringsCount); -// System.arraycopy(splitOperators, 0, -// (splitOperators = new int[substringsCount]), 0, substringsCount); -// } -// SplitLine splitLine = new SplitLine(splitOperators, result, -// substringsStartPositions); -// return splitLine; + // int currentToken = 0; + // int splitTokenType = 0; + // int splitTokenDepth = Integer.MAX_VALUE; + // int splitTokenPriority = Integer.MAX_VALUE; + // int[] substringsStartPositions = new int[10]; + // // contains the start position of substrings + // int[] substringsEndPositions = new int[10]; + // // contains the start position of substrings + // int substringsCount = 1; // index in the substringsStartPosition array + // int[] splitOperators = new int[10]; + // // contains the start position of substrings + // int splitOperatorsCount = 0; // index in the substringsStartPosition array + // int[] openParenthesisPosition = new int[10]; + // int openParenthesisPositionCount = 0; + // int position = 0; + // int lastOpenParenthesisPosition = -1; + // // used to remember the position of the 1st open parenthesis + // // needed for a pattern like: A.B(C); we want formatted like A.B( split C); + // // setup the scanner with a new source + // int lastCommentStartPosition = -1; + // // to remember the start position of the last comment + // int firstTokenOnLine = -1; + // // to remember the first token of the line + // int previousToken = -1; + // // to remember the previous token. + // splitScanner.setSource(stringToSplit.toCharArray()); + // try { + // // start the loop + // while (true) { + // // takes the next token + // try { + // if (currentToken != Scanner.TokenNameWHITESPACE) + // previousToken = currentToken; + // currentToken = splitScanner.getNextToken(); + // if (Scanner.DEBUG) { + // int currentEndPosition = splitScanner.getCurrentTokenEndPosition(); + // int currentStartPosition = splitScanner + // .getCurrentTokenStartPosition(); + // System.out.print(currentStartPosition + "," + currentEndPosition + // + ": "); + // System.out.println(scanner.toStringAction(currentToken)); + // } + // } catch (InvalidInputException e) { + // if (!handleInvalidToken(e)) + // throw e; + // currentToken = 0; + // // this value is not modify when an exception is raised. + // } + // if (currentToken == TokenNameEOF) + // break; + // if (firstTokenOnLine == -1) { + // firstTokenOnLine = currentToken; + // } + // switch (currentToken) { + // case TokenNameRBRACE : + // case TokenNameRPAREN : + // if (openParenthesisPositionCount > 0) { + // if (openParenthesisPositionCount == 1 + // && lastOpenParenthesisPosition < openParenthesisPosition[0]) { + // lastOpenParenthesisPosition = openParenthesisPosition[0]; + // } else if ((splitTokenDepth == Integer.MAX_VALUE) + // || (splitTokenDepth > openParenthesisPositionCount && openParenthesisPositionCount == 1)) { + // splitTokenType = 0; + // splitTokenDepth = openParenthesisPositionCount; + // splitTokenPriority = Integer.MAX_VALUE; + // substringsStartPositions[0] = 0; + // // better token means the whole line until now is the first + // // substring + // substringsCount = 1; // resets the count of substrings + // substringsEndPositions[0] = openParenthesisPosition[0]; + // // substring ends on operator start + // position = openParenthesisPosition[0]; + // // the string mustn't be cut before the closing parenthesis but + // // after the opening one. + // splitOperatorsCount = 1; // resets the count of split operators + // splitOperators[0] = 0; + // } + // openParenthesisPositionCount--; + // } + // break; + // case TokenNameLBRACE : + // case TokenNameLPAREN : + // if (openParenthesisPositionCount == openParenthesisPosition.length) { + // System + // .arraycopy( + // openParenthesisPosition, + // 0, + // (openParenthesisPosition = new int[openParenthesisPositionCount * 2]), + // 0, openParenthesisPositionCount); + // } + // openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition; + // if (currentToken == TokenNameLPAREN + // && previousToken == TokenNameRPAREN) { + // openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition; + // } + // break; + // case TokenNameSEMICOLON : + // // ; + // case TokenNameCOMMA : + // // , + // case TokenNameEQUAL : + // // = + // if (openParenthesisPositionCount < splitTokenDepth + // || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) { + // // the current token is better than the one we currently have + // // (in level or in priority if same level) + // // reset the substringsCount + // splitTokenDepth = openParenthesisPositionCount; + // splitTokenType = currentToken; + // splitTokenPriority = getTokenPriority(currentToken); + // substringsStartPositions[0] = 0; + // // better token means the whole line until now is the first + // // substring + // if (separateFirstArgumentOn(firstTokenOnLine) + // && openParenthesisPositionCount > 0) { + // substringsCount = 2; // resets the count of substrings + // substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1]; + // substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1]; + // substringsEndPositions[1] = splitScanner.startPosition; + // splitOperatorsCount = 2; // resets the count of split operators + // splitOperators[0] = 0; + // splitOperators[1] = currentToken; + // position = splitScanner.currentPosition; + // // next substring will start from operator end + // } else { + // substringsCount = 1; // resets the count of substrings + // substringsEndPositions[0] = splitScanner.startPosition; + // // substring ends on operator start + // position = splitScanner.currentPosition; + // // next substring will start from operator end + // splitOperatorsCount = 1; // resets the count of split operators + // splitOperators[0] = currentToken; + // } + // } else { + // if ((openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken)) + // && splitTokenType != TokenNameEQUAL + // && currentToken != TokenNameEQUAL) { + // // fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after + // // split + // // take only the 1st = into account. + // // if another token with the same priority is found, + // // push the start position of the substring and + // // push the token into the stack. + // // create a new array object if the current one is full. + // if (substringsCount == substringsStartPositions.length) { + // System + // .arraycopy( + // substringsStartPositions, + // 0, + // (substringsStartPositions = new int[substringsCount * 2]), + // 0, substringsCount); + // System.arraycopy(substringsEndPositions, 0, + // (substringsEndPositions = new int[substringsCount * 2]), + // 0, substringsCount); + // } + // if (splitOperatorsCount == splitOperators.length) { + // System.arraycopy(splitOperators, 0, + // (splitOperators = new int[splitOperatorsCount * 2]), 0, + // splitOperatorsCount); + // } + // substringsStartPositions[substringsCount] = position; + // substringsEndPositions[substringsCount++] = splitScanner.startPosition; + // // substring ends on operator start + // position = splitScanner.currentPosition; + // // next substring will start from operator end + // splitOperators[splitOperatorsCount++] = currentToken; + // } + // } + // break; + // case TokenNameCOLON : + // // : (15.24) + // // see 1FK7C5R, we only split on a colon, when it is associated + // // with a question-mark. + // // indeed it might appear also behind a case statement, and we do + // // not to break at this point. + // if ((splitOperatorsCount == 0) + // || splitOperators[splitOperatorsCount - 1] != TokenNameQUESTION) { + // break; + // } + // case TokenNameextends : + // case TokenNameimplements : + // //case TokenNamethrows : + // case TokenNameDOT : + // // . + // case TokenNameMULTIPLY : + // // * (15.16.1) + // case TokenNameDIVIDE : + // // / (15.16.2) + // case TokenNameREMAINDER : + // // % (15.16.3) + // case TokenNamePLUS : + // // + (15.17, 15.17.2) + // case TokenNameMINUS : + // // - (15.17.2) + // case TokenNameLEFT_SHIFT : + // // << (15.18) + // case TokenNameRIGHT_SHIFT : + // // >> (15.18) + // // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18) + // case TokenNameLESS : + // // < (15.19.1) + // case TokenNameLESS_EQUAL : + // // <= (15.19.1) + // case TokenNameGREATER : + // // > (15.19.1) + // case TokenNameGREATER_EQUAL : + // // >= (15.19.1) + // // case TokenNameinstanceof : // instanceof + // case TokenNameEQUAL_EQUAL : + // // == (15.20, 15.20.1, 15.20.2, 15.20.3) + // case TokenNameEQUAL_EQUAL_EQUAL : + // // == (15.20, 15.20.1, 15.20.2, 15.20.3) + // case TokenNameNOT_EQUAL : + // // != (15.20, 15.20.1, 15.20.2, 15.20.3) + // case TokenNameNOT_EQUAL_EQUAL : + // // != (15.20, 15.20.1, 15.20.2, 15.20.3) + // case TokenNameAND : + // // & (15.21, 15.21.1, 15.21.2) + // case TokenNameOR : + // // | (15.21, 15.21.1, 15.21.2) + // case TokenNameXOR : + // // ^ (15.21, 15.21.1, 15.21.2) + // case TokenNameAND_AND : + // // && (15.22) + // case TokenNameOR_OR : + // // || (15.23) + // case TokenNameQUESTION : + // // ? (15.24) + // case TokenNameMULTIPLY_EQUAL : + // // *= (15.25.2) + // case TokenNameDIVIDE_EQUAL : + // // /= (15.25.2) + // case TokenNameREMAINDER_EQUAL : + // // %= (15.25.2) + // case TokenNamePLUS_EQUAL : + // // += (15.25.2) + // case TokenNameMINUS_EQUAL : + // // -= (15.25.2) + // case TokenNameLEFT_SHIFT_EQUAL : + // // <<= (15.25.2) + // case TokenNameRIGHT_SHIFT_EQUAL : + // // >>= (15.25.2) + // // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2) + // case TokenNameAND_EQUAL : + // // &= (15.25.2) + // case TokenNameXOR_EQUAL : + // // ^= (15.25.2) + // case TokenNameOR_EQUAL : + // // |= (15.25.2) + // if ((openParenthesisPositionCount < splitTokenDepth || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority + // > getTokenPriority(currentToken))) + // && !((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS) && (previousToken == TokenNameLBRACE + // || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))) { + // // the current token is better than the one we currently have + // // (in level or in priority if same level) + // // reset the substringsCount + // splitTokenDepth = openParenthesisPositionCount; + // splitTokenType = currentToken; + // splitTokenPriority = getTokenPriority(currentToken); + // substringsStartPositions[0] = 0; + // // better token means the whole line until now is the first + // // substring + // if (separateFirstArgumentOn(firstTokenOnLine) + // && openParenthesisPositionCount > 0) { + // substringsCount = 2; // resets the count of substrings + // substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1]; + // substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1]; + // substringsEndPositions[1] = splitScanner.startPosition; + // splitOperatorsCount = 3; // resets the count of split operators + // splitOperators[0] = 0; + // splitOperators[1] = 0; + // splitOperators[2] = currentToken; + // position = splitScanner.currentPosition; + // // next substring will start from operator end + // } else { + // substringsCount = 1; // resets the count of substrings + // substringsEndPositions[0] = splitScanner.startPosition; + // // substring ends on operator start + // position = splitScanner.currentPosition; + // // next substring will start from operator end + // splitOperatorsCount = 2; // resets the count of split operators + // splitOperators[0] = 0; + // // nothing for first operand since operator will be inserted in + // // front of the second operand + // splitOperators[1] = currentToken; + // } + // } else { + // if (openParenthesisPositionCount == splitTokenDepth + // && splitTokenPriority == getTokenPriority(currentToken)) { + // // if another token with the same priority is found, + // // push the start position of the substring and + // // push the token into the stack. + // // create a new array object if the current one is full. + // if (substringsCount == substringsStartPositions.length) { + // System + // .arraycopy( + // substringsStartPositions, + // 0, + // (substringsStartPositions = new int[substringsCount * 2]), + // 0, substringsCount); + // System.arraycopy(substringsEndPositions, 0, + // (substringsEndPositions = new int[substringsCount * 2]), + // 0, substringsCount); + // } + // if (splitOperatorsCount == splitOperators.length) { + // System.arraycopy(splitOperators, 0, + // (splitOperators = new int[splitOperatorsCount * 2]), 0, + // splitOperatorsCount); + // } + // substringsStartPositions[substringsCount] = position; + // substringsEndPositions[substringsCount++] = splitScanner.startPosition; + // // substring ends on operator start + // position = splitScanner.currentPosition; + // // next substring will start from operator end + // splitOperators[splitOperatorsCount++] = currentToken; + // } + // } + // default : + // break; + // } + // if (isComment(currentToken)) { + // lastCommentStartPosition = splitScanner.startPosition; + // } else { + // lastCommentStartPosition = -1; + // } + // } + // } catch (InvalidInputException e) { + // return null; + // } + // // if the string cannot be split, return null. + // if (splitOperatorsCount == 0) + // return null; + // // ## SPECIAL CASES BEGIN + // if (((splitOperatorsCount == 2 && splitOperators[1] == TokenNameDOT + // && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1) + // || (splitOperatorsCount > 2 && splitOperators[1] == TokenNameDOT + // && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1 && lastOpenParenthesisPosition <= options.maxLineLength) || + // (separateFirstArgumentOn(firstTokenOnLine) + // && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1)) + // && (lastOpenParenthesisPosition < splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition] != ')')) { + // // fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should + // // not be broken on two lines + // // only one split on a top level . + // // or more than one split on . and substring before open parenthesis fits + // // one line. + // // or split inside parenthesis and first token is not a for/while/if + // SplitLine sl = split( + // stringToSplit.substring(lastOpenParenthesisPosition), + // lastOpenParenthesisPosition); + // if (sl == null || sl.operators[0] != TokenNameCOMMA) { + // // trim() is used to remove the extra blanks at the end of the + // // substring. See PR 1FGYPI1 + // return new SplitLine(new int[]{0, 0}, new String[]{ + // stringToSplit.substring(0, lastOpenParenthesisPosition).trim(), + // stringToSplit.substring(lastOpenParenthesisPosition)}, new int[]{ + // offsetInGlobalLine, + // lastOpenParenthesisPosition + offsetInGlobalLine}); + // } else { + // // right substring can be split and is split on comma + // // copy substrings and operators + // // except if the 1st string is empty. + // int startIndex = (sl.substrings[0].length() == 0) ? 1 : 0; + // int subStringsLength = sl.substrings.length + 1 - startIndex; + // String[] result = new String[subStringsLength]; + // int[] startIndexes = new int[subStringsLength]; + // int operatorsLength = sl.operators.length + 1 - startIndex; + // int[] operators = new int[operatorsLength]; + // result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition); + // operators[0] = 0; + // System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes, + // 1, subStringsLength - 1); + // for (int i = subStringsLength - 1; i >= 0; i--) { + // startIndexes[i] += offsetInGlobalLine; + // } + // System.arraycopy(sl.substrings, startIndex, result, 1, + // subStringsLength - 1); + // System.arraycopy(sl.operators, startIndex, operators, 1, + // operatorsLength - 1); + // return new SplitLine(operators, result, startIndexes); + // } + // } + // // if the last token is a comment and the substring before the comment fits + // // on a line, + // // split before the comment and return the result. + // if (lastCommentStartPosition > -1 + // && lastCommentStartPosition < options.maxLineLength + // && splitTokenPriority > 50) { + // int end = lastCommentStartPosition; + // int start = lastCommentStartPosition; + // if (stringToSplit.charAt(end - 1) == ' ') { + // end--; + // } + // if (start != end && stringToSplit.charAt(start) == ' ') { + // start++; + // } + // return new SplitLine(new int[]{0, 0}, new String[]{ + // stringToSplit.substring(0, end), stringToSplit.substring(start)}, + // new int[]{0, start}); + // } + // if (position != stringToSplit.length()) { + // if (substringsCount == substringsStartPositions.length) { + // System.arraycopy(substringsStartPositions, 0, + // (substringsStartPositions = new int[substringsCount * 2]), 0, + // substringsCount); + // System.arraycopy(substringsEndPositions, 0, + // (substringsEndPositions = new int[substringsCount * 2]), 0, + // substringsCount); + // } + // // avoid empty extra substring, e.g. line terminated with a semi-colon + // substringsStartPositions[substringsCount] = position; + // substringsEndPositions[substringsCount++] = stringToSplit.length(); + // } + // if (splitOperatorsCount == splitOperators.length) { + // System.arraycopy(splitOperators, 0, + // (splitOperators = new int[splitOperatorsCount * 2]), 0, + // splitOperatorsCount); + // } + // splitOperators[splitOperatorsCount] = 0; + // // the last element of the stack is the position of the end of + // // StringToSPlit + // // +1 because the substring method excludes the last character + // String[] result = new String[substringsCount]; + // for (int i = 0; i < substringsCount; i++) { + // int start = substringsStartPositions[i]; + // int end = substringsEndPositions[i]; + // if (stringToSplit.charAt(start) == ' ') { + // start++; + // substringsStartPositions[i]++; + // } + // if (end != start && stringToSplit.charAt(end - 1) == ' ') { + // end--; + // } + // result[i] = stringToSplit.substring(start, end); + // substringsStartPositions[i] += offsetInGlobalLine; + // } + // if (splitOperatorsCount > substringsCount) { + // System.arraycopy(substringsStartPositions, 0, + // (substringsStartPositions = new int[splitOperatorsCount]), 0, + // substringsCount); + // System.arraycopy(substringsEndPositions, 0, + // (substringsEndPositions = new int[splitOperatorsCount]), 0, + // substringsCount); + // for (int i = substringsCount; i < splitOperatorsCount; i++) { + // substringsStartPositions[i] = position; + // substringsEndPositions[i] = position; + // } + // System.arraycopy(splitOperators, 0, + // (splitOperators = new int[splitOperatorsCount]), 0, + // splitOperatorsCount); + // } else { + // System.arraycopy(substringsStartPositions, 0, + // (substringsStartPositions = new int[substringsCount]), 0, + // substringsCount); + // System.arraycopy(substringsEndPositions, 0, + // (substringsEndPositions = new int[substringsCount]), 0, + // substringsCount); + // System.arraycopy(splitOperators, 0, + // (splitOperators = new int[substringsCount]), 0, substringsCount); + // } + // SplitLine splitLine = new SplitLine(splitOperators, result, + // substringsStartPositions); + // return splitLine; } + private void updateMappedPositions(int startPosition) { if (positionsToMap == null) { return; } char[] source = scanner.source; int sourceLength = source.length; - while (indexToMap < positionsToMap.length - && positionsToMap[indexToMap] <= startPosition) { + while (indexToMap < positionsToMap.length && positionsToMap[indexToMap] <= startPosition) { int posToMap = positionsToMap[indexToMap]; if (posToMap < 0 || posToMap >= sourceLength) { // protection against out of bounds position @@ -2506,17 +2451,17 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { indexToMap++; } } - private void updateMappedPositionsWhileSplitting(int startPosition, - int endPosition) { + + private void updateMappedPositionsWhileSplitting(int startPosition, int endPosition) { if (mappedPositions == null || mappedPositions.length == indexInMap) return; - while (indexInMap < mappedPositions.length - && startPosition <= mappedPositions[indexInMap] + while (indexInMap < mappedPositions.length && startPosition <= mappedPositions[indexInMap] && mappedPositions[indexInMap] < endPosition && indexInMap < indexToMap) { mappedPositions[indexInMap] += splitDelta; indexInMap++; } } + private int getLength(String s, int tabDepth) { int length = 0; for (int i = 0; i < tabDepth; i++) { @@ -2525,25 +2470,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { for (int i = 0, max = s.length(); i < max; i++) { char currentChar = s.charAt(i); switch (currentChar) { - case '\t' : - length += options.tabSize; - break; - default : - length++; + case '\t': + length += options.tabSize; + break; + default: + length++; } } return length; } + /** * Sets the initial indentation level * * @param indentationLevel - * new indentation level + * new indentation level * * @deprecated */ public void setInitialIndentationLevel(int newIndentationLevel) { this.initialIndentationLevel = currentLineIndentationLevel = indentationLevel = newIndentationLevel; } - + } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/SplitLine.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/SplitLine.java index 049c220..745aaa3 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/SplitLine.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/SplitLine.java @@ -192,6 +192,9 @@ public class SplitLine implements ITerminalSymbols { case TokenNameOR_EQUAL : // |= (15.25.2) operatorString = "|="; //$NON-NLS-1$ break; + case TokenNameDOT_EQUAL : // .= + operatorString = ".="; //$NON-NLS-1$ + break; case TokenNameDOT : // . operatorString = "."; //$NON-NLS-1$ break; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java index 4c20296..7a33214 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java @@ -17,12 +17,13 @@ import net.sourceforge.phpdt.internal.corext.template.TemplateMessages; import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator; import net.sourceforge.phpdt.internal.ui.dialogs.StatusDialog; import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.template.TemplateVariableProcessor; import net.sourceforge.phpdt.internal.ui.util.SWTUtil; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.IPreferenceConstants; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.Action; @@ -88,7 +89,7 @@ public class EditTemplateDialog extends StatusDialog { // SimpleJavaSourceViewerConfiguration(JavaTextTools tools, ITextEditor editor, IContentAssistProcessor processor) { SimpleJavaSourceViewerConfiguration(JavaTextTools tools, IContentAssistProcessor processor) { - super(tools, null); + super(tools, null, IPHPPartitions.PHP_PARTITIONING); fProcessor= processor; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java index c7e7b17..30cbe67 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java @@ -27,20 +27,19 @@ import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds; import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo; import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter; import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.EditorUtility; import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.preferences.ColorEditor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; -import net.sourceforge.phpdt.internal.ui.preferences.FoldingConfigurationBlock; -import net.sourceforge.phpdt.internal.ui.preferences.PreferencesMessages; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; @@ -52,7 +51,6 @@ import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; @@ -309,7 +307,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements // private Button fAddJavaDocTagsButton; -// private Button fEscapeStringsButton; + private Button fEscapeStringsButton; // private Button fGuessMethodArgumentsButton; private SourceViewer fPreviewViewer; @@ -609,13 +607,13 @@ public class JavaEditorPreferencePage extends PreferencePage implements overlayKeys.add(new OverlayPreferenceStore.OverlayKey( OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP)); - overlayKeys - .add(new OverlayPreferenceStore.OverlayKey( - OverlayPreferenceStore.BOOLEAN, - PreferenceConstants.EDITOR_CLOSE_BRACES)); - overlayKeys.add(new OverlayPreferenceStore.OverlayKey( - OverlayPreferenceStore.BOOLEAN, - PreferenceConstants.EDITOR_CLOSE_JAVADOCS)); +// overlayKeys +// .add(new OverlayPreferenceStore.OverlayKey( +// OverlayPreferenceStore.BOOLEAN, +// PreferenceConstants.EDITOR_CLOSE_BRACES)); +// overlayKeys.add(new OverlayPreferenceStore.OverlayKey( +// OverlayPreferenceStore.BOOLEAN, +// PreferenceConstants.EDITOR_CLOSE_JAVADOCS)); overlayKeys .add(new OverlayPreferenceStore.OverlayKey( OverlayPreferenceStore.BOOLEAN, @@ -901,7 +899,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER, store); fPreviewViewer.configure(new PHPSourceViewerConfiguration(fJavaTextTools, - null)); + null, IPHPPartitions.PHP_PARTITIONING)); // Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT); // fPreviewViewer.getTextWidget().setFont(font); fPreviewViewer.getTextWidget().setFont( @@ -910,7 +908,8 @@ public class JavaEditorPreferencePage extends PreferencePage implements fPreviewViewer.setEditable(false); String content = loadPreviewContentFromFile("ColorSettingPreviewCode.txt"); //$NON-NLS-1$ IDocument document = new Document(content); - fJavaTextTools.setupJavaDocumentPartitioner(document, ".php", null); //IJavaPartitions.JAVA_PARTITIONING); +// fJavaTextTools.setupJavaDocumentPartitioner(document, ".php", null); //IJavaPartitions.JAVA_PARTITIONING); + fJavaTextTools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING); fPreviewViewer.setDocument(document); return fPreviewViewer.getControl(); } @@ -1287,23 +1286,23 @@ public class JavaEditorPreferencePage extends PreferencePage implements group.setText(PreferencesMessages .getString("JavaEditorPreferencePage.typing.description")); //$NON-NLS-1$ -// label = PreferencesMessages -// .getString("JavaEditorPreferencePage.wrapStrings"); -// //$NON-NLS-1$ -// Button button = addCheckBox(group, label, -// PreferenceConstants.EDITOR_WRAP_STRINGS, 1); -// -// label = PreferencesMessages -// .getString("JavaEditorPreferencePage.escapeStrings"); -// //$NON-NLS-1$ -// fEscapeStringsButton = addCheckBox(group, label, -// PreferenceConstants.EDITOR_ESCAPE_STRINGS, 1); -// createDependency(button, fEscapeStringsButton); + label = PreferencesMessages + .getString("JavaEditorPreferencePage.wrapStrings"); + //$NON-NLS-1$ + Button button = addCheckBox(group, label, + PreferenceConstants.EDITOR_WRAP_STRINGS, 1); -// label = PreferencesMessages -// .getString("JavaEditorPreferencePage.smartPaste"); -// //$NON-NLS-1$ -// addCheckBox(group, label, PreferenceConstants.EDITOR_SMART_PASTE, 1); + label = PreferencesMessages + .getString("JavaEditorPreferencePage.escapeStrings"); + //$NON-NLS-1$ + fEscapeStringsButton = addCheckBox(group, label, + PreferenceConstants.EDITOR_ESCAPE_STRINGS, 1); + createDependency(button, fEscapeStringsButton); + + label = PreferencesMessages + .getString("JavaEditorPreferencePage.smartPaste"); + //$NON-NLS-1$ + addCheckBox(group, label, PreferenceConstants.EDITOR_SMART_PASTE, 1); label = PreferencesMessages .getString("JavaEditorPreferencePage.insertSpaceForTabs"); @@ -1324,7 +1323,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements // .getString("JavaEditorPreferencePage.closeBraces"); // //$NON-NLS-1$ // addCheckBox(group, label, PreferenceConstants.EDITOR_CLOSE_BRACES, 1); -// + // label = PreferencesMessages // .getString("JavaEditorPreferencePage.closeJavaDocs"); // //$NON-NLS-1$ @@ -1677,8 +1676,8 @@ public class JavaEditorPreferencePage extends PreferencePage implements // boolean closeJavaDocs = fOverlayStore // .getBoolean(PreferenceConstants.EDITOR_CLOSE_JAVADOCS); // fAddJavaDocTagsButton.setEnabled(closeJavaDocs); -// fEscapeStringsButton.setEnabled(fOverlayStore -// .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS)); + fEscapeStringsButton.setEnabled(fOverlayStore + .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS)); // boolean fillMethodArguments= // fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES); // fGuessMethodArgumentsButton.setEnabled(fillMethodArguments); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java index 6500ee1..72ab748 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java @@ -25,12 +25,13 @@ import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.internal.ui.PHPUIMessages; import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo; import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.IPreferenceConstants; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.preferences.ColorEditor; import org.eclipse.core.runtime.IStatus; @@ -760,12 +761,12 @@ public class PHPEditorPreferencePage extends PreferencePage .add(new OverlayPreferenceStore.OverlayKey( OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SMART_PASTE)); - // overlayKeys.add(new - // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, - // PreferenceConstants.EDITOR_CLOSE_STRINGS)); - // overlayKeys.add(new - // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, - // PreferenceConstants.EDITOR_CLOSE_BRACKETS)); +// overlayKeys.add(new +// OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, +// PreferenceConstants.EDITOR_CLOSE_STRINGS)); +// overlayKeys.add(new +// OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, +// PreferenceConstants.EDITOR_CLOSE_BRACKETS)); overlayKeys .add(new OverlayPreferenceStore.OverlayKey( OverlayPreferenceStore.BOOLEAN, @@ -1060,7 +1061,7 @@ public class PHPEditorPreferencePage extends PreferencePage fPreviewViewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); fPreviewViewer.configure(new PHPSourceViewerConfiguration(fJavaTextTools, - null)); + null, IPHPPartitions.PHP_PARTITIONING)); fPreviewViewer.getTextWidget().setFont( JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT)); fPreviewViewer.setEditable(false); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/TemplatePreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/TemplatePreferencePage.java index d719efe..f375353 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/TemplatePreferencePage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/TemplatePreferencePage.java @@ -11,12 +11,13 @@ import net.sourceforge.phpdt.internal.corext.template.Template; import net.sourceforge.phpdt.internal.corext.template.TemplateMessages; import net.sourceforge.phpdt.internal.corext.template.TemplateSet; import net.sourceforge.phpdt.internal.corext.template.Templates; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.template.TemplateContentProvider; import net.sourceforge.phpdt.internal.ui.text.template.TemplateLabelProvider; import net.sourceforge.phpdt.internal.ui.util.SWTUtil; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.dialogs.ErrorDialog; @@ -359,7 +360,7 @@ public class TemplatePreferencePage document.setDocumentPartitioner(partitioner); partitioner.connect(document); - viewer.configure(new PHPSourceViewerConfiguration(tools, null)); + viewer.configure(new PHPSourceViewerConfiguration(tools, null, IPHPPartitions.PHP_PARTITIONING)); // (tools, null)); viewer.setEditable(false); viewer.setDocument(document); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java index 26116e0..cb1a56d 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java @@ -1,14 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.text; -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ +import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.rules.ICharacterScanner; -import org.eclipse.jface.util.Assert; @@ -105,8 +111,13 @@ public final class BufferedDocumentScanner implements ICharacterScanner { fOffset= 0; } } - + try { return fBuffer[fOffset++]; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("Offset:"+fOffset); + System.out.println("Buffer:"+fBuffer); + throw e; + } } /* @@ -148,4 +159,4 @@ public final class BufferedDocumentScanner implements ICharacterScanner { public final char[][] getLegalLineDelimiters() { return fDelimiters; } -} \ No newline at end of file +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java index 70f5461..ed3302f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java @@ -1,527 +1,580 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.text; -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ +import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner; +import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IPartitionTokenScanner; import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; import org.eclipse.jface.text.rules.Token; - /** - * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments, - * Java strings and Java characters. + * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments, Java strings. */ -public class FastJavaPartitionScanner implements IPartitionTokenScanner { - -// private final static String SKIP= "__skip"; //$NON-NLS-1$ -// public final static String JAVA_STRING= "__php_string"; //$NON-NLS-1$ -// public final static String JAVA_SINGLE_LINE_COMMENT= "__php_singleline_comment"; //$NON-NLS-1$ -// public final static String JAVA_MULTI_LINE_COMMENT= "__php_multiline_comment"; //$NON-NLS-1$ -// public final static String JAVA_DOC= "__php_phpdoc"; //$NON-NLS-1$ - - // states - private static final int HTML= 0; - private static final int SINGLE_LINE_COMMENT= 1; - private static final int MULTI_LINE_COMMENT= 2; - private static final int PHPDOC= 3; -// private static final int CHARACTER= 4; - private static final int STRING_SQ= 4; // single quote string - private static final int STRING_DQ= 5; // double quote string - private static final int PHP= 6; // double quote string - - // beginning of prefixes and postfixes - private static final int NONE= 0; - private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER - private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC - private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC - private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC - private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC - private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT - - /** The scanner. */ -// private final BufferedRuleBasedScanner fScanner= new BufferedRuleBasedScanner(1000); - private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000); // faster implementation - - /** The offset of the last returned token. */ - private int fTokenOffset; - /** The length of the last returned token. */ - private int fTokenLength; - - /** The state of the scanner. */ - private int fState; - /** The last significant characters read. */ - private int fLast; - /** The amount of characters already read on first call to nextToken(). */ - private int fPrefixLength; - - // emulate JavaPartitionScanner -// private static final boolean fgEmulate= false; - private int fJavaOffset; - private int fJavaLength; - - private final IToken[] fTokens= new IToken[] { - new Token(null), - new Token(IPHPPartitions.PHP_SINGLELINE_COMMENT), - new Token(IPHPPartitions.PHP_MULTILINE_COMMENT), - new Token(IPHPPartitions.PHP_PHPDOC_COMMENT), - new Token(IPHPPartitions.PHP_STRING_SQ), - new Token(IPHPPartitions.PHP_STRING_DQ), - new Token(IPHPPartitions.PHP_PARTITIONING), - }; - - /* - * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() - */ - public IToken nextToken() { - - fTokenOffset += fTokenLength; - fTokenLength= fPrefixLength; - - while (true) { - final int ch= fScanner.read(); - - // characters - switch (ch) { - case ICharacterScanner.EOF: - if (fTokenLength > 0) { - fLast= NONE; // ignore last - return preFix(fState, HTML, NONE, 0); - - } else { - fLast= NONE; - fPrefixLength= 0; - return Token.EOF; - } - - case '\r': - if ( fLast != CARRIAGE_RETURN) { - fLast= CARRIAGE_RETURN; - fTokenLength++; - continue; - - } else { - - switch (fState) { - case SINGLE_LINE_COMMENT: -// case CHARACTER: - case STRING_SQ: - case STRING_DQ: - if (fTokenLength > 0) { - IToken token= fTokens[fState]; - - // emulate JavaPartitionScanner -// if (fgEmulate) { -// fTokenLength++; -// fLast= NONE; -// fPrefixLength= 0; -// } else { - fLast= CARRIAGE_RETURN; - fPrefixLength= 1; -// } - - fState= HTML; - return token; - - } else { - consume(); - continue; - } - - default: - consume(); - continue; - } - } - - case '\n': - switch (fState) { - case SINGLE_LINE_COMMENT: -// case CHARACTER: - case STRING_SQ: - case STRING_DQ: - // assert(fTokenLength > 0); - return postFix(fState); - - default: - consume(); - continue; - } - - default: - if ( fLast == CARRIAGE_RETURN) { - switch (fState) { - case SINGLE_LINE_COMMENT: -// case CHARACTER: - case STRING_SQ: - case STRING_DQ: - - int last; - int newState; - switch (ch) { - case '/': - last= SLASH; - newState= HTML; - break; - - case '*': - last= STAR; - newState= HTML; - break; - - case '\'': - last= NONE; - // newState= CHARACTER; - newState= STRING_SQ; - break; - - case '"': - last= NONE; - newState= STRING_DQ; - break; - - case '\r': - last= CARRIAGE_RETURN; - newState= HTML; - break; - - case '\\': - last= BACKSLASH; - newState= HTML; - break; - - default: - last= NONE; - newState= HTML; - break; - } - - fLast= NONE; // ignore fLast - return preFix(fState, newState, last, 1); - - default: - break; - } - } - } - - // states - switch (fState) { - case PHP: - switch (ch) { - case '/': - if (fLast == SLASH) { - if (fTokenLength - getLastLength(fLast) > 0) { - return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2); - } else { - preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2); - fTokenOffset += fTokenLength; - fTokenLength= fPrefixLength; - break; - } - - } else { - fTokenLength++; - fLast= SLASH; - break; - } - - case '*': - if (fLast == SLASH) { - if (fTokenLength - getLastLength(fLast) > 0) - return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2); - else { - preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2); - fTokenOffset += fTokenLength; - fTokenLength= fPrefixLength; - break; - } - - } else { - consume(); - break; - } - - case '\'': - fLast= NONE; // ignore fLast - if (fTokenLength > 0) - return preFix(PHP, STRING_SQ, NONE, 1); - else { - preFix(PHP, STRING_SQ, NONE, 1); - fTokenOffset += fTokenLength; - fTokenLength= fPrefixLength; - break; - } - - case '"': - fLast= NONE; // ignore fLast - if (fTokenLength > 0) - return preFix(PHP, STRING_DQ, NONE, 1); - else { - preFix(PHP, STRING_DQ, NONE, 1); - fTokenOffset += fTokenLength; - fTokenLength= fPrefixLength; - break; - } - - default: - consume(); - break; - } - break; - - case SINGLE_LINE_COMMENT: - consume(); - break; - - case PHPDOC: - switch (ch) { - case '/': - switch (fLast) { - case SLASH_STAR_STAR: - return postFix(MULTI_LINE_COMMENT); - - case STAR: - return postFix(PHPDOC); - - default: - consume(); - break; - } - break; - - case '*': - fTokenLength++; - fLast= STAR; - break; - - default: - consume(); - break; - } - break; - - case MULTI_LINE_COMMENT: - switch (ch) { - case '*': - if (fLast == SLASH_STAR) { - fLast= SLASH_STAR_STAR; - fTokenLength++; - fState= PHPDOC; - } else { - fTokenLength++; - fLast= STAR; - } - break; - - case '/': - if (fLast == STAR) { - return postFix(MULTI_LINE_COMMENT); - } else { - consume(); - break; - } - - default: - consume(); - break; - } - break; - - case STRING_DQ: - switch (ch) { - case '\\': - fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH; - fTokenLength++; - break; - - case '\"': - if (fLast != BACKSLASH) { - return postFix(STRING_DQ); - - } else { - consume(); - break; - } - - default: - consume(); - break; - } - break; - - case STRING_SQ: - switch (ch) { - case '\\': - fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH; - fTokenLength++; - break; - - case '\'': - if (fLast != BACKSLASH) { - return postFix(STRING_SQ); - - } else { - consume(); - break; - } - - default: - consume(); - break; - } - break; - } - } - } - - private static final int getLastLength(int last) { - switch (last) { - default: - return -1; - - case NONE: - return 0; - - case CARRIAGE_RETURN: - case BACKSLASH: - case SLASH: - case STAR: - return 1; - - case SLASH_STAR: - return 2; - - case SLASH_STAR_STAR: - return 3; - } - } - - private final void consume() { - fTokenLength++; - fLast= NONE; - } - - private final IToken postFix(int state) { - fTokenLength++; - fLast= NONE; - fState= HTML; - fPrefixLength= 0; - return fTokens[state]; - } - - private final IToken preFix(int state, int newState, int last, int prefixLength) { - // emulate JavaPartitionScanner -// if (fgEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) { -// fTokenLength -= getLastLength(fLast); -// fJavaOffset= fTokenOffset; -// fJavaLength= fTokenLength; -// fTokenLength= 1; -// fState= newState; -// fPrefixLength= prefixLength; -// fLast= last; -// return fTokens[state]; -// -// } else { - fTokenLength -= getLastLength(fLast); - fLast= last; - fPrefixLength= prefixLength; - IToken token= fTokens[state]; - fState= newState; - return token; -// } - } - - private static int getState(String contentType) { - - if (contentType == null) - return HTML; - - else if (contentType.equals(IPHPPartitions.PHP_PARTITIONING)) - return PHP; - - else if (contentType.equals(IPHPPartitions.PHP_SINGLELINE_COMMENT)) - return SINGLE_LINE_COMMENT; - - else if (contentType.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) - return MULTI_LINE_COMMENT; - - else if (contentType.equals(IPHPPartitions.PHP_PHPDOC_COMMENT)) - return PHPDOC; - - else if (contentType.equals(IPHPPartitions.PHP_STRING_DQ)) - return STRING_DQ; - - else if (contentType.equals(IPHPPartitions.PHP_STRING_SQ)) - return STRING_SQ; - -// else if (contentType.equals(SKIP)) -// return CHARACTER; - - else - return HTML; - } - - /* - * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int) - */ - public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { - - fScanner.setRange(document, offset, length); - fTokenOffset= partitionOffset; - fTokenLength= 0; - fPrefixLength= offset - partitionOffset; - fLast= NONE; - - if (offset == partitionOffset) { - // restart at beginning of partition - fState= HTML; - } else { - fState= getState(contentType); - } - - // emulate JavaPartitionScanner -// if (fgEmulate) { -// fJavaOffset= -1; -// fJavaLength= 0; -// } - } - - /* - * @see ITokenScanner#setRange(IDocument, int, int) - */ - public void setRange(IDocument document, int offset, int length) { - - fScanner.setRange(document, offset, length); - fTokenOffset= offset; - fTokenLength= 0; - fPrefixLength= 0; - fLast= NONE; - fState= HTML; - - // emulate JavaPartitionScanner -// if (fgEmulate) { -// fJavaOffset= -1; -// fJavaLength= 0; -// } - } - - /* - * @see ITokenScanner#getTokenLength() - */ - public int getTokenLength() { - return fTokenLength; - } - - /* - * @see ITokenScanner#getTokenOffset() - */ - public int getTokenOffset() { - return fTokenOffset; - } - -} +public class FastJavaPartitionScanner implements IPartitionTokenScanner, IPHPPartitions { + + // states + private static final int PHP = 0; + + private static final int SINGLE_LINE_COMMENT = 1; + + private static final int MULTI_LINE_COMMENT = 2; + + private static final int PHPDOC = 3; + + private static final int STRING_DQ = 4; + + private static final int STRING_SQ = 5; + + // private static final int CHARACTER= 4; + + // beginning of prefixes and postfixes + private static final int NONE = 0; + + private static final int BACKSLASH = 1; // postfix for STRING and CHARACTER + + private static final int SLASH = 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC + + private static final int SLASH_STAR = 3; // prefix for MULTI_LINE_COMMENT or JAVADOC + + private static final int SLASH_STAR_STAR = 4; // prefix for MULTI_LINE_COMMENT or JAVADOC + + private static final int STAR = 5; // postfix for MULTI_LINE_COMMENT or JAVADOC + + private static final int CARRIAGE_RETURN = 6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT + + /** The scanner. */ + private final BufferedDocumentScanner fScanner = new BufferedDocumentScanner(1000); // faster implementation + + /** The offset of the last returned token. */ + private int fTokenOffset; + + /** The length of the last returned token. */ + private int fTokenLength; + + /** The state of the scanner. */ + private int fState; + + /** The last significant characters read. */ + private int fLast; + + /** The amount of characters already read on first call to nextToken(). */ + private int fPrefixLength; + + // emulate JavaPartitionScanner + private boolean fEmulate = false; + + private int fJavaOffset; + + private int fJavaLength; + + private final IToken[] fTokens = new IToken[] { new Token(null), new Token(PHP_SINGLELINE_COMMENT), + new Token(PHP_MULTILINE_COMMENT), new Token(PHP_PHPDOC_COMMENT), new Token(PHP_STRING_DQ), new Token(PHP_STRING_SQ) }; + + public FastJavaPartitionScanner(boolean emulate) { + fEmulate = emulate; + } + + public FastJavaPartitionScanner() { + this(false); + } + + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() + */ + public IToken nextToken() { + + // emulate JavaPartitionScanner + if (fEmulate) { + if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) { + fTokenOffset += fTokenLength; + return fTokens[PHP]; + } else { + fJavaOffset = -1; + fJavaLength = 0; + } + } + + fTokenOffset += fTokenLength; + fTokenLength = fPrefixLength; + + while (true) { + final int ch = fScanner.read(); + + // characters + switch (ch) { + case ICharacterScanner.EOF: + if (fTokenLength > 0) { + fLast = NONE; // ignore last + return preFix(fState, PHP, NONE, 0); + + } else { + fLast = NONE; + fPrefixLength = 0; + return Token.EOF; + } + + case '\r': + // emulate JavaPartitionScanner + if (!fEmulate && fLast != CARRIAGE_RETURN) { + fLast = CARRIAGE_RETURN; + fTokenLength++; + continue; + + } else { + + switch (fState) { + case SINGLE_LINE_COMMENT: + // case CHARACTER: + // case STRING_DQ: + // case STRING_SQ: + if (fTokenLength > 0) { + IToken token = fTokens[fState]; + + // emulate JavaPartitionScanner + if (fEmulate) { + fTokenLength++; + fLast = NONE; + fPrefixLength = 0; + } else { + fLast = CARRIAGE_RETURN; + fPrefixLength = 1; + } + + fState = PHP; + return token; + + } else { + consume(); + continue; + } + + default: + consume(); + continue; + } + } + + case '\n': + switch (fState) { + case SINGLE_LINE_COMMENT: + // case CHARACTER: + // case STRING_DQ: + // case STRING_SQ: + // assert(fTokenLength > 0); + return postFix(fState); + + default: + consume(); + continue; + } + + default: + if (!fEmulate && fLast == CARRIAGE_RETURN) { + switch (fState) { + case SINGLE_LINE_COMMENT: + // case CHARACTER: + // case STRING_DQ: + // case STRING_SQ: + int last; + int newState; + switch (ch) { + case '/': + last = SLASH; + newState = PHP; + break; + + case '*': + last = STAR; + newState = PHP; + break; + + case '\'': + last = NONE; + newState = STRING_SQ; + break; + + case '"': + last = NONE; + newState = STRING_DQ; + break; + + case '\r': + last = CARRIAGE_RETURN; + newState = PHP; + break; + + case '\\': + last = BACKSLASH; + newState = PHP; + break; + + default: + last = NONE; + newState = PHP; + break; + } + + fLast = NONE; // ignore fLast + return preFix(fState, newState, last, 1); + + default: + break; + } + } + } + + // states + switch (fState) { + case PHP: + switch (ch) { + case '#': + if (fTokenLength > 0) { + return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1); + } else { + preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1); + fTokenOffset += fTokenLength; + fTokenLength = fPrefixLength; + break; + } + case '/': + if (fLast == SLASH) { + if (fTokenLength - getLastLength(fLast) > 0) { + return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2); + } else { + preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2); + fTokenOffset += fTokenLength; + fTokenLength = fPrefixLength; + break; + } + + } else { + fTokenLength++; + fLast = SLASH; + break; + } + + case '*': + if (fLast == SLASH) { + if (fTokenLength - getLastLength(fLast) > 0) + return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2); + else { + preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2); + fTokenOffset += fTokenLength; + fTokenLength = fPrefixLength; + break; + } + + } else { + consume(); + break; + } + + case '\'': + fLast = NONE; // ignore fLast + if (fTokenLength > 0) + return preFix(PHP, STRING_SQ, NONE, 1); + else { + preFix(PHP, STRING_SQ, NONE, 1); + fTokenOffset += fTokenLength; + fTokenLength = fPrefixLength; + break; + } + + case '"': + fLast = NONE; // ignore fLast + if (fTokenLength > 0) + return preFix(PHP, STRING_DQ, NONE, 1); + else { + preFix(PHP, STRING_DQ, NONE, 1); + fTokenOffset += fTokenLength; + fTokenLength = fPrefixLength; + break; + } + + default: + consume(); + break; + } + break; + + case SINGLE_LINE_COMMENT: + consume(); + break; + + case PHPDOC: + switch (ch) { + case '/': + switch (fLast) { + case SLASH_STAR_STAR: + return postFix(MULTI_LINE_COMMENT); + + case STAR: + return postFix(PHPDOC); + + default: + consume(); + break; + } + break; + + case '*': + fTokenLength++; + fLast = STAR; + break; + + default: + consume(); + break; + } + break; + + case MULTI_LINE_COMMENT: + switch (ch) { + case '*': + if (fLast == SLASH_STAR) { + fLast = SLASH_STAR_STAR; + fTokenLength++; + fState = PHPDOC; + } else { + fTokenLength++; + fLast = STAR; + } + break; + + case '/': + if (fLast == STAR) { + return postFix(MULTI_LINE_COMMENT); + } else { + consume(); + break; + } + + default: + consume(); + break; + } + break; + + case STRING_DQ: + switch (ch) { + case '\\': + fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH; + fTokenLength++; + break; + + case '\"': + if (fLast != BACKSLASH) { + return postFix(STRING_DQ); + + } else { + consume(); + break; + } + + default: + consume(); + break; + } + break; + case STRING_SQ: + switch (ch) { + case '\\': + fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH; + fTokenLength++; + break; + + case '\'': + if (fLast != BACKSLASH) { + return postFix(STRING_SQ); + + } else { + consume(); + break; + } + + default: + consume(); + break; + } + break; + // case CHARACTER: + // switch (ch) { + // case '\\': + // fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH; + // fTokenLength++; + // break; + // + // case '\'': + // if (fLast != BACKSLASH) { + // return postFix(CHARACTER); + // + // } else { + // consume(); + // break; + // } + // + // default: + // consume(); + // break; + // } + // break; + } + } + } + + private static final int getLastLength(int last) { + switch (last) { + default: + return -1; + + case NONE: + return 0; + + case CARRIAGE_RETURN: + case BACKSLASH: + case SLASH: + case STAR: + return 1; + + case SLASH_STAR: + return 2; + + case SLASH_STAR_STAR: + return 3; + } + } + + private final void consume() { + fTokenLength++; + fLast = NONE; + } + + private final IToken postFix(int state) { + fTokenLength++; + fLast = NONE; + fState = PHP; + fPrefixLength = 0; + return fTokens[state]; + } + + private final IToken preFix(int state, int newState, int last, int prefixLength) { + // emulate JavaPartitionScanner + if (fEmulate && state == PHP && (fTokenLength - getLastLength(fLast) > 0)) { + fTokenLength -= getLastLength(fLast); + fJavaOffset = fTokenOffset; + fJavaLength = fTokenLength; + fTokenLength = 1; + fState = newState; + fPrefixLength = prefixLength; + fLast = last; + return fTokens[state]; + + } else { + fTokenLength -= getLastLength(fLast); + fLast = last; + fPrefixLength = prefixLength; + IToken token = fTokens[state]; + fState = newState; + return token; + } + } + + private static int getState(String contentType) { + + if (contentType == null) + return PHP; + + else if (contentType.equals(PHP_SINGLELINE_COMMENT)) + return SINGLE_LINE_COMMENT; + + else if (contentType.equals(PHP_MULTILINE_COMMENT)) + return MULTI_LINE_COMMENT; + + else if (contentType.equals(PHP_PHPDOC_COMMENT)) + return PHPDOC; + + else if (contentType.equals(PHP_STRING_DQ)) + return STRING_DQ; + else if (contentType.equals(PHP_STRING_SQ)) + return STRING_SQ; + // else if (contentType.equals(JAVA_CHARACTER)) + // return CHARACTER; + + else + return PHP; + } + + /* + * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int) + */ + public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { + fScanner.setRange(document, offset, length); + setRange(document, offset, length); + fTokenOffset = partitionOffset; + fTokenLength = 0; + fPrefixLength = offset - partitionOffset; + fLast = NONE; + + if (offset == partitionOffset) { + // restart at beginning of partition + fState = PHP; + } else { + fState = getState(contentType); + } + + // emulate JavaPartitionScanner + if (fEmulate) { + fJavaOffset = -1; + fJavaLength = 0; + } + } + + /* + * @see ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + fScanner.setRange(document, offset, length); + fTokenOffset = offset; + fTokenLength = 0; + fPrefixLength = 0; + fLast = NONE; + fState = PHP; + + // emulate JavaPartitionScanner + if (fEmulate) { + fJavaOffset = -1; + fJavaLength = 0; + } + } + + /* + * @see ITokenScanner#getTokenLength() + */ + public int getTokenLength() { + return fTokenLength; + } + + /* + * @see ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + if (AbstractPartitioner.DEBUG) { + Assert.isTrue(fTokenOffset >= 0, Integer.toString(fTokenOffset)); + } + return fTokenOffset; + } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java index 8d6b040..8ba709a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java @@ -10,7 +10,8 @@ package net.sourceforge.phpdt.internal.ui.text; */ public interface IPHPPartitions { - public final static String PHP_PARTITIONING = "__php"; //$NON-NLS-1$ + public final static String PHP_PARTITIONING = "___php_partitioning"; //$NON-NLS-1$ + public final static String PHP_PHPDOC_COMMENT = "__php_phpdoc_comment"; //$NON-NLS-1$ public final static String PHP_SINGLELINE_COMMENT = "__php_singleline_comment"; //$NON-NLS-1$ public final static String PHP_MULTILINE_COMMENT = "__php_multiline_comment"; //$NON-NLS-1$ @@ -22,6 +23,7 @@ public interface IPHPPartitions public final static String CSS_MULTILINE_COMMENT = "__css_multiline_comment"; //$NON-NLS-1$ public final static String HTML = "__html"; //$NON-NLS-1$ public final static String HTML_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$ + public final static String SMARTY = "__smarty"; //$NON-NLS-1$ public final static String SMARTY_MULTILINE_COMMENT = "__smarty_multiline_comment"; //$NON-NLS-1$ diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java new file mode 100644 index 0000000..edd3013 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java @@ -0,0 +1,1005 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + +import java.util.Arrays; + +import net.sourceforge.phpdt.internal.core.Assert; +import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager.UndoSpec; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentCommand; +import org.eclipse.jface.text.IAutoEditStrategy; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.TextUtilities; +import org.eclipse.text.edits.DeleteEdit; +import org.eclipse.text.edits.MalformedTreeException; +import org.eclipse.text.edits.ReplaceEdit; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.texteditor.ITextEditorExtension2; +import org.eclipse.ui.texteditor.ITextEditorExtension3; + +/** + * Modifies DocumentCommands inserting semicolons and opening braces to place them + * smartly, i.e. moving them to the end of a line if that is what the user expects. + * + *

In practice, semicolons and braces (and the caret) are moved to the end of the line if they are typed + * anywhere except for semicolons in a for statements definition. If the line contains a semicolon + * or brace after the current caret position, the cursor is moved after it.

+ * + * @see org.eclipse.jface.text.DocumentCommand + * @since 3.0 + */ +public class SmartSemicolonAutoEditStrategy implements IAutoEditStrategy { + + /** String representation of a semicolon. */ + private static final String SEMICOLON= ";"; //$NON-NLS-1$ + /** Char representation of a semicolon. */ + private static final char SEMICHAR= ';'; + /** String represenattion of a opening brace. */ + private static final String BRACE= "{"; //$NON-NLS-1$ + /** Char representation of a opening brace */ + private static final char BRACECHAR= '{'; + + private char fCharacter; + private String fPartitioning; + + /** + * Creates a new SmartSemicolonAutoEditStrategy. + * + * @param partitioning the document partitioning + */ + public SmartSemicolonAutoEditStrategy(String partitioning) { + fPartitioning= partitioning; + } + + /* + * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand) + */ + public void customizeDocumentCommand(IDocument document, DocumentCommand command) { + // 0: early pruning + // also customize if doit is false (so it works in code completion situations) + // if (!command.doit) + // return; + + if (command.text == null) + return; + + if (command.text.equals(SEMICOLON)) + fCharacter= SEMICHAR; + else if (command.text.equals(BRACE)) + fCharacter= BRACECHAR; + else + return; + + IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore(); + if (fCharacter == SEMICHAR && !store.getBoolean(PreferenceConstants.EDITOR_SMART_SEMICOLON)) + return; + if (fCharacter == BRACECHAR && !store.getBoolean(PreferenceConstants.EDITOR_SMART_OPENING_BRACE)) + return; + + IWorkbenchPage page= PHPeclipsePlugin.getActivePage(); + if (page == null) + return; + IEditorPart part= page.getActiveEditor(); + if (!(part instanceof PHPUnitEditor)) + return; + PHPUnitEditor editor= (PHPUnitEditor)part; + if (editor.getInsertMode() != ITextEditorExtension3.SMART_INSERT || !editor.isEditable()) + return; + ITextEditorExtension2 extension= (ITextEditorExtension2)editor.getAdapter(ITextEditorExtension2.class); + if (extension != null && !extension.validateEditorInputState()) + return; + if (isMultilineSelection(document, command)) + return; + + // 1: find concerned line / position in java code, location in statement + int pos= command.offset; + ITextSelection line; + try { + IRegion l= document.getLineInformationOfOffset(pos); + line= new TextSelection(document, l.getOffset(), l.getLength()); + } catch (BadLocationException e) { + return; + } + + // 2: choose action based on findings (is for-Statement?) + // for now: compute the best position to insert the new character + int positionInLine= computeCharacterPosition(document, line, pos - line.getOffset(), fCharacter, fPartitioning); + int position= positionInLine + line.getOffset(); + + // never position before the current position! + if (position < pos) + return; + + // never double already existing content + if (alreadyPresent(document, fCharacter, position)) + return; + + // don't do special processing if what we do is actually the normal behaviour + String insertion= adjustSpacing(document, position, fCharacter); + if (command.offset == position && insertion.equals(command.text)) + return; + + try { + + final SmartBackspaceManager manager= (SmartBackspaceManager) editor.getAdapter(SmartBackspaceManager.class); + if (manager != null && PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_BACKSPACE)) { + TextEdit e1= new ReplaceEdit(command.offset, command.text.length(), document.get(command.offset, command.length)); + UndoSpec s1= new UndoSpec(command.offset + command.text.length(), + new Region(command.offset, 0), + new TextEdit[] {e1}, + 0, + null); + + DeleteEdit smart= new DeleteEdit(position, insertion.length()); + ReplaceEdit raw= new ReplaceEdit(command.offset, command.length, command.text); + UndoSpec s2= new UndoSpec(position + insertion.length(), + new Region(command.offset + command.text.length(), 0), + new TextEdit[] {smart, raw}, + 2, + s1); + manager.register(s2); + } + + // 3: modify command + command.offset= position; + command.length= 0; + command.caretOffset= position; + command.text= insertion; + command.doit= true; + command.owner= null; + } catch (MalformedTreeException e) { + PHPeclipsePlugin.log(e); + } catch (BadLocationException e) { + PHPeclipsePlugin.log(e); + } + + + } + + /** + * Returns true if the document command is applied on a multi + * line selection, false otherwise. + * + * @param document the document + * @param command the command + * @return true if command is a multiline command + */ + private boolean isMultilineSelection(IDocument document, DocumentCommand command) { + try { + return document.getNumberOfLines(command.offset, command.length) > 1; + } catch (BadLocationException e) { + // ignore + return false; + } + } + + /** + * Adds a space before a brace if it is inserted after a parenthesis, equal sign, or one + * of the keywords try, else, do. + * + * @param document the document we are working on + * @param position the insert position of character + * @param character the character to be inserted + * @return a String consisting of character plus any additional spacing + */ + private String adjustSpacing(IDocument doc, int position, char character) { + if (character == BRACECHAR) { + if (position > 0 && position <= doc.getLength()) { + int pos= position - 1; + if (looksLike(doc, pos, ")") //$NON-NLS-1$ + || looksLike(doc, pos, "=") //$NON-NLS-1$ + || looksLike(doc, pos, "]") //$NON-NLS-1$ + || looksLike(doc, pos, "try") //$NON-NLS-1$ + || looksLike(doc, pos, "else") //$NON-NLS-1$ + || looksLike(doc, pos, "synchronized") //$NON-NLS-1$ + || looksLike(doc, pos, "static") //$NON-NLS-1$ + || looksLike(doc, pos, "finally") //$NON-NLS-1$ + || looksLike(doc, pos, "do")) //$NON-NLS-1$ + return new String(new char[] { ' ', character }); + } + } + + return new String(new char[] { character }); + } + + /** + * Checks whether a character to be inserted is already present at the insert location (perhaps + * separated by some whitespace from position. + * + * @param document the document we are working on + * @param position the insert position of ch + * @param character the character to be inserted + * @return true if ch is already present at location, false otherwise + */ + private boolean alreadyPresent(IDocument document, char ch, int position) { + int pos= firstNonWhitespaceForward(document, position, fPartitioning, document.getLength()); + try { + if (pos != -1 && document.getChar(pos) == ch) + return true; + } catch (BadLocationException e) { + } + + return false; + } + + /** + * Computes the next insert position of the given character in the current line. + * + * @param document the document we are working on + * @param line the line where the change is being made + * @param offset the position of the caret in the line when character was typed + * @param character the character to look for + * @param partitioning the document partitioning + * @return the position where character should be inserted / replaced + */ + protected static int computeCharacterPosition(IDocument document, ITextSelection line, int offset, char character, String partitioning) { + String text= line.getText(); + if (text == null) + return 0; + + int insertPos; + if (character == BRACECHAR) { + + insertPos= computeArrayInitializationPos(document, line, offset, partitioning); + + if (insertPos == -1) { + insertPos= computeAfterTryDoElse(document, line, offset); + } + + if (insertPos == -1) { + insertPos= computeAfterParenthesis(document, line, offset, partitioning); + } + + } else if (character == SEMICHAR) { + + if (isForStatement(text, offset)) { + insertPos= -1; // don't do anything in for statements, as semis are vital part of these + } else { + int nextPartitionPos= nextPartitionOrLineEnd(document, line, offset, partitioning); + insertPos= startOfWhitespaceBeforeOffset(text, nextPartitionPos); + // if there is a semi present, return its location as alreadyPresent() will take it out this way. + if (insertPos > 0 && text.charAt(insertPos - 1) == character) + insertPos= insertPos - 1; + } + + } else { + Assert.isTrue(false); + return -1; + } + + return insertPos; + } + + /** + * Computes an insert position for an opening brace if offset maps to a position in + * document that looks like being the RHS of an assignment or like an array definition. + * + * @param document the document being modified + * @param line the current line under investigation + * @param offset the offset of the caret position, relative to the line start. + * @param partitioning the document partitioning + * @return an insert position relative to the line start if line looks like being an array initialization at offset, -1 otherwise + */ + private static int computeArrayInitializationPos(IDocument document, ITextSelection line, int offset, String partitioning) { + // search backward while WS, find = (not != <= >= ==) in default partition + int pos= offset + line.getOffset(); + + if (pos == 0) + return -1; + + int p= firstNonWhitespaceBackward(document, pos - 1, partitioning, -1); + + if (p == -1) + return -1; + + try { + + char ch= document.getChar(p); + if (ch != '=' && ch != ']') + return -1; + + if (p == 0) + return offset; + + p= firstNonWhitespaceBackward(document, p - 1, partitioning, -1); + if (p == -1) + return -1; + + ch= document.getChar(p); + if (Character.isJavaIdentifierPart(ch) || ch == ']' || ch == '[') + return offset; + + } catch (BadLocationException e) { + } + return -1; + } + + /** + * Computes an insert position for an opening brace if offset maps to a position in + * document involving a keyword taking a block after it. These are: try, + * do, synchronized, static, finally, or else. + * + * @param document the document being modified + * @param line the current line under investigation + * @param offset the offset of the caret position, relative to the line start. + * @return an insert position relative to the line start if line contains one of the above keywords at or before offset, -1 otherwise + */ + private static int computeAfterTryDoElse(IDocument doc, ITextSelection line, int offset) { + // search backward while WS, find 'try', 'do', 'else' in default partition + int p= offset + line.getOffset(); + p= firstWhitespaceToRight(doc, p); + if (p == -1) + return -1; + p--; + + if (looksLike(doc, p, "try") //$NON-NLS-1$ + || looksLike(doc, p, "do") //$NON-NLS-1$ + || looksLike(doc, p, "synchronized") //$NON-NLS-1$ + || looksLike(doc, p, "static") //$NON-NLS-1$ + || looksLike(doc, p, "finally") //$NON-NLS-1$ + || looksLike(doc, p, "else")) //$NON-NLS-1$ + return p + 1 - line.getOffset(); + + return -1; + } + + /** + * Computes an insert position for an opening brace if offset maps to a position in + * document with a expression in parenthesis that will take a block after the closing parenthesis. + * + * @param document the document being modified + * @param line the current line under investigation + * @param offset the offset of the caret position, relative to the line start. + * @param partitioning the document partitioning + * @return an insert position relative to the line start if line contains a parenthesized expression that can be followed by a block, -1 otherwise + */ + private static int computeAfterParenthesis(IDocument document, ITextSelection line, int offset, String partitioning) { + // find the opening parenthesis for every closing parenthesis on the current line after offset + // return the position behind the closing parenthesis if it looks like a method declaration + // or an expression for an if, while, for, catch statement + int pos= offset + line.getOffset(); + int length= line.getOffset() + line.getLength(); + int scanTo= scanForward(document, pos, partitioning, length, '}'); + if (scanTo == -1) + scanTo= length; + + int closingParen= findClosingParenToLeft(document, pos, partitioning) - 1; + + while (true) { + int startScan= closingParen + 1; + closingParen= scanForward(document, startScan, partitioning, scanTo, ')'); + if (closingParen == -1) + break; + + int openingParen= findOpeningParenMatch(document, closingParen, partitioning); + + // no way an expression at the beginning of the document can mean anything + if (openingParen < 1) + break; + + // only select insert positions for parenthesis currently embracing the caret + if (openingParen > pos) + continue; + + if (looksLikeAnonymousClassDef(document, openingParen - 1, partitioning)) + return closingParen + 1 - line.getOffset(); + + if (looksLikeIfWhileForCatch(document, openingParen - 1, partitioning)) + return closingParen + 1 - line.getOffset(); + + if (looksLikeMethodDecl(document, openingParen - 1, partitioning)) + return closingParen + 1 - line.getOffset(); + + } + + return -1; + } + + /** + * Finds a closing parenthesis to the left of position in document, where that parenthesis is only + * separated by whitespace from position. If no such parenthesis can be found, position is returned. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @return the position of a closing parenthesis left to position separated only by whitespace, or position if no parenthesis can be found + */ + private static int findClosingParenToLeft(IDocument document, int position, String partitioning) { + final char CLOSING_PAREN= ')'; + try { + if (position < 1) + return position; + + int nonWS= firstNonWhitespaceBackward(document, position - 1, partitioning, -1); + if (nonWS != -1 && document.getChar(nonWS) == CLOSING_PAREN) + return nonWS; + } catch (BadLocationException e1) { + } + return position; + } + + /** + * Finds the first whitespace character position to the right of (and including) position. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @return the position of a whitespace character greater or equal than position separated only by whitespace, or -1 if none found + */ + private static int firstWhitespaceToRight(IDocument document, int position) { + int length= document.getLength(); + Assert.isTrue(position >= 0); + Assert.isTrue(position <= length); + + try { + while (position < length) { + char ch= document.getChar(position); + if (Character.isWhitespace(ch)) + return position; + position++; + } + return position; + } catch (BadLocationException e) { + } + return -1; + } + + /** + * Finds the highest position in document such that the position is <= position + * and > bound and Character.isWhitespace(document.getChar(pos)) evaluates to false + * and the position is in the default partition. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @param bound the first position in document to not consider any more, with bound > position + * @return the highest position of one element in chars in [position, scanTo) that resides in a Java partition, or -1 if none can be found + */ + private static int firstNonWhitespaceBackward(IDocument document, int position, String partitioning, int bound) { + Assert.isTrue(position < document.getLength()); + Assert.isTrue(bound >= -1); + + try { + while (position > bound) { + char ch= document.getChar(position); + if (!Character.isWhitespace(ch) && isDefaultPartition(document, position, partitioning)) + return position; + position--; + } + } catch (BadLocationException e) { + } + return -1; + } + + /** + * Finds the smallest position in document such that the position is >= position + * and < bound and Character.isWhitespace(document.getChar(pos)) evaluates to false + * and the position is in the default partition. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @param bound the first position in document to not consider any more, with bound > position + * @return the smallest position of one element in chars in [position, scanTo) that resides in a Java partition, or -1 if none can be found + */ + private static int firstNonWhitespaceForward(IDocument document, int position, String partitioning, int bound) { + Assert.isTrue(position >= 0); + Assert.isTrue(bound <= document.getLength()); + + try { + while (position < bound) { + char ch= document.getChar(position); + if (!Character.isWhitespace(ch) && isDefaultPartition(document, position, partitioning)) + return position; + position++; + } + } catch (BadLocationException e) { + } + return -1; + } + + /** + * Finds the highest position in document such that the position is <= position + * and > bound and document.getChar(position) == ch evaluates to true for at least one + * ch in chars and the position is in the default partition. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @param bound the first position in document to not consider any more, with scanTo > position + * @param chars an array of char to search for + * @return the highest position of one element in chars in (bound, position] that resides in a Java partition, or -1 if none can be found + */ + private static int scanBackward(IDocument document, int position, String partitioning, int bound, char[] chars) { + Assert.isTrue(bound >= -1); + Assert.isTrue(position < document.getLength() ); + + Arrays.sort(chars); + + try { + while (position > bound) { + + if (Arrays.binarySearch(chars, document.getChar(position)) >= 0 && isDefaultPartition(document, position, partitioning)) + return position; + + position--; + } + } catch (BadLocationException e) { + } + return -1; + } + +// /** +// * Finds the highest position in document such that the position is <= position +// * and > bound and document.getChar(position) == ch evaluates to true +// * and the position is in the default partition. +// * +// * @param document the document being modified +// * @param position the first character position in document to be considered +// * @param bound the first position in document to not consider any more, with scanTo > position +// * @param chars an array of char to search for +// * @return the highest position of one element in chars in [position, scanTo) that resides in a Java partition, or -1 if none can be found +// */ +// private static int scanBackward(IDocument document, int position, int bound, char ch) { +// return scanBackward(document, position, bound, new char[] {ch}); +// } +// + /** + * Finds the lowest position in document such that the position is >= position + * and < bound and document.getChar(position) == ch evaluates to true for at least one + * ch in chars and the position is in the default partition. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @param bound the first position in document to not consider any more, with scanTo > position + * @param chars an array of char to search for + * @return the lowest position of one element in chars in [position, bound) that resides in a Java partition, or -1 if none can be found + */ + private static int scanForward(IDocument document, int position, String partitioning, int bound, char[] chars) { + Assert.isTrue(position >= 0); + Assert.isTrue(bound <= document.getLength()); + + Arrays.sort(chars); + + try { + while (position < bound) { + + if (Arrays.binarySearch(chars, document.getChar(position)) >= 0 && isDefaultPartition(document, position, partitioning)) + return position; + + position++; + } + } catch (BadLocationException e) { + } + return -1; + } + + /** + * Finds the lowest position in document such that the position is >= position + * and < bound and document.getChar(position) == ch evaluates to true + * and the position is in the default partition. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @param bound the first position in document to not consider any more, with scanTo > position + * @param chars an array of char to search for + * @return the lowest position of one element in chars in [position, bound) that resides in a Java partition, or -1 if none can be found + */ + private static int scanForward(IDocument document, int position, String partitioning, int bound, char ch) { + return scanForward(document, position, partitioning, bound, new char[] {ch}); + } + + /** + * Checks whether the content of document in the range (offset, length) + * contains the new keyword. + * + * @param document the document being modified + * @param offset the first character position in document to be considered + * @param length the length of the character range to be considered + * @param partitioning the document partitioning + * @return true if the specified character range contains a new keyword, false otherwise. + */ + private static boolean isNewMatch(IDocument document, int offset, int length, String partitioning) { + Assert.isTrue(length >= 0); + Assert.isTrue(offset >= 0); + Assert.isTrue(offset + length < document.getLength() + 1); + + try { + String text= document.get(offset, length); + int pos= text.indexOf("new"); //$NON-NLS-1$ + + while (pos != -1 && !isDefaultPartition(document, pos + offset, partitioning)) + pos= text.indexOf("new", pos + 2); //$NON-NLS-1$ + + if (pos < 0) + return false; + + if (pos != 0 && Character.isJavaIdentifierPart(text.charAt(pos - 1))) + return false; + + if (pos + 3 < length && Character.isJavaIdentifierPart(text.charAt(pos + 3))) + return false; + + return true; + + } catch (BadLocationException e) { + } + return false; + } + + /** + * Checks whether the content of document at position looks like an + * anonymous class definition. position must be to the left of the opening + * parenthesis of the definition's parameter list. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @return true if the content of document looks like an anonymous class definition, false otherwise + */ + private static boolean looksLikeAnonymousClassDef(IDocument document, int position, String partitioning) { + int previousCommaOrParen= scanBackward(document, position - 1, partitioning, -1, new char[] {',', '('}); + if (previousCommaOrParen == -1 || position < previousCommaOrParen + 5) // 2 for borders, 3 for "new" + return false; + + if (isNewMatch(document, previousCommaOrParen + 1, position - previousCommaOrParen - 2, partitioning)) + return true; + + return false; + } + + /** + * Checks whether position resides in a default (Java) partition of document. + * + * @param document the document being modified + * @param position the position to be checked + * @param partitioning the document partitioning + * @return true if position is in the default partition of document, false otherwise + */ + private static boolean isDefaultPartition(IDocument document, int position, String partitioning) { + Assert.isTrue(position >= 0); + Assert.isTrue(position <= document.getLength()); + + try { + // don't use getPartition2 since we're interested in the scanned character's partition + ITypedRegion region= TextUtilities.getPartition(document, partitioning, position, false); + return region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE); + + } catch (BadLocationException e) { + } + + return false; + } + + /** + * Finds the position of the parenthesis matching the closing parenthesis at position. + * + * @param document the document being modified + * @param position the position in document of a closing parenthesis + * @param partitioning the document partitioning + * @return the position in document of the matching parenthesis, or -1 if none can be found + */ + private static int findOpeningParenMatch(IDocument document, int position, String partitioning) { + final char CLOSING_PAREN= ')'; + final char OPENING_PAREN= '('; + + Assert.isTrue(position < document.getLength()); + Assert.isTrue(position >= 0); + Assert.isTrue(isDefaultPartition(document, position, partitioning)); + + try { + + Assert.isTrue(document.getChar(position) == CLOSING_PAREN); + + int depth= 1; + while (true) { + position= scanBackward(document, position - 1, partitioning, -1, new char[] {CLOSING_PAREN, OPENING_PAREN}); + if (position == -1) + return -1; + + if (document.getChar(position) == CLOSING_PAREN) + depth++; + else + depth--; + + if (depth == 0) + return position; + } + + } catch (BadLocationException e) { + return -1; + } + } + + /** + * Checks whether, to the left of position and separated only by whitespace, + * document contains a keyword taking a parameter list and a block after it. + * These are: if, while, catch, for, synchronized, switch. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @return true if document contains any of the above keywords to the left of position, false otherwise + */ + private static boolean looksLikeIfWhileForCatch(IDocument document, int position, String partitioning) { + position= firstNonWhitespaceBackward(document, position, partitioning, -1); + if (position == -1) + return false; + + return looksLike(document, position, "if") //$NON-NLS-1$ + || looksLike(document, position, "while") //$NON-NLS-1$ + || looksLike(document, position, "catch") //$NON-NLS-1$ + || looksLike(document, position, "synchronized") //$NON-NLS-1$ + || looksLike(document, position, "switch") //$NON-NLS-1$ + || looksLike(document, position, "for"); //$NON-NLS-1$ + } + + /** + * Checks whether code>document contains the String like such + * that its last character is at position. If like starts with a + * identifier part (as determined by {@link Character#isJavaIdentifier(char)}), it is also made + * sure that like is preceded by some non-identifier character or stands at the + * document start. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param like the String to look for. + * @return true if document contains like such that it ends at position, false otherwise + */ + private static boolean looksLike(IDocument document, int position, String like) { + int length= like.length(); + if (position < length - 1) + return false; + + try { + if (!like.equals(document.get(position - length + 1, length))) + return false; + + if (position >= length && Character.isJavaIdentifierPart(like.charAt(0)) && Character.isJavaIdentifierPart(document.getChar(position - length))) + return false; + + } catch (BadLocationException e) { + return false; + } + + return true; + } + + /** + * Checks whether the content of document at position looks like a + * method declaration header (i.e. only the return type and method name). position + * must be just left of the opening parenthesis of the parameter list. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @return true if the content of document looks like a method definition, false otherwise + */ + private static boolean looksLikeMethodDecl(IDocument document, int position, String partitioning) { + + // method name + position= eatIdentToLeft(document, position, partitioning); + if (position < 1) + return false; + + position= eatBrackets(document, position - 1, partitioning); + if (position < 1) + return false; + + position= eatIdentToLeft(document, position - 1, partitioning); + + return position != -1; + } + + /** + * From position to the left, eats any whitespace and then a pair of brackets + * as used to declare an array return type like
String [ ]
. + * The return value is either the position of the opening bracket or position if no + * pair of brackets can be parsed. + * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @return the smallest character position of bracket pair or position + */ + private static int eatBrackets(IDocument document, int position, String partitioning) { + // accept array return type + int pos= firstNonWhitespaceBackward(document, position, partitioning, -1); + try { + if (pos > 1 && document.getChar(pos) == ']') { + pos= firstNonWhitespaceBackward(document, pos - 1, partitioning, -1); + if (pos > 0 && document.getChar(pos) == '[') + return pos; + } + } catch (BadLocationException e) { + // won't happen + } + return position; + } + + /** + * From position to the left, eats any whitespace and the first identifier, returning + * the position of the first identifier character (in normal read order). + *

When called on a document with content " some string " and positionition 13, the + * return value will be 6 (the first letter in string). + *

+ * + * @param document the document being modified + * @param position the first character position in document to be considered + * @param partitioning the document partitioning + * @return the smallest character position of an identifier or -1 if none can be found; always <= position + */ + private static int eatIdentToLeft(IDocument document, int position, String partitioning) { + if (position < 0) + return -1; + Assert.isTrue(position < document.getLength()); + + int p= firstNonWhitespaceBackward(document, position, partitioning, -1); + if (p == -1) + return -1; + + try { + while (p >= 0) { + + char ch= document.getChar(p); + if (Character.isJavaIdentifierPart(ch)) { + p--; + continue; + } + + // length must be > 0 + if (Character.isWhitespace(ch) && p != position) + return p + 1; + else + return -1; + + } + + // start of document reached + return 0; + + } catch (BadLocationException e) { + } + return -1; + } + + /** + * Returns a position in the first java partition after the last non-empty and non-comment partition. + * There is no non-whitespace from the returned position to the end of the partition it is contained in. + * + * @param document the document being modified + * @param line the line under investigation + * @param offset the caret offset into line + * @param partitioning the document partitioning + * @return the position of the next Java partition, or the end of line + */ + private static int nextPartitionOrLineEnd(IDocument document, ITextSelection line, int offset, String partitioning) { + // run relative to document + final int docOffset= offset + line.getOffset(); + final int eol= line.getOffset() + line.getLength(); + int nextPartitionPos= eol; // init with line end + int validPosition= docOffset; + + try { + ITypedRegion partition= TextUtilities.getPartition(document, partitioning, nextPartitionPos, true); + validPosition= getValidPositionForPartition(document, partition, eol); + while (validPosition == -1) { + nextPartitionPos= partition.getOffset() - 1; + if (nextPartitionPos < docOffset) { + validPosition= docOffset; + break; + } + partition= TextUtilities.getPartition(document, partitioning, nextPartitionPos, false); + validPosition= getValidPositionForPartition(document, partition, eol); + } + } catch (BadLocationException e) { + } + + validPosition= Math.max(validPosition, docOffset); + // make relative to line + validPosition -= line.getOffset(); + return validPosition; + } + + /** + * Returns a valid insert location (except for whitespace) in partition or -1 if + * there is no valid insert location. + * An valid insert location is right after any java string or character partition, or at the end + * of a java default partition, but never behind maxOffset. Comment partitions or + * empty java partitions do never yield valid insert positions. + * + * @param doc the document being modified + * @param partition the current partition + * @param maxOffset the maximum offset to consider + * @return a valid insert location in partition, or -1 if there is no valid insert location + */ + private static int getValidPositionForPartition(IDocument doc, ITypedRegion partition, int maxOffset) { + final int INVALID= -1; + + if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(partition.getType())) + return INVALID; + if (IPHPPartitions.PHP_MULTILINE_COMMENT.equals(partition.getType())) + return INVALID; + if (IPHPPartitions.PHP_SINGLELINE_COMMENT.equals(partition.getType())) + return INVALID; + + int endOffset= Math.min(maxOffset, partition.getOffset() + partition.getLength()); + +// if (IPHPPartitions.JAVA_CHARACTER.equals(partition.getType())) +// return endOffset; + if (IPHPPartitions.PHP_STRING_DQ.equals(partition.getType())) + return endOffset; + if (IPHPPartitions.PHP_STRING_SQ.equals(partition.getType())) + return endOffset; + if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) { + try { + if (doc.get(partition.getOffset(), endOffset - partition.getOffset()).trim().length() == 0) + return INVALID; + else + return endOffset; + } catch (BadLocationException e) { + return INVALID; + } + } + // default: we don't know anything about the partition - assume valid + return endOffset; + } + + /** + * Determines whether the current line contains a for statement. + * Algorithm: any "for" word in the line is a positive, "for" contained in a string literal will + * produce a false positive. + * + * @param line the line where the change is being made + * @param offset the position of the caret + * @return true if line contains for, false otherwise + */ + private static boolean isForStatement(String line, int offset) { + /* searching for (^|\s)for(\s|$) */ + int forPos= line.indexOf("for"); //$NON-NLS-1$ + if (forPos != -1) { + if ((forPos == 0 || !Character.isJavaIdentifierPart(line.charAt(forPos - 1))) && (line.length() == forPos + 3 || !Character.isJavaIdentifierPart(line.charAt(forPos + 3)))) + return true; + } + return false; + } + + /** + * Returns the position in text after which there comes only whitespace, up to + * offset. + * + * @param text the text being searched + * @param offset the maximum offset to search for + * @return the smallest value v such that text.substring(v, offset).trim() == 0 + */ + private static int startOfWhitespaceBeforeOffset(String text, int offset) { + int i= Math.min(offset, text.length()); + for (; i >= 1; i--) { + if (!Character.isWhitespace(text.charAt(i - 1))) + break; + } + return i; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java index 411b38b..b873cc6 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java @@ -63,7 +63,7 @@ public class DefaultJavaFoldingPreferenceBlock implements IJavaFoldingPreference private OverlayKey[] createKeys() { ArrayList overlayKeys= new ArrayList(); -// overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_JAVADOC)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_JAVADOC)); // overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_INNERTYPES)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_METHODS)); // overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_IMPORTS)); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategy.java index 56d3d75..ea00344 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategy.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategy.java @@ -53,12 +53,12 @@ public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy { token = tokenizer.nextToken(); if (token.equals("\n")) { //$NON-NLS-1$ buffer.append("\\n"); //$NON-NLS-1$ - buffer.append("\" + " + delimiter); //$NON-NLS-1$ + buffer.append("\" . " + delimiter); //$NON-NLS-1$ buffer.append(indentation); buffer.append("\""); //$NON-NLS-1$ continue; } else { - buffer.append("\" + " + delimiter); //$NON-NLS-1$ + buffer.append("\" . " + delimiter); //$NON-NLS-1$ buffer.append(indentation); buffer.append("\""); //$NON-NLS-1$ } @@ -67,7 +67,7 @@ public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy { } } else if (token.equals("\n")) { //$NON-NLS-1$ buffer.append("\\n"); //$NON-NLS-1$ - buffer.append("\" + " + delimiter); //$NON-NLS-1$ + buffer.append("\" . " + delimiter); //$NON-NLS-1$ buffer.append(indentation); buffer.append("\""); //$NON-NLS-1$ continue; @@ -170,7 +170,7 @@ public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy { IPreferenceStore preferenceStore= PHPeclipsePlugin.getDefault().getPreferenceStore(); if (isLineDelimiter(document, command.text)) - command.text= "\" +" + command.text + indentation + "\""; //$NON-NLS-1$//$NON-NLS-2$ + command.text= "\" ." + command.text + indentation + "\""; //$NON-NLS-1$//$NON-NLS-2$ else if (command.text.length() > 1 && preferenceStore.getBoolean(PreferenceConstants.EDITOR_ESCAPE_STRINGS)) command.text= getModifiedText(command.text, indentation, delimiter); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java new file mode 100644 index 0000000..098883a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java.hover; + + +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.information.IInformationProvider; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IPerspectiveDescriptor; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; + +import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover; + +import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder; + + +public class JavaInformationProvider implements IInformationProvider { + + class EditorWatcher implements IPartListener { + + /** + * @see IPartListener#partOpened(IWorkbenchPart) + */ + public void partOpened(IWorkbenchPart part) { + } + + /** + * @see IPartListener#partDeactivated(IWorkbenchPart) + */ + public void partDeactivated(IWorkbenchPart part) { + } + + /** + * @see IPartListener#partClosed(IWorkbenchPart) + */ + public void partClosed(IWorkbenchPart part) { + if (part == fEditor) { + fEditor.getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); + fPartListener= null; + } + } + + /** + * @see IPartListener#partActivated(IWorkbenchPart) + */ + public void partActivated(IWorkbenchPart part) { + update(); + } + + public void partBroughtToTop(IWorkbenchPart part) { + update(); + } + } + + protected IEditorPart fEditor; + protected IPartListener fPartListener; + + protected String fCurrentPerspective; + protected IJavaEditorTextHover fImplementation; + + + public JavaInformationProvider(IEditorPart editor) { + + fEditor= editor; + + if (fEditor != null) { + + fPartListener= new EditorWatcher(); + IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow(); + window.getPartService().addPartListener(fPartListener); + + update(); + } + } + + protected void update() { + + IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow(); + IWorkbenchPage page= window.getActivePage(); + if (page != null) { + + IPerspectiveDescriptor perspective= page.getPerspective(); + if (perspective != null) { + String perspectiveId= perspective.getId(); + + if (fCurrentPerspective == null || fCurrentPerspective != perspectiveId) { + fCurrentPerspective= perspectiveId; + + fImplementation= new JavaTypeHover(); + fImplementation.setEditor(fEditor); + } + } + } + } + + /* + * @see IInformationProvider#getSubject(ITextViewer, int) + */ + public IRegion getSubject(ITextViewer textViewer, int offset) { + + if (textViewer != null) + return JavaWordFinder.findWord(textViewer.getDocument(), offset); + + return null; + } + + /* + * @see IInformationProvider#getInformation(ITextViewer, IRegion) + */ + public String getInformation(ITextViewer textViewer, IRegion subject) { + if (fImplementation != null) { + String s= fImplementation.getHoverInfo(textViewer, subject); + if (s != null && s.trim().length() > 0) + return s; + } + + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java index 2936e54..d48678b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java @@ -10,9 +10,9 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.text.java.hover; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.Document; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java index 1d17285..24aa1f8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java @@ -1,16 +1,15 @@ /********************************************************************** -Copyright (c) 2000, 2002 IBM Corp. and others. -All rights reserved. This program and the accompanying materials -are made available under the terms of the Common Public License v1.0 -which accompanies this distribution, and is available at -http://www.eclipse.org/legal/cpl-v10.html - -Contributors: - IBM Corporation - Initial implementation -**********************************************************************/ + Copyright (c) 2000, 2002 IBM Corp. and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Common Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/cpl-v10.html + + Contributors: + IBM Corporation - Initial implementation + **********************************************************************/ package net.sourceforge.phpdt.internal.ui.text.phpdoc; - import java.util.ArrayList; import java.util.List; @@ -30,15 +29,11 @@ import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.rules.WhitespaceRule; import org.eclipse.jface.text.rules.WordRule; - - - /** * A rule based PHPDoc scanner. */ public final class PHPDocCodeScanner extends AbstractJavaScanner { - - + /** * A key word detector. */ @@ -58,8 +53,7 @@ public final class PHPDocCodeScanner extends AbstractJavaScanner { return Character.isLetter(c); } }; - - + /** * Detector for HTML comment delimiters. */ @@ -79,68 +73,77 @@ public final class PHPDocCodeScanner extends AbstractJavaScanner { return (c == '-' || c == '!' || c == '>'); } }; - + class TagRule extends SingleLineRule { - + /* * @see SingleLineRule */ public TagRule(IToken token) { super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$ } - + /* - * @see SingleLineRule + * @see SingleLineRule */ public TagRule(IToken token, char escapeCharacter) { super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$ } - + private IToken checkForWhitespace(ICharacterScanner scanner) { - + try { - - char c= getDocument().getChar(getTokenOffset() + 1); - if (!Character.isWhitespace(c)) + + char c = getDocument().getChar(getTokenOffset() + 1); + if (!Character.isWhitespace(c)) return fToken; - + } catch (BadLocationException x) { } - + return Token.UNDEFINED; } - + /* * @see PatternRule#evaluate(ICharacterScanner) */ public IToken evaluate(ICharacterScanner scanner) { - IToken result= super.evaluate(scanner); + IToken result = super.evaluate(scanner); if (result == fToken) return checkForWhitespace(scanner); return result; } }; - - - private static String[] fgKeywords= {"@author", "@deprecated", "@exception", "@param", "@return", "@see", "@serial", "@serialData", "@serialField", "@since", "@throws", "@version"}; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ - - private static String[] fgTokenProperties= { - IPreferenceConstants.PHPDOC_KEYWORD, - IPreferenceConstants.PHPDOC_TAG, - IPreferenceConstants.PHPDOC_LINK, - IPreferenceConstants.PHPDOC_DEFAULT - }; - - + + private static String[] fgKeywords = { + "@author", + "@copyright", + "@deprecated", + "@exception", + "@link", + "@package", + "@param", + "@return", + "@see", + "@serial", + "@serialData", + "@serialField", + "@since", + "@throws", + "@version" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + + private static String[] fgTokenProperties = { IPreferenceConstants.PHPDOC_KEYWORD, IPreferenceConstants.PHPDOC_TAG, + IPreferenceConstants.PHPDOC_LINK, IPreferenceConstants.PHPDOC_DEFAULT }; + public PHPDocCodeScanner(IColorManager manager, IPreferenceStore store) { super(manager, store); initialize(); } - + public IDocument getDocument() { return fDocument; } - + /* * @see AbstractJavaScanner#getTokenProperties() */ @@ -152,42 +155,37 @@ public final class PHPDocCodeScanner extends AbstractJavaScanner { * @see AbstractJavaScanner#createRules() */ protected List createRules() { - - List list= new ArrayList(); - + + List list = new ArrayList(); + // Add rule for tags. - Token token= getToken(IPreferenceConstants.PHPDOC_TAG); + Token token = getToken(IPreferenceConstants.PHPDOC_TAG); list.add(new TagRule(token)); - - + // Add rule for HTML comments - WordRule wordRule= new WordRule(new HTMLCommentDetector(), token); + WordRule wordRule = new WordRule(new HTMLCommentDetector(), token); wordRule.addWord("", token); //$NON-NLS-1$ list.add(wordRule); - - + // Add rule for links. - token= getToken(IPreferenceConstants.PHPDOC_LINK); + token = getToken(IPreferenceConstants.PHPDOC_LINK); list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$ - - + // Add generic whitespace rule. list.add(new WhitespaceRule(new PHPWhitespaceDetector())); - - + // Add word rule for keywords. - token= getToken(IPreferenceConstants.PHPDOC_DEFAULT); - wordRule= new WordRule(new JavaDocKeywordDetector(), token); - - token= getToken(IPreferenceConstants.PHPDOC_KEYWORD); - for (int i= 0; i < fgKeywords.length; i++) + token = getToken(IPreferenceConstants.PHPDOC_DEFAULT); + wordRule = new WordRule(new JavaDocKeywordDetector(), token); + + token = getToken(IPreferenceConstants.PHPDOC_KEYWORD); + for (int i = 0; i < fgKeywords.length; i++) wordRule.addWord(fgKeywords[i], token); list.add(wordRule); - + setDefaultReturnToken(getToken(IPreferenceConstants.PHPDOC_DEFAULT)); return list; } } - diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java index e7c66c1..9ff8886 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java @@ -17,6 +17,7 @@ import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; @@ -34,6 +35,7 @@ public class DeclarationEngine { /** Token determines last which declarations are allowed for proposal */ private int fLastSignificantToken; + private IProject fProject; private IFile fFile; // private String fFileName; @@ -41,8 +43,9 @@ public class DeclarationEngine { * Creates the template engine for a particular context type. * See TemplateContext for supported context types. */ - public DeclarationEngine(ContextType contextType, int lastSignificantToken, IFile file) { + public DeclarationEngine(IProject project, ContextType contextType, int lastSignificantToken, IFile file) { // Assert.isNotNull(contextType); + fProject = project; fContextType = contextType; fLastSignificantToken = lastSignificantToken; @@ -151,7 +154,7 @@ public class DeclarationEngine { if (maxProposals-- < 0) { return; } - fProposals.add(new DeclarationProposal(identifier, location, context, region, viewer)); + fProposals.add( new DeclarationProposal(fProject, identifier, location, context, region, viewer)); } } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java index 539a49b..76da3b3 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java @@ -14,6 +14,7 @@ import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation; +import org.eclipse.core.resources.IProject; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; @@ -28,6 +29,7 @@ import org.eclipse.swt.graphics.Image; * A PHP identifier proposal. */ public class DeclarationProposal extends AbstractProposal { //implements IPHPCompletionProposal { + private IProject fProject; private final TemplateContext fContext; private final PHPIdentifierLocation fLocation; @@ -48,6 +50,7 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom * @param image the icon of the proposal. */ public DeclarationProposal( + IProject project, String identifierName, PHPIdentifierLocation location, TemplateContext context, @@ -56,6 +59,7 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom super(viewer); // Image image_fun, // Image image_var) { + fProject = project; fIdentifierName = identifierName; fLocation = location; fContext = context; @@ -138,10 +142,18 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom */ public String getAdditionalProposalInfo() { StringBuffer hoverInfoBuffer = new StringBuffer(); - String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString(); +// String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString(); + String workspaceLocation; + if (fProject!=null) { + workspaceLocation = fProject.getLocation().toString()+'/'; + } else { + // should never happen? + workspaceLocation = PHPeclipsePlugin.getWorkspace() + .getRoot().getLocation().toString(); + } String filename = workspaceLocation + fLocation.getFilename(); PHPDocUtil.appendPHPDoc(hoverInfoBuffer, filename, fLocation); - return textToHTML(hoverInfoBuffer.toString()); + return hoverInfoBuffer.toString(); } /* @@ -155,7 +167,15 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom * @see ICompletionProposal#getDisplayString() */ public String getDisplayString() { - String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString(); +// String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString(); + String workspaceLocation; + if (fProject!=null) { + workspaceLocation = fProject.getLocation().toString()+'/'; + } else { + // should never happen? + workspaceLocation = PHPeclipsePlugin.getWorkspace() + .getRoot().getLocation().toString(); + } String filename = workspaceLocation + fLocation.getFilename(); return fIdentifierName + TemplateMessages.getString("TemplateProposal.delimiter") + PHPDocUtil.getUsage(filename, fLocation) + TemplateMessages.getString("TemplateProposal.delimiter") + filename; // $NON-NLS-1$ //$NON-NLS-1$ } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java index ab65d86..2ac2f8b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java @@ -1570,6 +1570,14 @@ public final static String EDITOR_TEXT_FONT= "net.sourceforge.phpdt.ui.editors.t * @since 3.0 */ public static final String EDITOR_SMART_SEMICOLON= "smart_semicolon"; //$NON-NLS-1$ + /** + * A named preference that controls the smart backspace behavior. + *

+ * Value is of type Boolean. + * + * @since 3.0 + */ + public static final String EDITOR_SMART_BACKSPACE= "smart_backspace"; //$NON-NLS-1$ /** * A named preference that controls the "smart opening brace" smart typing handler @@ -2421,11 +2429,13 @@ public final static String EDITOR_TEXT_FONT= "net.sourceforge.phpdt.ui.editors.t // folding store.setDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED, true); store.setDefault(PreferenceConstants.EDITOR_FOLDING_PROVIDER, "net.sourceforge.phpdt.ui.text.defaultFoldingProvider"); //$NON-NLS-1$ - store.setDefault(PreferenceConstants.EDITOR_FOLDING_JAVADOC, false); + store.setDefault(PreferenceConstants.EDITOR_FOLDING_JAVADOC, true); store.setDefault(PreferenceConstants.EDITOR_FOLDING_INNERTYPES, true); store.setDefault(PreferenceConstants.EDITOR_FOLDING_METHODS, false); store.setDefault(PreferenceConstants.EDITOR_FOLDING_IMPORTS, false); + store.setDefault(PreferenceConstants.EDITOR_SMART_BACKSPACE, true); + // do more complicated stuff // NewJavaProjectPreferencePage.initDefaults(store); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java index 0d592a8..33a5411 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java @@ -5,17 +5,23 @@ package net.sourceforge.phpdt.ui.text; * All Rights Reserved. */ +import net.sourceforge.phpdt.internal.ui.text.FastJavaPartitionScanner; import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.JavaColorManager; import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner; import net.sourceforge.phpeclipse.IPreferenceConstants; -import net.sourceforge.phpeclipse.phpeditor.php.HTMLCodeScanner; -import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.php.HTMLPartitionScanner; +import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner; import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner; +import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner; import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner; import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner; +import net.sourceforge.phpeclipse.xml.ui.XMLPlugin; +import net.sourceforge.phpeclipse.xml.ui.internal.text.SingleTokenScanner; +import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner; +import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools; -import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; @@ -24,9 +30,10 @@ import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.rules.DefaultPartitioner; import org.eclipse.jface.text.rules.IPartitionTokenScanner; import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.ui.part.FileEditorInput; + // //import org.phpeclipse.phpdt.internal.ui.text.FastJavaPartitionScanner; //import org.phpeclipse.phpdt.internal.ui.text.JavaColorManager; @@ -36,136 +43,155 @@ import org.eclipse.ui.part.FileEditorInput; //import org.phpeclipse.phpdt.internal.ui.text.phpdoc.JavaDocScanner; /** - * Tools required to configure a Java text viewer. - * The color manager and all scanner exist only one time, i.e. - * the same instances are returned to all clients. Thus, clients - * share those tools. + * Tools required to configure a Java text viewer. The color manager and all scanner exist only one time, i.e. the same instances + * are returned to all clients. Thus, clients share those tools. *

* This class may be instantiated; it is not intended to be subclassed. *

*/ -public class JavaTextTools { - - private static PHPPartitionScanner HTML_PARTITION_SCANNER = null; - private static PHPPartitionScanner PHP_PARTITION_SCANNER = null; - private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null; - - // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, PHPPartitionScanner.JAVA_MULTILINE_COMMENT }; - private final static String[] TYPES = - new String[] { - IPHPPartitions.PHP_PARTITIONING, - IPHPPartitions.PHP_PHPDOC_COMMENT, - IPHPPartitions.HTML, - IPHPPartitions.HTML_MULTILINE_COMMENT, - IPHPPartitions.JAVASCRIPT, - IPHPPartitions.CSS, - IPHPPartitions.SMARTY, - IPHPPartitions.SMARTY_MULTILINE_COMMENT }; - private static PHPPartitionScanner XML_PARTITION_SCANNER = null; - - /** - * This tools' preference listener. +public class JavaTextTools implements IPHPPartitions { +// private static final String[] TOKENS = { +// JSPScriptScanner.JSP_DEFAULT, +// JSPScriptScanner.JSP_BRACKET }; + private final static String[] LEGAL_CONTENT_TYPES = new String[] { + PHP_PHPDOC_COMMENT, + PHP_MULTILINE_COMMENT, + PHP_SINGLELINE_COMMENT, + PHP_STRING_DQ, + PHP_STRING_SQ }; + + private static XMLPartitionScanner HTML_PARTITION_SCANNER = null; + + private static FastJavaPartitionScanner PHP_PARTITION_SCANNER = null; + + private static HTMLPartitionScanner SMARTY_PARTITION_SCANNER = null; + + private static XMLPartitionScanner XML_PARTITION_SCANNER = null; + + // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, + // PHPPartitionScanner.JAVA_MULTILINE_COMMENT }; +// private final static String[] TYPES = new String[] { +// IPHPPartitions.PHP_PARTITIONING, +// IPHPPartitions.PHP_PHPDOC_COMMENT, +// // IPHPPartitions.HTML, +// // IPHPPartitions.HTML_MULTILINE_COMMENT, +// IPHPPartitions.JAVASCRIPT, +// IPHPPartitions.CSS, +// IPHPPartitions.SMARTY, +// IPHPPartitions.SMARTY_MULTILINE_COMMENT }; + + /** + * This tools' preference listener. */ private class PreferenceListener implements IPropertyChangeListener, Preferences.IPropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { adaptToPreferenceChange(event); } + public void propertyChange(Preferences.PropertyChangeEvent event) { - adaptToPreferenceChange( - new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue())); + adaptToPreferenceChange(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event + .getNewValue())); } }; - /** The color manager */ - private JavaColorManager fColorManager; + // /** The color manager */ + private JavaColorManager colorManager; + /** The PHP source code scanner */ private PHPCodeScanner fCodeScanner; + /** The PHP multiline comment scanner */ private SingleTokenPHPScanner fMultilineCommentScanner; + /** The Java singleline comment scanner */ private SingleTokenPHPScanner fSinglelineCommentScanner; + /** The Java string scanner */ private SingleTokenPHPScanner fStringScanner; + /** The PHPDoc scanner */ private PHPDocCodeScanner fPHPDocScanner; + /** The HTML scanner */ - private HTMLCodeScanner fHTMLScanner; + // private HTMLCodeScanner fHTMLScanner; /** The Smarty scanner */ private SmartyCodeScanner fSmartyScanner; + /** The SmartyDoc scanner */ private SmartyDocCodeScanner fSmartyDocScanner; - /** The Java partitions scanner */ - private PHPPartitionScanner fPartitionScanner; - + + /** The Java partitions scanner. */ + private FastJavaPartitionScanner fPartitionScanner; + /** The preference store */ private IPreferenceStore fPreferenceStore; + + /** The XML Language text tools */ + private XMLTextTools xmlTextTools; /** * The core preference store. + * * @since 2.1 */ private Preferences fCorePreferenceStore; + /** The preference change listener */ private PreferenceListener fPreferenceListener = new PreferenceListener(); + /** The JSP partitions scanner */ + private PHPPartitionScanner jspPartitionScanner = null; + + /** The JSP script subpartitions scanner */ +// private JSPScriptScanner jspScriptScanner; + + /** The PHP plain text scanner */ +// private RuleBasedScanner jspTextScanner; + + /** The PHP brackets scanner */ +// private RuleBasedScanner jspBracketScanner; + /** * Creates a new Java text tools collection. * - * @param store the preference store to initialize the text tools. The text tool - * instance installs a listener on the passed preference store to adapt itself to - * changes in the preference store. In general PreferenceConstants. - * getPreferenceStore() shoould be used to initialize the text tools. - * - * @see org.phpeclipse.phpdt.ui.PreferenceConstants#getPreferenceStore() - * @since 2.0 + * @param store + * the preference store to initialize the text tools. The text tool instance installs a listener on the passed preference + * store to adapt itself to changes in the preference store. In general PreferenceConstants. + * getPreferenceStore() + * should be used to initialize the text tools. + * @param coreStore + * optional preference store to initialize the text tools. The text tool instance installs a listener on the passed + * preference store to adapt itself to changes in the preference store. + * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore() + * @since 2.1 */ -// public JavaTextTools(IPreferenceStore store) { -// fPreferenceStore = store; -// fPreferenceStore.addPropertyChangeListener(fPreferenceListener); -// -// fColorManager = new JavaColorManager(); -// fCodeScanner = new PHPCodeScanner(fColorManager, store); -// fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT); -// fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT); -// fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING); -// fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store); -// fHTMLScanner = new HTMLCodeScanner(fColorManager, store); -// fSmartyScanner = new SmartyCodeScanner(fColorManager, store); -// fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store); -//// fPartitionScanner = new FastJavaPartitionScanner(); -// fPartitionScanner = new PHPPartitionScanner(); -// } - /** - * Creates a new Java text tools collection. - * @param store the preference store to initialize the text tools. The text tool - * instance installs a listener on the passed preference store to adapt itself to - * changes in the preference store. In general PreferenceConstants. - * getPreferenceStore() should be used to initialize the text tools. - * @param coreStore optional preference store to initialize the text tools. The text tool - * instance installs a listener on the passed preference store to adapt itself to - * changes in the preference store. - * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore() - * @since 2.1 - */ - public JavaTextTools(IPreferenceStore store, Preferences coreStore) { - this(store, coreStore, true); - } + public JavaTextTools(IPreferenceStore store, Preferences coreStore) { + this(store, coreStore, true); + } + /** * Creates a new Java text tools collection. * - * @param store the preference store to initialize the text tools. The text tool - * instance installs a listener on the passed preference store to adapt itself to - * changes in the preference store. In general PreferenceConstants. - * getPreferenceStore() shoould be used to initialize the text tools. - * @param coreStore optional preference store to initialize the text tools. The text tool - * instance installs a listener on the passed preference store to adapt itself to - * changes in the preference store. - * @param autoDisposeOnDisplayDispose if true the color manager - * automatically disposes all managed colors when the current display gets disposed - * and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored. + * @param store + * the preference store to initialize the text tools. The text tool instance installs a listener on the passed preference + * store to adapt itself to changes in the preference store. In general PreferenceConstants. + * getPreferenceStore() + * shoould be used to initialize the text tools. + * @param coreStore + * optional preference store to initialize the text tools. The text tool instance installs a listener on the passed + * preference store to adapt itself to changes in the preference store. + * @param autoDisposeOnDisplayDispose + * if true the color manager automatically disposes all managed colors when the current display gets + * disposed and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}are ignored. * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore() * @since 2.1 */ public JavaTextTools(IPreferenceStore store, Preferences coreStore, boolean autoDisposeOnDisplayDispose) { + // super(store, TOKENS, ); +// REVISIT: preference store + xmlTextTools = new XMLTextTools( + XMLPlugin.getDefault().getPreferenceStore()); + + colorManager = new JavaColorManager(autoDisposeOnDisplayDispose); fPreferenceStore = store; fPreferenceStore.addPropertyChangeListener(fPreferenceListener); @@ -173,21 +199,36 @@ public class JavaTextTools { if (fCorePreferenceStore != null) fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener); - fColorManager = new JavaColorManager(autoDisposeOnDisplayDispose); - - fCodeScanner = new PHPCodeScanner(fColorManager, store); - fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT); - fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT); - fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING); - fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store); - fHTMLScanner = new HTMLCodeScanner(fColorManager, store); - fSmartyScanner = new SmartyCodeScanner(fColorManager, store); - fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store); - // fPartitionScanner = new FastJavaPartitionScanner(); - fPartitionScanner = new PHPPartitionScanner(); + fCodeScanner = new PHPCodeScanner((JavaColorManager) colorManager, store); + fMultilineCommentScanner = new SingleTokenPHPScanner((JavaColorManager) colorManager, store, + IPreferenceConstants.PHP_MULTILINE_COMMENT); + fSinglelineCommentScanner = new SingleTokenPHPScanner((JavaColorManager) colorManager, store, + IPreferenceConstants.PHP_SINGLELINE_COMMENT); + fStringScanner = new SingleTokenPHPScanner((JavaColorManager) colorManager, store, IPreferenceConstants.PHP_STRING); + fPHPDocScanner = new PHPDocCodeScanner((JavaColorManager) colorManager, store); + // fHTMLScanner = new HTMLCodeScanner((JavaColorManager)fColorManager, store); + fSmartyScanner = new SmartyCodeScanner((JavaColorManager) colorManager, store); + fSmartyDocScanner = new SmartyDocCodeScanner((JavaColorManager) colorManager, store); + + fPartitionScanner= new FastJavaPartitionScanner(); + +// jspScriptScanner = new JSPScriptScanner(); + // fPartitionScanner = new FastJavaPartitionScanner(); + // fPartitionScanner = new PHPPartitionScanner(); + +// jspBracketScanner = new RuleBasedScanner(); +// jspBracketScanner.setDefaultReturnToken(new Token(JSPScriptScanner.JSP_BRACKET)); +// jspTextScanner = new RuleBasedScanner(); +// jspTextScanner.setDefaultReturnToken(new Token(JSPScriptScanner.JSP_DEFAULT)); } /** + * + */ + public XMLTextTools getXMLTextTools() { + return xmlTextTools; + } + /** * Disposes all the individual tools of this tools collection. */ public void dispose() { @@ -197,11 +238,11 @@ public class JavaTextTools { fSinglelineCommentScanner = null; fStringScanner = null; fPHPDocScanner = null; - fPartitionScanner = null; + // fPartitionScanner = null; - if (fColorManager != null) { - fColorManager.dispose(); - fColorManager = null; + if (colorManager != null) { + colorManager.dispose(); + colorManager = null; } if (fPreferenceStore != null) { @@ -218,18 +259,17 @@ public class JavaTextTools { } /** - * Returns the color manager which is used to manage - * any Java-specific colors needed for such things like syntax highlighting. - * + * Returns the color manager which is used to manage any Java-specific colors needed for such things like syntax highlighting. + * * @return the color manager to be used for Java text viewers */ - public IColorManager getColorManager() { - return fColorManager; + public JavaColorManager getColorManager() { + return (JavaColorManager) colorManager; } /** * Returns a scanner which is configured to scan Java source code. - * + * * @return a Java source code scanner */ public RuleBasedScanner getCodeScanner() { @@ -238,7 +278,7 @@ public class JavaTextTools { /** * Returns a scanner which is configured to scan Java multiline comments. - * + * * @return a Java multiline comment scanner * * @since 2.0 @@ -249,18 +289,17 @@ public class JavaTextTools { /** * Returns a scanner which is configured to scan HTML code. - * + * * @return a HTML scanner * * @since 2.0 */ - public RuleBasedScanner getHTMLScanner() { - return fHTMLScanner; - } - + // public RuleBasedScanner getHTMLScanner() { + // return fHTMLScanner; + // } /** * Returns a scanner which is configured to scan Smarty code. - * + * * @return a Smarty scanner * * @since 2.0 @@ -270,18 +309,19 @@ public class JavaTextTools { } /** - * Returns a scanner which is configured to scan Smarty code. - * - * @return a Smarty scanner - * - * @since 2.0 - */ + * Returns a scanner which is configured to scan Smarty code. + * + * @return a Smarty scanner + * + * @since 2.0 + */ public RuleBasedScanner getSmartyDocScanner() { return fSmartyDocScanner; } + /** * Returns a scanner which is configured to scan Java singleline comments. - * + * * @return a Java singleline comment scanner * * @since 2.0 @@ -292,7 +332,7 @@ public class JavaTextTools { /** * Returns a scanner which is configured to scan Java strings. - * + * * @return a Java string scanner * * @since 2.0 @@ -302,10 +342,9 @@ public class JavaTextTools { } /** - * Returns a scanner which is configured to scan JavaDoc compliant comments. - * Notes that the start sequence "/**" and the corresponding end sequence - * are part of the JavaDoc comment. - * + * Returns a scanner which is configured to scan JavaDoc compliant comments. Notes that the start sequence "/**" and the + * corresponding end sequence are part of the JavaDoc comment. + * * @return a JavaDoc scanner */ public RuleBasedScanner getJavaDocScanner() { @@ -313,21 +352,18 @@ public class JavaTextTools { } /** - * Returns a scanner which is configured to scan - * Java-specific partitions, which are multi-line comments, - * JavaDoc comments, and regular Java source code. - * + * Returns a scanner which is configured to scan Java-specific partitions, which are multi-line comments, JavaDoc comments, and + * regular Java source code. + * * @return a Java partition scanner */ - public IPartitionTokenScanner getPartitionScanner() { - return fPartitionScanner; - } - + // public IPartitionTokenScanner getPartitionScanner() { + // return fPartitionScanner; + // } /** - * Factory method for creating a PHP-specific document partitioner - * using this object's partitions scanner. This method is a + * Factory method for creating a PHP-specific document partitioner using this object's partitions scanner. This method is a * convenience method. - * + * * @return a newly created Java document partitioner */ public IDocumentPartitioner createDocumentPartitioner() { @@ -335,10 +371,9 @@ public class JavaTextTools { } /** - * Factory method for creating a PHP-specific document partitioner - * using this object's partitions scanner. This method is a + * Factory method for creating a PHP-specific document partitioner using this object's partitions scanner. This method is a * convenience method. - * + * * @return a newly created Java document partitioner */ public IDocumentPartitioner createDocumentPartitioner(String extension) { @@ -356,114 +391,110 @@ public class JavaTextTools { if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) { // html partitioner = createHTMLPartitioner(); + partitioner = createJSPPartitioner(); } else if (extension.equalsIgnoreCase(".xml")) { // xml partitioner = createXMLPartitioner(); - } else if (extension.equalsIgnoreCase(".js")) { - // javascript - partitioner = createJavaScriptPartitioner(); - } else if (extension.equalsIgnoreCase(".css")) { - // cascading style sheets - partitioner = createCSSPartitioner(); +// } else if (extension.equalsIgnoreCase(".js")) { +// // javascript +// partitioner = createJavaScriptPartitioner(); +// } else if (extension.equalsIgnoreCase(".css")) { +// // cascading style sheets +// partitioner = createCSSPartitioner(); } else if (extension.equalsIgnoreCase(".tpl")) { // smarty ? partitioner = createSmartyPartitioner(); - } else if (extension.equalsIgnoreCase(".inc")) { - // php include files ? - partitioner = createIncludePartitioner(); +// } else if (extension.equalsIgnoreCase(".inc")) { +// // php include files ? +// partitioner = createIncludePartitioner(); } - + if (partitioner == null) { - partitioner = createPHPPartitioner(); + partitioner = createJSPPartitioner(); } return partitioner; } - /** - * Sets up the Java document partitioner for the given document for the default partitioning. - * - * @param document the document to be set up - * @since 3.0 - */ - public void setupJavaDocumentPartitioner(IDocument document) { - setupJavaDocumentPartitioner(document, IDocumentExtension3.DEFAULT_PARTITIONING,null); - } - /** - * Sets up the Java document partitioner for the given document for the given partitioning. - * @param document the document to be set up - * @param partitioning the document partitioning - * @param element TODO - * - * @since 3.0 - */ - public void setupJavaDocumentPartitioner(IDocument document, String partitioning, Object element) { - IDocumentPartitioner partitioner = createDocumentPartitioner(".php"); - -// if (document instanceof IDocumentExtension3) { -// IDocumentExtension3 extension3= (IDocumentExtension3) document; -// extension3.setDocumentPartitioner(partitioning, partitioner); -// } else { - document.setDocumentPartitioner(partitioner); -// } - partitioner.connect(document); - } - public void setupHTMLDocumentPartitioner(IDocument document, String partitioning, Object element) { - IDocumentPartitioner partitioner = createDocumentPartitioner(".html"); - -// if (document instanceof IDocumentExtension3) { -// IDocumentExtension3 extension3= (IDocumentExtension3) document; -// extension3.setDocumentPartitioner(partitioning, partitioner); -// } else { - document.setDocumentPartitioner(partitioner); -// } - partitioner.connect(document); - } - public void setupSmartyDocumentPartitioner(IDocument document, String partitioning, Object element) { - IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl"); - -// if (document instanceof IDocumentExtension3) { -// IDocumentExtension3 extension3= (IDocumentExtension3) document; -// extension3.setDocumentPartitioner(partitioning, partitioner); -// } else { - document.setDocumentPartitioner(partitioner); -// } - partitioner.connect(document); - } + + + /** + * Sets up the Java document partitioner for the given document for the given partitioning. + * + * @param document + * the document to be set up + * @param partitioning + * the document partitioning + * @param element + * TODO + * + * @since 3.0 + */ +// public void setupJavaDocumentPartitioner(IDocument document, String partitioning, Object element) { +// IDocumentPartitioner partitioner = createDocumentPartitioner(".php"); +// +// // if (document instanceof IDocumentExtension3) { +// // IDocumentExtension3 extension3= (IDocumentExtension3) document; +// // extension3.setDocumentPartitioner(partitioning, partitioner); +// // } else { +// document.setDocumentPartitioner(partitioner); +// // } +// partitioner.connect(document); +// } + + public void setupHTMLDocumentPartitioner(IDocument document, String partitioning, Object element) { + IDocumentPartitioner partitioner = createDocumentPartitioner(".html"); + + // if (document instanceof IDocumentExtension3) { + // IDocumentExtension3 extension3= (IDocumentExtension3) document; + // extension3.setDocumentPartitioner(partitioning, partitioner); + // } else { + document.setDocumentPartitioner(partitioner); + // } + partitioner.connect(document); + } + + public void setupSmartyDocumentPartitioner(IDocument document, String partitioning, Object element) { + IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl"); + + // if (document instanceof IDocumentExtension3) { + // IDocumentExtension3 extension3= (IDocumentExtension3) document; + // extension3.setDocumentPartitioner(partitioning, partitioner); + // } else { + document.setDocumentPartitioner(partitioner); + // } + partitioner.connect(document); + } + /** - * Returns the names of the document position categories used by the document - * partitioners created by this object to manage their partition information. - * If the partitioners don't use document position categories, the returned - * result is null. - * - * @return the partition managing position categories or null - * if there is none + * Returns the names of the document position categories used by the document partitioners created by this object to manage their + * partition information. If the partitioners don't use document position categories, the returned result is null. + * + * @return the partition managing position categories or null if there is none */ public String[] getPartitionManagingPositionCategories() { return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY }; } /** - * Determines whether the preference change encoded by the given event - * changes the behavior of one its contained components. + * Determines whether the preference change encoded by the given event changes the behavior of one its contained components. * - * @param event the event to be investigated + * @param event + * the event to be investigated * @return true if event causes a behavioral change * * @since 2.0 */ public boolean affectsBehavior(PropertyChangeEvent event) { - return fCodeScanner.affectsBehavior(event) - || fMultilineCommentScanner.affectsBehavior(event) - || fSinglelineCommentScanner.affectsBehavior(event) - || fStringScanner.affectsBehavior(event) - || fPHPDocScanner.affectsBehavior(event); + return fCodeScanner.affectsBehavior(event) || fMultilineCommentScanner.affectsBehavior(event) + || fSinglelineCommentScanner.affectsBehavior(event) || fStringScanner.affectsBehavior(event) + || fPHPDocScanner.affectsBehavior(event); } /** - * Adapts the behavior of the contained components to the change - * encoded in the given event. + * Adapts the behavior of the contained components to the change encoded in the given event. * - * @param event the event to which to adapt + * @param event + * the event to which to adapt * @since 2.0 */ protected void adaptToPreferenceChange(PropertyChangeEvent event) { @@ -477,80 +508,179 @@ public class JavaTextTools { fStringScanner.adaptToPreferenceChange(event); if (fPHPDocScanner.affectsBehavior(event)) fPHPDocScanner.adaptToPreferenceChange(event); - if (fHTMLScanner.affectsBehavior(event)) - fHTMLScanner.adaptToPreferenceChange(event); + // if (fHTMLScanner.affectsBehavior(event)) + // fHTMLScanner.adaptToPreferenceChange(event); if (fSmartyScanner.affectsBehavior(event)) fSmartyScanner.adaptToPreferenceChange(event); if (fSmartyDocScanner.affectsBehavior(event)) fSmartyDocScanner.adaptToPreferenceChange(event); + XMLPlugin.getDefault().getXMLTextTools().affectsBehavior(event); } /** - * Return a partitioner for .html files. - */ - private static IDocumentPartitioner createHTMLPartitioner() { - return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + * Return a partitioner for .html files. + */ + public IDocumentPartitioner createHTMLPartitioner() { +// return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); + return xmlTextTools.createXMLPartitioner(); } - private static IDocumentPartitioner createIncludePartitioner() { - return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); - } +// private static IDocumentPartitioner createIncludePartitioner() { +// // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); +// return new DefaultPartitioner(getPHPPartitionScanner(), FastJavaPartitionScanner.PHP_PARTITION_TYPES); +// +// } - private static IDocumentPartitioner createJavaScriptPartitioner() { - return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); - } +// private static IDocumentPartitioner createJavaScriptPartitioner() { +// return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); +// } /** - * Return a partitioner for .php files. - */ - private static IDocumentPartitioner createPHPPartitioner() { - return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + * Return a partitioner for .php files. + */ + public IDocumentPartitioner createPHPPartitioner() { + // return new DefaultPartitioner(getPHPPartitionScanner(), TYPES); + return new DefaultPartitioner(getPHPPartitionScanner(), LEGAL_CONTENT_TYPES); + } + + private IDocumentPartitioner createJSPPartitioner() { + return new PHPDocumentPartitioner( + getJSPPartitionScanner(), getPHPPartitionScanner()); +// return new JSPDocumentPartitioner(getJSPPartitionScanner(), jspScriptScanner); } + + /** + * + */ +// public IPartitionTokenScanner getJSPScriptScanner() { +// return jspScriptScanner; +// } - private static IDocumentPartitioner createSmartyPartitioner() { - return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES); + private IDocumentPartitioner createSmartyPartitioner() { + return new DefaultPartitioner(getSmartyPartitionScanner(), XMLTextTools.TYPES); } - private static IDocumentPartitioner createXMLPartitioner() { - return new DefaultPartitioner(getXMLPartitionScanner(), TYPES); + private IDocumentPartitioner createXMLPartitioner() { +// return new DefaultPartitioner(getXMLPartitionScanner(), XMLTextTools.TYPES); + return xmlTextTools.createXMLPartitioner(); } - private static IDocumentPartitioner createCSSPartitioner() { - return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES); - } +// private IDocumentPartitioner createCSSPartitioner() { +// return new DefaultPartitioner(getHTMLPartitionScanner(), XMLTextTools.TYPES); +// } + /** - * Return a scanner for creating html partitions. - */ - private static PHPPartitionScanner getHTMLPartitionScanner() { - if (HTML_PARTITION_SCANNER == null) - HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.HTML_FILE); - return HTML_PARTITION_SCANNER; - } + * Return a scanner for creating html partitions. + */ +// private static XMLPartitionScanner getHTMLPartitionScanner() { +// // if (HTML_PARTITION_SCANNER == null) +// // HTML_PARTITION_SCANNER = new HTMLPartitionScanner(IPHPPartitions.HTML_FILE); +// // return HTML_PARTITION_SCANNER;^ +// if (HTML_PARTITION_SCANNER == null) +// HTML_PARTITION_SCANNER = new XMLPartitionScanner(false); +// return HTML_PARTITION_SCANNER; +// } + /** - * Return a scanner for creating php partitions. - */ - private static PHPPartitionScanner getPHPPartitionScanner() { - if (PHP_PARTITION_SCANNER == null) - PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.PHP_FILE); - return PHP_PARTITION_SCANNER; + * Return a scanner for creating php partitions. + */ + private FastJavaPartitionScanner getPHPPartitionScanner() { +// if (PHP_PARTITION_SCANNER == null) +// PHP_PARTITION_SCANNER = new FastJavaPartitionScanner(); //new PHPPartitionScanner(IPHPPartitions.PHP_FILE); +// return PHP_PARTITION_SCANNER; + return fPartitionScanner; } /** - * Return a scanner for creating smarty partitions. - */ - private static PHPPartitionScanner getSmartyPartitionScanner() { + * Returns a scanner which is configured to scan plain text in JSP. + * + * @return a JSP text scanner + */ +// public RuleBasedScanner getJSPTextScanner() { +// return jspTextScanner; +// } + + /** + * Returns a scanner which is configured to scan plain text in JSP. + * + * @return a JSP text scanner + */ +// public RuleBasedScanner getJSPBracketScanner() { +// return jspBracketScanner; +// } + + /** + * Return a scanner for creating smarty partitions. + */ + private static HTMLPartitionScanner getSmartyPartitionScanner() { if (SMARTY_PARTITION_SCANNER == null) - SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.SMARTY_FILE); + SMARTY_PARTITION_SCANNER = new HTMLPartitionScanner(IPHPPartitions.SMARTY_FILE); return SMARTY_PARTITION_SCANNER; } /** - * Return a scanner for creating xml partitions. - */ - private static PHPPartitionScanner getXMLPartitionScanner() { + * Return a scanner for creating xml partitions. + */ + private static XMLPartitionScanner getXMLPartitionScanner() { + // if (XML_PARTITION_SCANNER == null) + // XML_PARTITION_SCANNER = new HTMLPartitionScanner(IPHPPartitions.XML_FILE); + // return XML_PARTITION_SCANNER; if (XML_PARTITION_SCANNER == null) - XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.XML_FILE); + XML_PARTITION_SCANNER = new XMLPartitionScanner(false); return XML_PARTITION_SCANNER; } + + private PHPPartitionScanner getJSPPartitionScanner() { + if (jspPartitionScanner == null) + jspPartitionScanner = new PHPPartitionScanner(); + return jspPartitionScanner; + } + + /** + * Sets up the Java document partitioner for the given document for the default partitioning. + * + * @param document the document to be set up + * @since 3.0 + */ + public void setupJavaDocumentPartitioner(IDocument document) { + setupJavaDocumentPartitioner(document, IDocumentExtension3.DEFAULT_PARTITIONING); + } + + /** + * Sets up the Java document partitioner for the given document for the given partitioning. + * + * @param document the document to be set up + * @param partitioning the document partitioning + * @since 3.0 + */ + public void setupJavaDocumentPartitioner(IDocument document, String partitioning) { + IDocumentPartitioner partitioner= createDocumentPartitioner(); + if (document instanceof IDocumentExtension3) { + IDocumentExtension3 extension3= (IDocumentExtension3) document; + extension3.setDocumentPartitioner(partitioning, partitioner); + } else { + document.setDocumentPartitioner(partitioner); + } + partitioner.connect(document); + } + + /** + * Returns this text tool's preference store. + * + * @return the preference store + * @since 3.0 + */ + protected IPreferenceStore getPreferenceStore() { + return fPreferenceStore; + } + /** + * Returns this text tool's core preference store. + * + * @return the core preference store + * @since 3.0 + */ + protected Preferences getCorePreferenceStore() { + return fCorePreferenceStore; + } } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java new file mode 100644 index 0000000..0dcaeed --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java @@ -0,0 +1,930 @@ +/********************************************************************** + Copyright (c) 2000, 2002 IBM Corp. and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Common Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/cpl-v10.html + + Contributors: + IBM Corporation - Initial implementation + Klaus Hartlage - www.eclipseproject.de + **********************************************************************/ +package net.sourceforge.phpdt.ui.text; + +import java.util.Vector; + +import net.sourceforge.phpdt.core.JavaCore; +import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; +import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; +import net.sourceforge.phpdt.internal.ui.text.JavaAnnotationHover; +import net.sourceforge.phpdt.internal.ui.text.JavaCompositeReconcilingStrategy; +import net.sourceforge.phpdt.internal.ui.text.JavaElementProvider; +import net.sourceforge.phpdt.internal.ui.text.JavaOutlineInformationControl; +import net.sourceforge.phpdt.internal.ui.text.JavaPresentationReconciler; +import net.sourceforge.phpdt.internal.ui.text.JavaReconciler; +import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter; +import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy; +import net.sourceforge.phpdt.internal.ui.text.java.JavaStringAutoIndentStrategy; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaInformationProvider; +import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; +import net.sourceforge.phpeclipse.phpeditor.html.HTMLFormattingStrategy; +import net.sourceforge.phpeclipse.phpeditor.php.HTMLCompletionProcessor; +import net.sourceforge.phpeclipse.phpeditor.php.PHPAutoIndentStrategy; +import net.sourceforge.phpeclipse.phpeditor.php.PHPCompletionProcessor; +import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner; +import net.sourceforge.phpeclipse.phpeditor.php.PHPDoubleClickSelector; +import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner; +import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider; +import net.sourceforge.phpeclipse.xml.ui.XMLPlugin; +import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration; +import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner; +import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.DefaultAutoIndentStrategy; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IAutoIndentStrategy; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.ITextDoubleClickStrategy; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewerExtension2; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.formatter.ContentFormatter; +import org.eclipse.jface.text.formatter.IContentFormatter; +import org.eclipse.jface.text.formatter.IFormattingStrategy; +import org.eclipse.jface.text.information.IInformationPresenter; +import org.eclipse.jface.text.information.IInformationProvider; +import org.eclipse.jface.text.information.InformationPresenter; +import org.eclipse.jface.text.presentation.IPresentationDamager; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.IPresentationRepairer; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.reconciler.IReconciler; +import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.DefaultPartitioner; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.texteditor.ChainedPreferenceStore; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Configuration for an SourceViewer which shows PHP code. + */ +public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { + /** + * Preference key used to look up display tab width. + * + * @since 2.0 + */ + public final static String PREFERENCE_TAB_WIDTH = PreferenceConstants.EDITOR_TAB_WIDTH; + + /** + * Preference key for inserting spaces rather than tabs. + * + * @since 2.0 + */ + public final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS; + + // public static final String HTML_DEFAULT = + // IPHPPartitionScannerConstants.HTML; + //IDocument.DEFAULT_CONTENT_TYPE; + private JavaTextTools fJavaTextTools; + + private ITextEditor fTextEditor; + /** + * The document partitioning. + * @since 3.0 + */ + private String fDocumentPartitioning; + + private ContentFormatter fFormatter; + + private HTMLFormattingStrategy fFormattingStrategy; + + /** + * Single token scanner. + */ + static class SingleTokenScanner extends BufferedRuleBasedScanner { + public SingleTokenScanner(TextAttribute attribute) { + setDefaultReturnToken(new Token(attribute)); + } + }; + + /** + * The document partitioning. + * + * @since 3.0 + */ +// private String fDocumentPartitioning; + +// /** +// * The Java source code scanner +// * +// * @since 3.0 +// */ +// private AbstractJavaScanner fCodeScanner; +// +// /** +// * The Java multi-line comment scanner +// * +// * @since 3.0 +// */ +// private AbstractJavaScanner fMultilineCommentScanner; +// +// /** +// * The Java single-line comment scanner +// * +// * @since 3.0 +// */ +// private AbstractJavaScanner fSinglelineCommentScanner; +// +// /** +// * The Java string scanner +// * +// * @since 3.0 +// */ +// private AbstractJavaScanner fStringScanner; +// +// /** +// * The Javadoc scanner +// * +// * @since 3.0 +// */ +// private AbstractJavaScanner fJavaDocScanner; + + /** + * The preference store, can be read-only + * + * @since 3.0 + */ + private IPreferenceStore fPreferenceStore; + + /** + * The color manager + * + * @since 3.0 + */ + private IColorManager fColorManager; + + private XMLTextTools fXMLTextTools; + private XMLConfiguration xmlConfiguration; + /** + * Creates a new Java source viewer configuration for viewers in the given editor using the given preference store, the color + * manager and the specified document partitioning. + *

+ * Creates a Java source viewer configuration in the new setup without text tools. Clients are allowed to call + * {@link JavaSourceViewerConfiguration#handlePropertyChangeEvent(PropertyChangeEvent)}and disallowed to call + * {@link JavaSourceViewerConfiguration#getPreferenceStore()}on the resulting Java source viewer configuration. + *

+ * + * @param colorManager + * the color manager + * @param preferenceStore + * the preference store, can be read-only + * @param editor + * the editor in which the configured viewer(s) will reside + * @param partitioning + * the document partitioning for this configuration + * @since 3.0 + */ + public PHPSourceViewerConfiguration(IColorManager colorManager, IPreferenceStore preferenceStore, ITextEditor editor, + String partitioning) { + fColorManager = colorManager; + fPreferenceStore = preferenceStore; + fTextEditor = editor; + fDocumentPartitioning = partitioning; + fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); + fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools(); + xmlConfiguration = new XMLConfiguration(fXMLTextTools); + + // initializeScanners(); + } + + /** + * Default constructor. + */ + public PHPSourceViewerConfiguration(JavaTextTools tools, PHPEditor editor, String partitioning) { + fJavaTextTools= tools; + fColorManager= tools.getColorManager(); + fPreferenceStore= createPreferenceStore(); + fDocumentPartitioning = partitioning; +// fCodeScanner= (AbstractJavaScanner) fJavaTextTools.getCodeScanner(); +// fMultilineCommentScanner= (AbstractJavaScanner) fJavaTextTools.getMultilineCommentScanner(); +// fSinglelineCommentScanner= (AbstractJavaScanner) fJavaTextTools.getSinglelineCommentScanner(); +// fStringScanner= (AbstractJavaScanner) fJavaTextTools.getStringScanner(); +// fJavaDocScanner= (AbstractJavaScanner) fJavaTextTools.getJavaDocScanner(); + fTextEditor= editor; + fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools(); + xmlConfiguration = new XMLConfiguration(fXMLTextTools); + } + + /* + * @see SourceViewerConfiguration#getContentFormatter(ISourceViewer) + */ + public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) { + // if (fFormatter == null) { + // fFormatter = new ContentFormatter(); + // fFormattingStrategy = new HTMLFormattingStrategy(this, + // sourceViewer); + // fFormatter.setFormattingStrategy(fFormattingStrategy, HTML_DEFAULT); + // fFormatter.enablePartitionAwareFormatting(false); + // fFormatter.setPartitionManagingPositionCategories(getConfiguredContentTypes(null)); + // } + // return fFormatter; + if (fFormatter == null) { + //ContentFormatter + fFormatter = new ContentFormatter(); + IFormattingStrategy strategy = new JavaFormattingStrategy(sourceViewer); + fFormatter.setFormattingStrategy(strategy, IDocument.DEFAULT_CONTENT_TYPE); + fFormatter.enablePartitionAwareFormatting(false); + fFormatter.setPartitionManagingPositionCategories(getPartitionManagingPositionCategories()); + } + return fFormatter; + } + + /** + * Returns the names of the document position categories used by the document partitioners created by this object to manage their + * partition information. If the partitioners don't use document position categories, the returned result is null. + * + * @return the partition managing position categories or null if there is none + */ + public String[] getPartitionManagingPositionCategories() { + return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY }; + } + + // /** + // * Returns the names of the document position categories used by the + // document + // * partitioners created by this object to manage their partition + // information. + // * If the partitioners don't use document position categories, the + // returned + // * result is null. + // * + // * @return the partition managing position categories or + // null + // * if there is none + // */ + // private String[] getPartitionManagingPositionCategories() { + // return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY }; + // } + public ITextEditor getEditor() { + return fTextEditor; + } + + /** + * Returns the preference store used by this configuration to initialize the individual bits and pieces. + * + * @return the preference store used to initialize this configuration + * + * @since 2.0 + */ + protected IPreferenceStore getPreferenceStore() { + return PHPeclipsePlugin.getDefault().getPreferenceStore(); + } + + // /* (non-Javadoc) + // * Method declared on SourceViewerConfiguration + // */ + // public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + // return new PHPAnnotationHover(); + // } + /* + * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer) + */ + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + return new JavaAnnotationHover(JavaAnnotationHover.VERTICAL_RULER_HOVER); + } + + /* + * @see SourceViewerConfiguration#getOverviewRulerAnnotationHover(ISourceViewer) + * @since 3.0 + */ + public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) { + return new JavaAnnotationHover(JavaAnnotationHover.OVERVIEW_RULER_HOVER); + } + + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer, String contentType) { + if (IPHPPartitions.PHP_STRING_DQ.equals(contentType)) + return new JavaStringAutoIndentStrategy(getConfiguredDocumentPartitioning(sourceViewer)); + + return (IPHPPartitions.PHP_PARTITIONING.equals(contentType) ? new PHPAutoIndentStrategy() : new DefaultAutoIndentStrategy()); + } + + /** + * Returns the PHP source code scanner for this configuration. + * + * @return the PHP source code scanner + */ + protected RuleBasedScanner getCodeScanner() { + return fJavaTextTools.getCodeScanner(); + } + + /** + * Returns the HTML source code scanner for this configuration. + * + * @return the HTML source code scanner + */ +// protected RuleBasedScanner getHTMLScanner() { +// return fJavaTextTools.getHTMLScanner(); +// } + + /** + * Returns the Smarty source code scanner for this configuration. + * + * @return the Smarty source code scanner + */ + protected RuleBasedScanner getSmartyScanner() { + return fJavaTextTools.getSmartyScanner(); + } + + /* + * @see SourceViewerConfiguration#getReconciler(ISourceViewer) + */ + /* + * @see SourceViewerConfiguration#getReconciler(ISourceViewer) + */ + public IReconciler getReconciler(ISourceViewer sourceViewer) { + + final ITextEditor editor = getEditor(); + if (editor != null && editor.isEditable()) { + + JavaCompositeReconcilingStrategy strategy = new JavaCompositeReconcilingStrategy(editor, + getConfiguredDocumentPartitioning(sourceViewer)); + JavaReconciler reconciler = new JavaReconciler(editor, strategy, false); + reconciler.setIsIncrementalReconciler(false); + reconciler.setProgressMonitor(new NullProgressMonitor()); + reconciler.setDelay(500); + + return reconciler; + } + return null; + } + + // public IReconciler getReconciler(ISourceViewer sourceViewer) { + // if (getEditor() != null && getEditor().isEditable()) { + // JavaReconciler reconciler = new JavaReconciler(getEditor(), + // new JavaReconcilingStrategy(getEditor()), false); + // reconciler.setProgressMonitor(new NullProgressMonitor()); + // reconciler.setDelay(500); + // return reconciler; + // } + // return null; + // } + /* + * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String) + * @since 2.1 + */ + public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) { + JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors(); + int stateMasks[] = new int[hoverDescs.length]; + int stateMasksLength = 0; + for (int i = 0; i < hoverDescs.length; i++) { + if (hoverDescs[i].isEnabled()) { + int j = 0; + int stateMask = hoverDescs[i].getStateMask(); + while (j < stateMasksLength) { + if (stateMasks[j] == stateMask) + break; + j++; + } + if (j == stateMasksLength) + stateMasks[stateMasksLength++] = stateMask; + } + } + if (stateMasksLength == hoverDescs.length) + return stateMasks; + int[] shortenedStateMasks = new int[stateMasksLength]; + System.arraycopy(stateMasks, 0, shortenedStateMasks, 0, stateMasksLength); + return shortenedStateMasks; + } + + /* + * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int) + * @since 2.1 + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) { + JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors(); + int i = 0; + while (i < hoverDescs.length) { + if (hoverDescs[i].isEnabled() && hoverDescs[i].getStateMask() == stateMask) + return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor()); + i++; + } + return null; + // if (fEditor != null) { + // IEditorInput editorInput = fEditor.getEditorInput(); + // if (editorInput instanceof IFileEditorInput) { + // try { + // IFile f = ((IFileEditorInput) editorInput).getFile(); + // return new PHPTextHover(f.getProject()); + // } catch (NullPointerException e) { + // // this exception occurs, if getTextHover is called by + // // preference pages ! + // } + // } + // } + // return new PHPTextHover(null); + } + + /* + * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String) + */ + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return getTextHover(sourceViewer, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); + } + + /** + * Returns the SmartyDoc source code scanner for this configuration. + * + * @return the SmartyDoc source code scanner + */ + protected RuleBasedScanner getSmartyDocScanner() { + return fJavaTextTools.getSmartyDocScanner(); + } + + /** + * Returns the PHPDoc source code scanner for this configuration. + * + * @return the PHPDoc source code scanner + */ + protected RuleBasedScanner getPHPDocScanner() { + return fJavaTextTools.getJavaDocScanner(); + } + + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { + return new String[] { + IDocument.DEFAULT_CONTENT_TYPE, + PHPPartitionScanner.PHP_SCRIPTING_AREA, + + IPHPPartitions.HTML, + IPHPPartitions.HTML_MULTILINE_COMMENT, + IPHPPartitions.PHP_PARTITIONING, + IPHPPartitions.PHP_SINGLELINE_COMMENT, + IPHPPartitions.PHP_MULTILINE_COMMENT, + IPHPPartitions.PHP_PHPDOC_COMMENT, + IPHPPartitions.PHP_STRING_DQ, + IPHPPartitions.PHP_STRING_SQ, + IPHPPartitions.CSS, + IPHPPartitions.CSS_MULTILINE_COMMENT, + IPHPPartitions.JAVASCRIPT, + IPHPPartitions.JS_MULTILINE_COMMENT, + IPHPPartitions.SMARTY, + IPHPPartitions.SMARTY_MULTILINE_COMMENT, + + XMLPartitionScanner.XML_PI, + XMLPartitionScanner.XML_COMMENT, + XMLPartitionScanner.XML_DECL, + XMLPartitionScanner.XML_TAG, + XMLPartitionScanner.XML_ATTRIBUTE, + XMLPartitionScanner.XML_CDATA, + + XMLPartitionScanner.DTD_INTERNAL, + XMLPartitionScanner.DTD_INTERNAL_PI, + XMLPartitionScanner.DTD_INTERNAL_COMMENT, + XMLPartitionScanner.DTD_INTERNAL_DECL, + + PHPDocumentPartitioner.PHP_TEMPLATE_DATA, + PHPDocumentPartitioner.PHP_SCRIPT_CODE + }; + } + + public String[] getConfiguredHTMLContentTypes() { + return new String[] { + XMLPartitionScanner.XML_PI, + XMLPartitionScanner.XML_COMMENT, + XMLPartitionScanner.XML_DECL, + XMLPartitionScanner.XML_TAG, + XMLPartitionScanner.XML_ATTRIBUTE, + XMLPartitionScanner.XML_CDATA, + + XMLPartitionScanner.DTD_INTERNAL, + XMLPartitionScanner.DTD_INTERNAL_PI, + XMLPartitionScanner.DTD_INTERNAL_COMMENT, + XMLPartitionScanner.DTD_INTERNAL_DECL, + }; + } + public String[] getConfiguredPHPContentTypes() { + return new String[] { + IDocument.DEFAULT_CONTENT_TYPE, + IPHPPartitions.PHP_PARTITIONING, + IPHPPartitions.PHP_SINGLELINE_COMMENT, + IPHPPartitions.PHP_MULTILINE_COMMENT, + IPHPPartitions.PHP_PHPDOC_COMMENT, + IPHPPartitions.PHP_STRING_DQ, + IPHPPartitions.PHP_STRING_SQ, + IPHPPartitions.CSS, + IPHPPartitions.CSS_MULTILINE_COMMENT, + IPHPPartitions.JAVASCRIPT, + IPHPPartitions.JS_MULTILINE_COMMENT, + IPHPPartitions.SMARTY, + IPHPPartitions.SMARTY_MULTILINE_COMMENT, + }; + } + /* + * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer) + * @since 3.0 + */ + public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) { + if (fDocumentPartitioning != null) + return fDocumentPartitioning; + return super.getConfiguredDocumentPartitioning(sourceViewer); + } + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + ContentAssistant assistant = new ContentAssistant(); + IContentAssistProcessor processor = new HTMLCompletionProcessor(); + assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + assistant.setContentAssistProcessor(processor, IPHPPartitions.HTML); + assistant.setContentAssistProcessor(processor, IPHPPartitions.HTML_MULTILINE_COMMENT); + + assistant.setContentAssistProcessor(processor, IPHPPartitions.CSS); + assistant.setContentAssistProcessor(processor, IPHPPartitions.CSS_MULTILINE_COMMENT); + assistant.setContentAssistProcessor(processor, IPHPPartitions.JAVASCRIPT); + assistant.setContentAssistProcessor(processor, IPHPPartitions.JS_MULTILINE_COMMENT); + // TODO define special smarty partition content assist + assistant.setContentAssistProcessor(processor, IPHPPartitions.SMARTY); + assistant.setContentAssistProcessor(processor, IPHPPartitions.SMARTY_MULTILINE_COMMENT); + + assistant.setContentAssistProcessor(processor, PHPDocumentPartitioner.PHP_TEMPLATE_DATA); + String[] htmlTypes = getConfiguredHTMLContentTypes(); + for (int i = 0; i < htmlTypes.length; i++) { + assistant.setContentAssistProcessor(processor, htmlTypes[i]); + } + processor = new PHPCompletionProcessor(getEditor()); + + assistant.setContentAssistProcessor(processor, PHPDocumentPartitioner.PHP_SCRIPT_CODE); + assistant.setContentAssistProcessor(processor, IPHPPartitions.PHP_PARTITIONING); + assistant.setContentAssistProcessor(processor, IPHPPartitions.PHP_STRING_DQ); + assistant.setContentAssistProcessor(processor, IPHPPartitions.PHP_STRING_SQ); + + assistant.setContentAssistProcessor(new PHPDocCompletionProcessor(), IPHPPartitions.PHP_PHPDOC_COMMENT); + // assistant.enableAutoActivation(true); + // assistant.setAutoActivationDelay(500); + // assistant.setProposalPopupOrientation(ContentAssistant.PROPOSAL_OVERLAY); + // ContentAssistPreference.configure(assistant, getPreferenceStore()); + // assistant.setContextInformationPopupOrientation( + // ContentAssistant.CONTEXT_INFO_ABOVE); + // assistant.setContextInformationPopupBackground( + // PHPEditorEnvironment.getPHPColorProvider().getColor( + // new RGB(150, 150, 0))); + ContentAssistPreference.configure(assistant, getPreferenceStore()); + assistant.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE); + assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer)); + return assistant; + } + + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + // public String getDefaultPrefix(ISourceViewer sourceViewer, String + // contentType) { + // return (PHPPartitionScanner.PHP.equals(contentType) ? "//" : null); + // //$NON-NLS-1$ + // // return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? "//" : + // null); //$NON-NLS-1$ + // } + /* + * @see SourceViewerConfiguration#getDefaultPrefix(ISourceViewer, String) + * @since 2.0 + */ + public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) { + return new String[] { "//", "" }; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) { + return new PHPDoubleClickSelector(); + } + + /* + * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String) + */ + public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) { + Vector vector = new Vector(); + // prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces + final IPreferenceStore preferences = PHPeclipsePlugin.getDefault().getPreferenceStore(); + int tabWidth = preferences.getInt(JavaCore.FORMATTER_TAB_SIZE); + boolean useSpaces = getPreferenceStore().getBoolean(SPACES_FOR_TABS); + for (int i = 0; i <= tabWidth; i++) { + StringBuffer prefix = new StringBuffer(); + if (useSpaces) { + for (int j = 0; j + i < tabWidth; j++) + prefix.append(' '); + if (i != 0) + prefix.append('\t'); + } else { + for (int j = 0; j < i; j++) + prefix.append(' '); + if (i != tabWidth) + prefix.append('\t'); + } + vector.add(prefix.toString()); + } + vector.add(""); //$NON-NLS-1$ + return (String[]) vector.toArray(new String[vector.size()]); + } + /** + * @return true iff the new setup without text tools is in use. + * + * @since 3.0 + */ + private boolean isNewSetup() { + return fJavaTextTools == null; + } + /** + * Creates and returns a preference store which combines the preference + * stores from the text tools and which is read-only. + * + * @return the read-only preference store + * @since 3.0 + */ + private IPreferenceStore createPreferenceStore() { + Assert.isTrue(!isNewSetup()); + IPreferenceStore generalTextStore= EditorsUI.getPreferenceStore(); + if (fJavaTextTools.getCorePreferenceStore() == null) + return new ChainedPreferenceStore(new IPreferenceStore[] { fJavaTextTools.getPreferenceStore(), generalTextStore}); + + return new ChainedPreferenceStore(new IPreferenceStore[] { fJavaTextTools.getPreferenceStore(), new PreferencesAdapter(fJavaTextTools.getCorePreferenceStore()), generalTextStore }); + } + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + // PHPColorProvider provider = + // PHPEditorEnvironment.getPHPColorProvider(); + // JavaColorManager provider = + // PHPEditorEnvironment.getPHPColorProvider(); + PresentationReconciler phpReconciler = new JavaPresentationReconciler(); + phpReconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + +// DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getHTMLScanner()); +// reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); +// reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); +// dr = new DefaultDamagerRepairer(getHTMLScanner()); +// reconciler.setDamager(dr, IPHPPartitions.HTML); +// reconciler.setRepairer(dr, IPHPPartitions.HTML); +// dr = new DefaultDamagerRepairer(getHTMLScanner()); +// reconciler.setDamager(dr, IPHPPartitions.CSS); +// reconciler.setRepairer(dr, IPHPPartitions.CSS); +// dr = new DefaultDamagerRepairer(getHTMLScanner()); +// reconciler.setDamager(dr, IPHPPartitions.CSS_MULTILINE_COMMENT); +// reconciler.setRepairer(dr, IPHPPartitions.CSS_MULTILINE_COMMENT); +// dr = new DefaultDamagerRepairer(getHTMLScanner()); +// reconciler.setDamager(dr, IPHPPartitions.JAVASCRIPT); +// reconciler.setRepairer(dr, IPHPPartitions.JAVASCRIPT); +// dr = new DefaultDamagerRepairer(getHTMLScanner()); +// reconciler.setDamager(dr, IPHPPartitions.JS_MULTILINE_COMMENT); +// reconciler.setRepairer(dr, IPHPPartitions.JS_MULTILINE_COMMENT); + DefaultDamagerRepairer phpDR = new DefaultDamagerRepairer(getSmartyScanner()); + phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY); + phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY); + phpDR = new DefaultDamagerRepairer(getSmartyDocScanner()); + phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT); + phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT); +// dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( +// PHPColorProvider.MULTI_LINE_COMMENT)))); +// reconciler.setDamager(dr, IPHPPartitions.HTML_MULTILINE_COMMENT); +// reconciler.setRepairer(dr, IPHPPartitions.HTML_MULTILINE_COMMENT); + + phpDR = new DefaultDamagerRepairer(getCodeScanner()); + phpReconciler.setDamager(phpDR, IDocument.DEFAULT_CONTENT_TYPE); + phpReconciler.setRepairer(phpDR, IDocument.DEFAULT_CONTENT_TYPE); + + phpDR = new DefaultDamagerRepairer(getCodeScanner()); + phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_PARTITIONING); + phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_PARTITIONING); + + phpDR = new DefaultDamagerRepairer(getPHPDocScanner()); + phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_PHPDOC_COMMENT); + phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_PHPDOC_COMMENT); + + phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( + PHPColorProvider.STRING)))); + phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_DQ); + phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_DQ); + phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( + PHPColorProvider.STRING)))); + phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_SQ); + phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_SQ); + phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( + PHPColorProvider.SINGLE_LINE_COMMENT)))); + phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_SINGLELINE_COMMENT); + phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_SINGLELINE_COMMENT); + phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( + PHPColorProvider.MULTI_LINE_COMMENT)))); + phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_MULTILINE_COMMENT); + phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_MULTILINE_COMMENT); + + PresentationReconciler reconciler = new PresentationReconciler(); + reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); +// + JavaTextTools jspTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); + DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( + PHPColorProvider.PHPDOC_TAG))));//jspTextTools.getJSPTextScanner()); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + +// dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor( +// PHPColorProvider.PHPDOC_TAG))));//jspTextTools.getJSPBracketScanner()); +// reconciler.setDamager(dr, JSPScriptScanner.JSP_BRACKET); +// reconciler.setRepairer(dr, JSPScriptScanner.JSP_BRACKET); + + // xml partitions + configureEmbeddedPresentationReconciler(reconciler, + xmlConfiguration.getPresentationReconciler(sourceViewer), + xmlConfiguration.getConfiguredContentTypes(sourceViewer), + PHPDocumentPartitioner.PHP_TEMPLATE_DATA); + + // java partitions + configureEmbeddedPresentationReconciler(reconciler, + phpReconciler, + getConfiguredPHPContentTypes(), + PHPDocumentPartitioner.PHP_SCRIPT_CODE); + + return reconciler; + } + + private void configureEmbeddedPresentationReconciler( + PresentationReconciler reconciler, + IPresentationReconciler embedded, + String[] types, + String defaultType + ) { + for (int i = 0; i < types.length; i++) { + String type = types[i]; + + IPresentationDamager damager = embedded.getDamager(type); + IPresentationRepairer repairer = embedded.getRepairer(type); + + if (type == IDocument.DEFAULT_CONTENT_TYPE) { + type = defaultType; + } + + reconciler.setDamager(damager, type); + reconciler.setRepairer(repairer, type); + } + } + + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + public int getTabWidth(ISourceViewer sourceViewer) { + return getPreferenceStore().getInt(PREFERENCE_TAB_WIDTH); + } + + /* + * (non-Javadoc) Method declared on SourceViewerConfiguration + */ + // public ITextHover getTextHover(ISourceViewer sourceViewer, String + // contentType) { + // if (fEditor != null) { + // IEditorInput editorInput = fEditor.getEditorInput(); + // if (editorInput instanceof IFileEditorInput) { + // try { + // IFile f = ((IFileEditorInput) editorInput).getFile(); + // return new PHPTextHover(f.getProject()); + // } catch (NullPointerException e) { + // // this exception occurs, if getTextHover is called by preference pages + // ! + // } + // } + // } + // return new PHPTextHover(null); + // } + /* + * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer) + * @since 2.0 + */ + public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true)); + // return new HoverBrowserControl(parent); + } + }; + } + + /* + * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer) + * @since 2.0 + */ + public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) { + InformationPresenter presenter= new InformationPresenter(getInformationPresenterControlCreator(sourceViewer)); + presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + IInformationProvider provider= new JavaInformationProvider(getEditor()); + presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE); + presenter.setInformationProvider(provider, IPHPPartitions.PHP_PHPDOC_COMMENT); +// presenter.setInformationProvider(provider, IPHPPartitions.JAVA_CHARACTER); + presenter.setSizeConstraints(60, 10, true, true); + return presenter; + } + /* + * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer) + * @since 2.0 + */ + // public IInformationPresenter getInformationPresenter(ISourceViewer + // sourceViewer) { + // InformationPresenter presenter= new + // InformationPresenter(getInformationPresenterControlCreator(sourceViewer)); + // IInformationProvider provider= new JavaInformationProvider(getEditor()); + // presenter.setInformationProvider(provider, + // IDocument.DEFAULT_CONTENT_TYPE); + // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC); + // presenter.setSizeConstraints(60, 10, true, true); + // return presenter; + // } + /** + * Returns the information presenter control creator. The creator is a factory creating the presenter controls for the given + * source viewer. This implementation always returns a creator for DefaultInformationControl instances. + * + * @param sourceViewer + * the source viewer to be configured by this configuration + * @return an information control creator + * @since 2.1 + */ + private IInformationControlCreator getInformationPresenterControlCreator(ISourceViewer sourceViewer) { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + int shellStyle = SWT.RESIZE; + int style = SWT.V_SCROLL | SWT.H_SCROLL; + return new DefaultInformationControl(parent, shellStyle, style, new HTMLTextPresenter(false)); + // return new HoverBrowserControl(parent); + } + }; + } + + /** + * Returns the outline presenter control creator. The creator is a factory creating outline presenter controls for the given + * source viewer. This implementation always returns a creator for JavaOutlineInformationControl instances. + * + * @param sourceViewer + * the source viewer to be configured by this configuration + * @return an information control creator + * @since 2.1 + */ + private IInformationControlCreator getOutlinePresenterControlCreator(ISourceViewer sourceViewer) { + return new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + int shellStyle = SWT.RESIZE; + int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL; + return new JavaOutlineInformationControl(parent, shellStyle, treeStyle); + } + }; + } + + /** + * Returns the outline presenter which will determine and shown information requested for the current cursor position. + * + * @param sourceViewer + * the source viewer to be configured by this configuration + * @param doCodeResolve + * a boolean which specifies whether code resolve should be used to compute the Java element + * @return an information presenter + * @since 2.1 + */ + public IInformationPresenter getOutlinePresenter(ISourceViewer sourceViewer, boolean doCodeResolve) { + InformationPresenter presenter = new InformationPresenter(getOutlinePresenterControlCreator(sourceViewer)); + presenter.setAnchor(InformationPresenter.ANCHOR_GLOBAL); + IInformationProvider provider = new JavaElementProvider(getEditor(), doCodeResolve); + presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE); + presenter.setInformationProvider(provider, IPHPPartitions.PHP_PARTITIONING); + presenter.setInformationProvider(provider, IPHPPartitions.PHP_PHPDOC_COMMENT); + presenter.setInformationProvider(provider, IPHPPartitions.SMARTY_MULTILINE_COMMENT); + presenter.setInformationProvider(provider, IPHPPartitions.HTML); + presenter.setInformationProvider(provider, IPHPPartitions.HTML_MULTILINE_COMMENT); + presenter.setSizeConstraints(40, 20, true, false); + return presenter; + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java index 262d596..fda5d2e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java @@ -72,7 +72,7 @@ public class IdentifierIndexManager { line.append(phpdocLength); } } - + private void addClassVariableInformation(char typeOfIdentifier, char[] identifier, StringBuffer line, int phpdocOffset, int phpdocLength) { line.append('\t'); @@ -80,7 +80,7 @@ public class IdentifierIndexManager { line.append(identifier); line.append("\to"); // Offset // we don't store the '$' in the index for class variables: - line.append(fScanner.getCurrentTokenStartPosition()+1); + line.append(fScanner.getCurrentTokenStartPosition() + 1); if (phpdocOffset >= 0) { line.append("\tp"); // phpdoc offset line.append(phpdocOffset); @@ -113,33 +113,27 @@ public class IdentifierIndexManager { char[] ident; char[] classVariable; int counter = 0; + boolean hasModifiers = false; int phpdocOffset = -1; int phpdocLength = -1; try { while (fToken != TokenNameEOF && fToken != TokenNameERROR) { phpdocOffset = -1; + hasModifiers = false; if (fToken == TokenNameCOMMENT_PHPDOC) { phpdocOffset = fScanner.getCurrentTokenStartPosition(); phpdocLength = fScanner.getCurrentTokenEndPosition() - fScanner.getCurrentTokenStartPosition() + 1; getNextToken(); + while (fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic + || fToken == TokenNameprotected || fToken == TokenNameprivate || fToken == TokenNameabstract) { + hasModifiers = true; + getNextToken(); + } if (fToken == TokenNameEOF || fToken == TokenNameERROR) { break; } } - if (fToken == TokenNamevar || fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic - || fToken == TokenNameprotected || fToken == TokenNameprivate) { - while (fToken == TokenNamevar || fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic - || fToken == TokenNameprotected || fToken == TokenNameprivate) { - getNextToken(); - } - if (fToken == TokenNameVariable) { - ident = fScanner.getCurrentIdentifierSource(); - classVariable = new char[ident.length - 1]; - System.arraycopy(ident, 1, classVariable, 0, ident.length - 1); - addClassVariableInformation('v', classVariable, buf, phpdocOffset, phpdocLength); - getNextToken(); - } - } else if (fToken == TokenNamefunction) { + if (fToken == TokenNamefunction) { getNextToken(); if (fToken == TokenNameAND) { getNextToken(); @@ -174,7 +168,20 @@ public class IdentifierIndexManager { } parseDeclarations(ident, buf, true); } - } else if (fToken == TokenNameIdentifier) { + } else if (fToken == TokenNamevar || hasModifiers || fToken == TokenNamestatic || fToken == TokenNamefinal + || fToken == TokenNamepublic || fToken == TokenNameprotected || fToken == TokenNameprivate) { + while (fToken == TokenNamevar || fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic + || fToken == TokenNameprotected || fToken == TokenNameprivate) { + getNextToken(); + } + if (fToken == TokenNameVariable) { + ident = fScanner.getCurrentIdentifierSource(); + classVariable = new char[ident.length - 1]; + System.arraycopy(ident, 1, classVariable, 0, ident.length - 1); + addClassVariableInformation('v', classVariable, buf, phpdocOffset, phpdocLength); + getNextToken(); + } + } else if (!hasModifiers && fToken == TokenNameIdentifier) { ident = fScanner.getCurrentIdentifierSource(); getNextToken(); if (ident.length == 6 && ident[0] == 'd' && ident[1] == 'e' && ident[2] == 'f' && ident[3] == 'i' && ident[4] == 'n' @@ -221,6 +228,7 @@ public class IdentifierIndexManager { char[] ident; String identifier; int counter = 0; + boolean hasModifiers = false; int phpdocOffset = -1; int phpdocLength = -1; fScanner.setSource(charArray); @@ -230,10 +238,16 @@ public class IdentifierIndexManager { try { while (fToken != TokenNameEOF) { // && fToken != TokenNameERROR) { phpdocOffset = -1; + hasModifiers = false; if (fToken == TokenNameCOMMENT_PHPDOC) { phpdocOffset = fScanner.getCurrentTokenStartPosition(); phpdocLength = fScanner.getCurrentTokenEndPosition() - fScanner.getCurrentTokenStartPosition() + 1; getNextToken(); + while (fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic + || fToken == TokenNameprotected || fToken == TokenNameprivate || fToken == TokenNameabstract) { + hasModifiers = true; + getNextToken(); + } if (fToken == TokenNameEOF || fToken == TokenNameERROR) { break; } @@ -267,7 +281,7 @@ public class IdentifierIndexManager { ident = fScanner.getCurrentIdentifierSource(); addIdentifierInformation('g', ident, buf, phpdocOffset, phpdocLength); getNextToken(); - } else if (fToken == TokenNameIdentifier) { + } else if (!hasModifiers && fToken == TokenNameIdentifier) { ident = fScanner.getCurrentIdentifierSource(); getNextToken(); if (ident.length == 6 && ident[0] == 'd' && ident[1] == 'e' && ident[2] == 'f' && ident[3] == 'i' && ident[4] == 'n' diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java index c570267..d65fe4c 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java @@ -30,6 +30,8 @@ public class JavaDocumentSetupParticipant implements IDocumentSetupParticipant */ public void setup(IDocument document) { JavaTextTools tools= PHPeclipsePlugin.getDefault().getJavaTextTools(); - tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING, null); //IPHPPartitions.PHP_PARTITIONING, null); + tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING); + +// tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING, null); //IPHPPartitions.PHP_PARTITIONING, null); } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java index c5f8376..1b91695 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager; import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java index a5faee3..e91b68d 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java @@ -33,7 +33,9 @@ public class JavaStorageDocumentProvider extends StorageDocumentProvider { if (document != null) { JavaTextTools tools= PHPeclipsePlugin.getDefault().getJavaTextTools(); - tools.setupJavaDocumentPartitioner(document, IPHPPartitions.HTML, element); + tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING); + +// tools.setupJavaDocumentPartitioner(document, IDocument.DEFAULT_CONTENT_TYPE, element); //IPHPPartitions.HTML, element); } } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java index d7b5126..040e974 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java @@ -42,6 +42,7 @@ import net.sourceforge.phpdt.ui.JavaUI; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider; import net.sourceforge.phpeclipse.PHPeclipsePlugin; @@ -140,7 +141,6 @@ import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.editors.text.IEncodingSupport; import org.eclipse.ui.part.IShowInTargetList; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; -import org.eclipse.ui.texteditor.AnnotationPreference; import org.eclipse.ui.texteditor.ChainedPreferenceStore; import org.eclipse.ui.texteditor.DefaultRangeIndicator; import org.eclipse.ui.texteditor.IDocumentProvider; @@ -148,6 +148,7 @@ import org.eclipse.ui.texteditor.IEditorStatusLine; import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.ResourceAction; +import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; import org.eclipse.ui.texteditor.TextEditorAction; import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.views.contentoutline.ContentOutline; @@ -1741,7 +1742,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I protected void initializeEditor() { //jsurfer old code JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); - setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this)); //, IJavaPartitions.JAVA_PARTITIONING)); + setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this, IPHPPartitions.PHP_PARTITIONING)); //, IJavaPartitions.JAVA_PARTITIONING)); setRangeIndicator(new DefaultRangeIndicator()); // IPreferenceStore store= // PHPeclipsePlugin.getDefault().getPreferenceStore(); @@ -1893,6 +1894,14 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I // getEditorSite().getShell().addShellListener(fActivationListener); } + protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) { + + support.setCharacterPairMatcher(fBracketMatcher); + support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR); + + super.configureSourceViewerDecorationSupport(support); + } + /** * Returns this document's complete text. * diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java deleted file mode 100644 index 5ecde70..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java +++ /dev/null @@ -1,731 +0,0 @@ -/********************************************************************** - Copyright (c) 2000, 2002 IBM Corp. and others. - All rights reserved. This program and the accompanying materials - are made available under the terms of the Common Public License v1.0 - which accompanies this distribution, and is available at - http://www.eclipse.org/legal/cpl-v10.html - - Contributors: - IBM Corporation - Initial implementation - Klaus Hartlage - www.eclipseproject.de - **********************************************************************/ -package net.sourceforge.phpeclipse.phpeditor; -import java.util.Vector; - -import net.sourceforge.phpdt.core.JavaCore; -import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner; -import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; -import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter; -import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; -import net.sourceforge.phpdt.internal.ui.text.JavaAnnotationHover; -import net.sourceforge.phpdt.internal.ui.text.JavaCompositeReconcilingStrategy; -import net.sourceforge.phpdt.internal.ui.text.JavaElementProvider; -import net.sourceforge.phpdt.internal.ui.text.JavaOutlineInformationControl; -import net.sourceforge.phpdt.internal.ui.text.JavaPresentationReconciler; -import net.sourceforge.phpdt.internal.ui.text.JavaReconciler; -import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy; -import net.sourceforge.phpdt.internal.ui.text.java.JavaReconcilingStrategy; -import net.sourceforge.phpdt.internal.ui.text.java.JavaStringAutoIndentStrategy; -import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor; -import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy; -import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor; -import net.sourceforge.phpdt.ui.PreferenceConstants; -import net.sourceforge.phpdt.ui.text.IColorManager; -import net.sourceforge.phpdt.ui.text.JavaTextTools; -import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.html.HTMLFormattingStrategy; -import net.sourceforge.phpeclipse.phpeditor.php.HTMLCompletionProcessor; -import net.sourceforge.phpeclipse.phpeditor.php.PHPAutoIndentStrategy; -import net.sourceforge.phpeclipse.phpeditor.php.PHPCompletionProcessor; -import net.sourceforge.phpeclipse.phpeditor.php.PHPDoubleClickSelector; -import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider; - -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.text.DefaultAutoIndentStrategy; -import org.eclipse.jface.text.DefaultInformationControl; -import org.eclipse.jface.text.IAutoIndentStrategy; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IInformationControl; -import org.eclipse.jface.text.IInformationControlCreator; -import org.eclipse.jface.text.ITextDoubleClickStrategy; -import org.eclipse.jface.text.ITextHover; -import org.eclipse.jface.text.ITextViewerExtension2; -import org.eclipse.jface.text.TextAttribute; -import org.eclipse.jface.text.contentassist.ContentAssistant; -import org.eclipse.jface.text.contentassist.IContentAssistProcessor; -import org.eclipse.jface.text.contentassist.IContentAssistant; -import org.eclipse.jface.text.formatter.ContentFormatter; -import org.eclipse.jface.text.formatter.IContentFormatter; -import org.eclipse.jface.text.formatter.IFormattingStrategy; -import org.eclipse.jface.text.information.IInformationPresenter; -import org.eclipse.jface.text.information.IInformationProvider; -import org.eclipse.jface.text.information.InformationPresenter; -import org.eclipse.jface.text.presentation.IPresentationReconciler; -import org.eclipse.jface.text.presentation.PresentationReconciler; -import org.eclipse.jface.text.reconciler.IReconciler; -import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; -import org.eclipse.jface.text.rules.DefaultDamagerRepairer; -import org.eclipse.jface.text.rules.DefaultPartitioner; -import org.eclipse.jface.text.rules.RuleBasedScanner; -import org.eclipse.jface.text.rules.Token; -import org.eclipse.jface.text.source.IAnnotationHover; -import org.eclipse.jface.text.source.ISourceViewer; -import org.eclipse.jface.text.source.SourceViewerConfiguration; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.texteditor.ITextEditor; -/** - * Configuration for an SourceViewer which shows PHP code. - */ -public class PHPSourceViewerConfiguration extends SourceViewerConfiguration { - /** - * Preference key used to look up display tab width. - * - * @since 2.0 - */ - public final static String PREFERENCE_TAB_WIDTH = PreferenceConstants.EDITOR_TAB_WIDTH; - /** - * Preference key for inserting spaces rather than tabs. - * - * @since 2.0 - */ - public final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS; - // public static final String HTML_DEFAULT = - // IPHPPartitionScannerConstants.HTML; - //IDocument.DEFAULT_CONTENT_TYPE; - private JavaTextTools fJavaTextTools; - private ITextEditor fTextEditor; - private ContentFormatter fFormatter; - private HTMLFormattingStrategy fFormattingStrategy; - /** - * Single token scanner. - */ - static class SingleTokenScanner extends BufferedRuleBasedScanner { - public SingleTokenScanner(TextAttribute attribute) { - setDefaultReturnToken(new Token(attribute)); - } - }; - /** - * The document partitioning. - * @since 3.0 - */ - private String fDocumentPartitioning; - /** - * The Java source code scanner - * @since 3.0 - */ - private AbstractJavaScanner fCodeScanner; - /** - * The Java multi-line comment scanner - * @since 3.0 - */ - private AbstractJavaScanner fMultilineCommentScanner; - /** - * The Java single-line comment scanner - * @since 3.0 - */ - private AbstractJavaScanner fSinglelineCommentScanner; - /** - * The Java string scanner - * @since 3.0 - */ - private AbstractJavaScanner fStringScanner; - /** - * The Javadoc scanner - * @since 3.0 - */ - private AbstractJavaScanner fJavaDocScanner; - /** - * The preference store, can be read-only - * @since 3.0 - */ - private IPreferenceStore fPreferenceStore; - /** - * The color manager - * @since 3.0 - */ - private IColorManager fColorManager; - - /** - * Creates a new Java source viewer configuration for viewers in the given editor - * using the given preference store, the color manager and the specified document partitioning. - *

- * Creates a Java source viewer configuration in the new setup without text tools. Clients are - * allowed to call {@link JavaSourceViewerConfiguration#handlePropertyChangeEvent(PropertyChangeEvent)} - * and disallowed to call {@link JavaSourceViewerConfiguration#getPreferenceStore()} on the resulting - * Java source viewer configuration. - *

- * - * @param colorManager the color manager - * @param preferenceStore the preference store, can be read-only - * @param editor the editor in which the configured viewer(s) will reside - * @param partitioning the document partitioning for this configuration - * @since 3.0 - */ - public PHPSourceViewerConfiguration(IColorManager colorManager, IPreferenceStore preferenceStore, ITextEditor editor, String partitioning) { - fColorManager= colorManager; - fPreferenceStore= preferenceStore; - fTextEditor= editor; - fDocumentPartitioning= partitioning; - fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); -// initializeScanners(); - } - - /** - * Default constructor. - */ - public PHPSourceViewerConfiguration(JavaTextTools textTools, - PHPEditor editor) { - fJavaTextTools = textTools; - fTextEditor = editor; - } - /* - * @see SourceViewerConfiguration#getContentFormatter(ISourceViewer) - */ - public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) { - // if (fFormatter == null) { - // fFormatter = new ContentFormatter(); - // fFormattingStrategy = new HTMLFormattingStrategy(this, - // sourceViewer); - // fFormatter.setFormattingStrategy(fFormattingStrategy, HTML_DEFAULT); - // fFormatter.enablePartitionAwareFormatting(false); - // fFormatter.setPartitionManagingPositionCategories(getConfiguredContentTypes(null)); - // } - // return fFormatter; - if (fFormatter == null) { - //ContentFormatter - fFormatter = new ContentFormatter(); - IFormattingStrategy strategy = new JavaFormattingStrategy( - sourceViewer); - fFormatter.setFormattingStrategy(strategy, - IDocument.DEFAULT_CONTENT_TYPE); - fFormatter.enablePartitionAwareFormatting(false); - fFormatter - .setPartitionManagingPositionCategories(getPartitionManagingPositionCategories()); - } - return fFormatter; - } - /** - * Returns the names of the document position categories used by the - * document partitioners created by this object to manage their partition - * information. If the partitioners don't use document position categories, - * the returned result is null. - * - * @return the partition managing position categories or null - * if there is none - */ - public String[] getPartitionManagingPositionCategories() { - return new String[]{DefaultPartitioner.CONTENT_TYPES_CATEGORY}; - } - // /** - // * Returns the names of the document position categories used by the - // document - // * partitioners created by this object to manage their partition - // information. - // * If the partitioners don't use document position categories, the - // returned - // * result is null. - // * - // * @return the partition managing position categories or - // null - // * if there is none - // */ - // private String[] getPartitionManagingPositionCategories() { - // return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY }; - // } - public ITextEditor getEditor() { - return fTextEditor; - } - /** - * Returns the preference store used by this configuration to initialize - * the individual bits and pieces. - * - * @return the preference store used to initialize this configuration - * - * @since 2.0 - */ - protected IPreferenceStore getPreferenceStore() { - return PHPeclipsePlugin.getDefault().getPreferenceStore(); - } - // /* (non-Javadoc) - // * Method declared on SourceViewerConfiguration - // */ - // public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { - // return new PHPAnnotationHover(); - // } - /* - * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer) - */ - public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { - return new JavaAnnotationHover(JavaAnnotationHover.VERTICAL_RULER_HOVER); - } - /* - * @see SourceViewerConfiguration#getOverviewRulerAnnotationHover(ISourceViewer) - * @since 3.0 - */ - public IAnnotationHover getOverviewRulerAnnotationHover( - ISourceViewer sourceViewer) { - return new JavaAnnotationHover(JavaAnnotationHover.OVERVIEW_RULER_HOVER); - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - public IAutoIndentStrategy getAutoIndentStrategy( - ISourceViewer sourceViewer, String contentType) { - if (IPHPPartitions.PHP_STRING_DQ.equals(contentType)) - return new JavaStringAutoIndentStrategy(getConfiguredDocumentPartitioning(sourceViewer)); - - return (IPHPPartitions.PHP_PARTITIONING.equals(contentType) - ? new PHPAutoIndentStrategy() - : new DefaultAutoIndentStrategy()); - } - /** - * Returns the PHP source code scanner for this configuration. - * - * @return the PHP source code scanner - */ - protected RuleBasedScanner getCodeScanner() { - return fJavaTextTools.getCodeScanner(); - } - /** - * Returns the HTML source code scanner for this configuration. - * - * @return the HTML source code scanner - */ - protected RuleBasedScanner getHTMLScanner() { - return fJavaTextTools.getHTMLScanner(); - } - /** - * Returns the Smarty source code scanner for this configuration. - * - * @return the Smarty source code scanner - */ - protected RuleBasedScanner getSmartyScanner() { - return fJavaTextTools.getSmartyScanner(); - } - /* - * @see SourceViewerConfiguration#getReconciler(ISourceViewer) - */ - /* - * @see SourceViewerConfiguration#getReconciler(ISourceViewer) - */ - public IReconciler getReconciler(ISourceViewer sourceViewer) { - - final ITextEditor editor= getEditor(); - if (editor != null && editor.isEditable()) { - - JavaCompositeReconcilingStrategy strategy= new JavaCompositeReconcilingStrategy(editor, getConfiguredDocumentPartitioning(sourceViewer)); - JavaReconciler reconciler= new JavaReconciler(editor, strategy, false); - reconciler.setIsIncrementalReconciler(false); - reconciler.setProgressMonitor(new NullProgressMonitor()); - reconciler.setDelay(500); - - return reconciler; - } - return null; - } -// public IReconciler getReconciler(ISourceViewer sourceViewer) { -// if (getEditor() != null && getEditor().isEditable()) { -// JavaReconciler reconciler = new JavaReconciler(getEditor(), -// new JavaReconcilingStrategy(getEditor()), false); -// reconciler.setProgressMonitor(new NullProgressMonitor()); -// reconciler.setDelay(500); -// return reconciler; -// } -// return null; -// } - /* - * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, - * String) - * @since 2.1 - */ - public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, - String contentType) { - JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin - .getDefault().getJavaEditorTextHoverDescriptors(); - int stateMasks[] = new int[hoverDescs.length]; - int stateMasksLength = 0; - for (int i = 0; i < hoverDescs.length; i++) { - if (hoverDescs[i].isEnabled()) { - int j = 0; - int stateMask = hoverDescs[i].getStateMask(); - while (j < stateMasksLength) { - if (stateMasks[j] == stateMask) - break; - j++; - } - if (j == stateMasksLength) - stateMasks[stateMasksLength++] = stateMask; - } - } - if (stateMasksLength == hoverDescs.length) - return stateMasks; - int[] shortenedStateMasks = new int[stateMasksLength]; - System.arraycopy(stateMasks, 0, shortenedStateMasks, 0, - stateMasksLength); - return shortenedStateMasks; - } - /* - * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int) - * @since 2.1 - */ - public ITextHover getTextHover(ISourceViewer sourceViewer, - String contentType, int stateMask) { - JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin - .getDefault().getJavaEditorTextHoverDescriptors(); - int i = 0; - while (i < hoverDescs.length) { - if (hoverDescs[i].isEnabled() - && hoverDescs[i].getStateMask() == stateMask) - return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor()); - i++; - } - return null; -// if (fEditor != null) { -// IEditorInput editorInput = fEditor.getEditorInput(); -// if (editorInput instanceof IFileEditorInput) { -// try { -// IFile f = ((IFileEditorInput) editorInput).getFile(); -// return new PHPTextHover(f.getProject()); -// } catch (NullPointerException e) { -// // this exception occurs, if getTextHover is called by -// // preference pages ! -// } -// } -// } -// return new PHPTextHover(null); - } - /* - * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String) - */ - public ITextHover getTextHover(ISourceViewer sourceViewer, - String contentType) { - return getTextHover(sourceViewer, contentType, - ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); - } - /** - * Returns the SmartyDoc source code scanner for this configuration. - * - * @return the SmartyDoc source code scanner - */ - protected RuleBasedScanner getSmartyDocScanner() { - return fJavaTextTools.getSmartyDocScanner(); - } - /** - * Returns the PHPDoc source code scanner for this configuration. - * - * @return the PHPDoc source code scanner - */ - protected RuleBasedScanner getPHPDocScanner() { - return fJavaTextTools.getJavaDocScanner(); - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { - return new String[]{IPHPPartitions.HTML, - IPHPPartitions.HTML_MULTILINE_COMMENT, - IPHPPartitions.PHP_PARTITIONING, - IPHPPartitions.PHP_PHPDOC_COMMENT, - IPHPPartitions.CSS, - IPHPPartitions.CSS_MULTILINE_COMMENT, - IPHPPartitions.JAVASCRIPT, - IPHPPartitions.JS_MULTILINE_COMMENT, - IPHPPartitions.SMARTY, - IPHPPartitions.SMARTY_MULTILINE_COMMENT, - IDocument.DEFAULT_CONTENT_TYPE}; - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { - ContentAssistant assistant = new ContentAssistant(); - IContentAssistProcessor processor = new HTMLCompletionProcessor(); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.HTML); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.HTML_MULTILINE_COMMENT); - assistant.setContentAssistProcessor(processor, - IDocument.DEFAULT_CONTENT_TYPE); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.CSS); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.CSS_MULTILINE_COMMENT); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.JAVASCRIPT); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.JS_MULTILINE_COMMENT); - // TODO define special smarty partition content assist - assistant.setContentAssistProcessor(processor, - IPHPPartitions.SMARTY); - assistant.setContentAssistProcessor(processor, - IPHPPartitions.SMARTY_MULTILINE_COMMENT); - assistant.setContentAssistProcessor(new PHPCompletionProcessor(getEditor()), - IPHPPartitions.PHP_PARTITIONING); - assistant.setContentAssistProcessor(new PHPDocCompletionProcessor(), - IPHPPartitions.PHP_PHPDOC_COMMENT); - // assistant.enableAutoActivation(true); - // assistant.setAutoActivationDelay(500); - // assistant.setProposalPopupOrientation(ContentAssistant.PROPOSAL_OVERLAY); - // ContentAssistPreference.configure(assistant, getPreferenceStore()); - // assistant.setContextInformationPopupOrientation( - // ContentAssistant.CONTEXT_INFO_ABOVE); - // assistant.setContextInformationPopupBackground( - // PHPEditorEnvironment.getPHPColorProvider().getColor( - // new RGB(150, 150, 0))); - ContentAssistPreference.configure(assistant, getPreferenceStore()); - assistant - .setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE); - assistant - .setInformationControlCreator(getInformationControlCreator(sourceViewer)); - return assistant; - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - // public String getDefaultPrefix(ISourceViewer sourceViewer, String - // contentType) { - // return (PHPPartitionScanner.PHP.equals(contentType) ? "//" : null); - // //$NON-NLS-1$ - // // return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? "//" : - // null); //$NON-NLS-1$ - // } - /* - * @see SourceViewerConfiguration#getDefaultPrefix(ISourceViewer, String) - * @since 2.0 - */ - public String[] getDefaultPrefixes(ISourceViewer sourceViewer, - String contentType) { - return new String[]{"//", ""}; //$NON-NLS-1$ //$NON-NLS-2$ - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - public ITextDoubleClickStrategy getDoubleClickStrategy( - ISourceViewer sourceViewer, String contentType) { - return new PHPDoubleClickSelector(); - } - /* - * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String) - */ - public String[] getIndentPrefixes(ISourceViewer sourceViewer, - String contentType) { - Vector vector = new Vector(); - // prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces - final IPreferenceStore preferences = PHPeclipsePlugin.getDefault() - .getPreferenceStore(); - int tabWidth = preferences.getInt(JavaCore.FORMATTER_TAB_SIZE); - boolean useSpaces = getPreferenceStore().getBoolean(SPACES_FOR_TABS); - for (int i = 0; i <= tabWidth; i++) { - StringBuffer prefix = new StringBuffer(); - if (useSpaces) { - for (int j = 0; j + i < tabWidth; j++) - prefix.append(' '); - if (i != 0) - prefix.append('\t'); - } else { - for (int j = 0; j < i; j++) - prefix.append(' '); - if (i != tabWidth) - prefix.append('\t'); - } - vector.add(prefix.toString()); - } - vector.add(""); //$NON-NLS-1$ - return (String[]) vector.toArray(new String[vector.size()]); - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - public IPresentationReconciler getPresentationReconciler( - ISourceViewer sourceViewer) { - // PHPColorProvider provider = - // PHPEditorEnvironment.getPHPColorProvider(); - // JavaColorManager provider = - // PHPEditorEnvironment.getPHPColorProvider(); - PresentationReconciler reconciler= new JavaPresentationReconciler(); - reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); - - DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getHTMLScanner()); - reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); - reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); - dr = new DefaultDamagerRepairer(getHTMLScanner()); - reconciler.setDamager(dr, IPHPPartitions.HTML); - reconciler.setRepairer(dr, IPHPPartitions.HTML); - dr = new DefaultDamagerRepairer(getHTMLScanner()); - reconciler.setDamager(dr, IPHPPartitions.CSS); - reconciler.setRepairer(dr, IPHPPartitions.CSS); - dr = new DefaultDamagerRepairer(getHTMLScanner()); - reconciler.setDamager(dr, - IPHPPartitions.CSS_MULTILINE_COMMENT); - reconciler.setRepairer(dr, - IPHPPartitions.CSS_MULTILINE_COMMENT); - dr = new DefaultDamagerRepairer(getHTMLScanner()); - reconciler.setDamager(dr, IPHPPartitions.JAVASCRIPT); - reconciler.setRepairer(dr, IPHPPartitions.JAVASCRIPT); - dr = new DefaultDamagerRepairer(getHTMLScanner()); - reconciler.setDamager(dr, - IPHPPartitions.JS_MULTILINE_COMMENT); - reconciler.setRepairer(dr, - IPHPPartitions.JS_MULTILINE_COMMENT); - dr = new DefaultDamagerRepairer(getSmartyScanner()); - reconciler.setDamager(dr, IPHPPartitions.SMARTY); - reconciler.setRepairer(dr, IPHPPartitions.SMARTY); - dr = new DefaultDamagerRepairer(getSmartyDocScanner()); - reconciler.setDamager(dr, - IPHPPartitions.SMARTY_MULTILINE_COMMENT); - reconciler.setRepairer(dr, - IPHPPartitions.SMARTY_MULTILINE_COMMENT); - dr = new DefaultDamagerRepairer(new SingleTokenScanner( - new TextAttribute(fJavaTextTools.getColorManager().getColor( - PHPColorProvider.MULTI_LINE_COMMENT)))); - reconciler.setDamager(dr, - IPHPPartitions.HTML_MULTILINE_COMMENT); - reconciler.setRepairer(dr, - IPHPPartitions.HTML_MULTILINE_COMMENT); - dr = new DefaultDamagerRepairer(getCodeScanner()); - reconciler.setDamager(dr, IPHPPartitions.PHP_PARTITIONING); - reconciler.setRepairer(dr, IPHPPartitions.PHP_PARTITIONING); - dr = new DefaultDamagerRepairer(getPHPDocScanner()); - reconciler.setDamager(dr, - IPHPPartitions.PHP_PHPDOC_COMMENT); - reconciler.setRepairer(dr, - IPHPPartitions.PHP_PHPDOC_COMMENT); - return reconciler; - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - public int getTabWidth(ISourceViewer sourceViewer) { - return getPreferenceStore().getInt(PREFERENCE_TAB_WIDTH); - } - /* - * (non-Javadoc) Method declared on SourceViewerConfiguration - */ - // public ITextHover getTextHover(ISourceViewer sourceViewer, String - // contentType) { - // if (fEditor != null) { - // IEditorInput editorInput = fEditor.getEditorInput(); - // if (editorInput instanceof IFileEditorInput) { - // try { - // IFile f = ((IFileEditorInput) editorInput).getFile(); - // return new PHPTextHover(f.getProject()); - // } catch (NullPointerException e) { - // // this exception occurs, if getTextHover is called by preference pages - // ! - // } - // } - // } - // return new PHPTextHover(null); - // } - /* - * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer) - * @since 2.0 - */ - public IInformationControlCreator getInformationControlCreator( - ISourceViewer sourceViewer) { - return new IInformationControlCreator() { - public IInformationControl createInformationControl(Shell parent) { - return new DefaultInformationControl(parent, SWT.NONE, - new HTMLTextPresenter(true)); - // return new HoverBrowserControl(parent); - } - }; - } - /* - * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer) - * @since 2.0 - */ - // public IInformationPresenter getInformationPresenter(ISourceViewer - // sourceViewer) { - // InformationPresenter presenter= new - // InformationPresenter(getInformationPresenterControlCreator(sourceViewer)); - // IInformationProvider provider= new JavaInformationProvider(getEditor()); - // presenter.setInformationProvider(provider, - // IDocument.DEFAULT_CONTENT_TYPE); - // presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC); - // presenter.setSizeConstraints(60, 10, true, true); - // return presenter; - // } - /** - * Returns the information presenter control creator. The creator is a - * factory creating the presenter controls for the given source viewer. - * This implementation always returns a creator for DefaultInformationControl - * instances. - * - * @param sourceViewer - * the source viewer to be configured by this configuration - * @return an information control creator - * @since 2.1 - */ - private IInformationControlCreator getInformationPresenterControlCreator( - ISourceViewer sourceViewer) { - return new IInformationControlCreator() { - public IInformationControl createInformationControl(Shell parent) { - int shellStyle = SWT.RESIZE; - int style = SWT.V_SCROLL | SWT.H_SCROLL; - return new DefaultInformationControl(parent, shellStyle, style, - new HTMLTextPresenter(false)); - // return new HoverBrowserControl(parent); - } - }; - } - /** - * Returns the outline presenter control creator. The creator is a factory - * creating outline presenter controls for the given source viewer. This - * implementation always returns a creator for JavaOutlineInformationControl - * instances. - * - * @param sourceViewer - * the source viewer to be configured by this configuration - * @return an information control creator - * @since 2.1 - */ - private IInformationControlCreator getOutlinePresenterControlCreator( - ISourceViewer sourceViewer) { - return new IInformationControlCreator() { - public IInformationControl createInformationControl(Shell parent) { - int shellStyle = SWT.RESIZE; - int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL; - return new JavaOutlineInformationControl(parent, shellStyle, - treeStyle); - } - }; - } - /** - * Returns the outline presenter which will determine and shown information - * requested for the current cursor position. - * - * @param sourceViewer - * the source viewer to be configured by this configuration - * @param doCodeResolve - * a boolean which specifies whether code resolve should be used - * to compute the Java element - * @return an information presenter - * @since 2.1 - */ - public IInformationPresenter getOutlinePresenter( - ISourceViewer sourceViewer, boolean doCodeResolve) { - InformationPresenter presenter = new InformationPresenter( - getOutlinePresenterControlCreator(sourceViewer)); - presenter.setAnchor(InformationPresenter.ANCHOR_GLOBAL); - IInformationProvider provider = new JavaElementProvider(getEditor(), - doCodeResolve); - presenter.setInformationProvider(provider, - IDocument.DEFAULT_CONTENT_TYPE); - presenter.setInformationProvider(provider, - IPHPPartitions.PHP_PARTITIONING); - presenter.setInformationProvider(provider, - IPHPPartitions.PHP_PHPDOC_COMMENT); - presenter.setInformationProvider(provider, - IPHPPartitions.SMARTY_MULTILINE_COMMENT); - presenter.setInformationProvider(provider, - IPHPPartitions.HTML); - presenter.setInformationProvider(provider, - IPHPPartitions.HTML_MULTILINE_COMMENT); - presenter.setSizeConstraints(40, 20, true, false); - return presenter; - } -} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java index 7be2787..7ce2ef1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java @@ -70,7 +70,8 @@ public class PHPTextHover implements ITextHover { // elbuffer.getHoverText()); // } } - String hoverInfo = (String) functionDescriptions.get(word); + String hoverInfo = + (String) functionDescriptions.get(word); if (hoverInfo == null && fProject != null) { // get the possible PHPDoc information from the index file IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault() @@ -82,8 +83,14 @@ public class PHPTextHover implements ITextHover { String filename; FileReader phpdocFileReader; StringBuffer hoverInfoBuffer = new StringBuffer(); - String workspaceLocation = PHPeclipsePlugin.getWorkspace() - .getRoot().getLocation().toString(); + String workspaceLocation; + if (fProject!=null) { + workspaceLocation = fProject.getLocation().toString()+'/'; + } else { + // should never happen? + workspaceLocation = PHPeclipsePlugin.getWorkspace() + .getRoot().getLocation().toString(); + } // boolean foundPHPdoc = false; for (int i = 0; i < list.size(); i++) { location = (PHPIdentifierLocation) list.get(i); 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 a7cc596..f37c360 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java @@ -19,6 +19,7 @@ import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager; +import net.sourceforge.phpdt.internal.ui.text.SmartSemicolonAutoEditStrategy; import net.sourceforge.phpdt.internal.ui.text.java.IJavaReconcilingListener; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager; import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI; @@ -48,6 +49,7 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentCommand; +import org.eclipse.jface.text.IAutoEditStrategy; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.IRegion; @@ -498,18 +500,28 @@ public class PHPUnitEditor extends PHPEditor { //implements return super.requestWidgetToken(requester); } - /* - * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration) - */ +// /* +// * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration) +// */ +// public void configure(SourceViewerConfiguration configuration) { +// super.configure(configuration); +// // fCorrectionAssistant= new +// // JavaCorrectionAssistant(CompilationUnitEditor.this); +// // fCorrectionAssistant.install(this); +// //TODO install SmartBracesAutoEditStrategy +// // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), +// // IDocument.DEFAULT_CONTENT_TYPE); +// } public void configure(SourceViewerConfiguration configuration) { - super.configure(configuration); - // fCorrectionAssistant= new - // JavaCorrectionAssistant(CompilationUnitEditor.this); - // fCorrectionAssistant.install(this); - //TODO install SmartBracesAutoEditStrategy - // prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), - // IDocument.DEFAULT_CONTENT_TYPE); - } + super.configure(configuration); +// fCorrectionAssistant= new JavaCorrectionAssistant(CompilationUnitEditor.this); +// fCorrectionAssistant.install(this); + 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.JAVA_CHARACTER); + } }; /** * Remembers data related to the current selection to be able to diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormatter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormatter.java index 7e4c33c..e995bef 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormatter.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormatter.java @@ -4,8 +4,8 @@ import java.io.StringWriter; import java.util.HashSet; import java.util.Set; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.text.source.SourceViewer; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormattingStrategy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormattingStrategy.java index 2781272..0a52a0e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormattingStrategy.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormattingStrategy.java @@ -1,6 +1,6 @@ package net.sourceforge.phpeclipse.phpeditor.html; -import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration; +import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java new file mode 100644 index 0000000..d746edd --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java @@ -0,0 +1,845 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.phpeditor.php; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.DefaultPositionUpdater; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.IDocumentPartitionerExtension; +import org.eclipse.jface.text.IDocumentPartitionerExtension2; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TypedPosition; +import org.eclipse.jface.text.TypedRegion; +import org.eclipse.jface.text.rules.IPartitionTokenScanner; +import org.eclipse.jface.text.rules.IToken; + +/** + * A standard implementation of a document partitioner. It uses a partition token scanner to scan the document and to determine the + * document's partitioning. The tokens returned by the scanner are supposed to return the partition type as their data. The + * partitioner remembers the document's partitions in the document itself rather than maintaining its own data structure. + * + * @see IPartitionTokenScanner + * @since 2.0 + */ +public class DefaultPHPPartitioner_delete_it implements IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2 { + + /** + * The position category this partitioner uses to store the document's partitioning information. + * + * @deprecated As of 3.0, use getManagingPositionCategories() instead. + */ + public final static String CONTENT_TYPES_CATEGORY = "__content_types_category"; //$NON-NLS-1$ + + /** The HTML areas partitioner's scanner */ + protected IPartitionTokenScanner fHTMLScanner; + + /** The PHP areas partitioner's scanner */ + protected IPartitionTokenScanner fPHPScanner; + + /** The legal content types of both partitioners */ + protected String[] fLegalContentTypes; + + /** The legal content types of the HTML partitioner */ + protected String[] fLegalHTMLContentTypes; + + /** The legal content types of the PHP partitioner */ + protected String[] fLegalPHPContentTypes; + + /** The partitioner's document */ + protected IDocument fDocument; + + /** The document length before a document change occurred */ + protected int fPreviousDocumentLength; + + /** The position updater used to for the default updating of partitions */ + protected DefaultPositionUpdater fPositionUpdater; + + /** The offset at which the first changed partition starts */ + protected int fStartOffset; + + /** The offset at which the last changed partition ends */ + protected int fEndOffset; + + /** The offset at which a partition has been deleted */ + protected int fDeleteOffset; + + /** + * The position category this partitioner uses to store the document's partitioning information. + * + * @since 3.0 + */ + private String fPositionCategory; + + /** + * Creates a new partitioner that uses the given scanner and may return partitions of the given legal content types. + * + * @param scanner + * the scanner this partitioner is supposed to use + * @param legalContentTypes + * the legal content types of this partitioner + */ + public DefaultPHPPartitioner_delete_it(IPartitionTokenScanner htmlScanner, IPartitionTokenScanner phpScanner, String[] legalContentTypes, + String[] legalHTMLContentTypes, String[] legalPHPContentTypes) { + fHTMLScanner = htmlScanner; + fPHPScanner = phpScanner; + fLegalContentTypes = legalContentTypes; + fLegalHTMLContentTypes = legalHTMLContentTypes; + fLegalPHPContentTypes = legalPHPContentTypes; + + fPositionCategory = CONTENT_TYPES_CATEGORY + hashCode(); + fPositionUpdater = new DefaultPositionUpdater(fPositionCategory); + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() + * @since 3.0 + */ + public String[] getManagingPositionCategories() { + return new String[] { fPositionCategory }; + } + + /* + * @see IDocumentPartitioner#connect(IDocument) + */ + public void connect(IDocument document) { + Assert.isNotNull(document); + Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); + + fDocument = document; + fDocument.addPositionCategory(fPositionCategory); + + initialize(fDocument.getLength()); + } + + /** + * Performs the initial partitioning of the partitioner's document. + */ + protected void initialize(int initialLength) { + char ch; + boolean htmlMode = true; + int startPosition = 0; + int length = 0; + int i = 0; + try { + + while (i < initialLength) { + ch = fDocument.getChar(i++); + if (htmlMode) { + if (ch == '<' && fDocument.getChar(i) == '?' && fDocument.getChar(i + 1) == ' ') { + length = i - startPosition - 1; + if (length != 0) { + initializeHTML(startPosition, length); + startPosition = i - 1; + } + htmlMode = false; + } else if (ch == '<' && fDocument.getChar(i) == '?' + && (fDocument.getChar(i + 1) == 'p' || fDocument.getChar(i + 1) == 'P') + && (fDocument.getChar(i + 2) == 'h' || fDocument.getChar(i + 2) == 'H') + && (fDocument.getChar(i + 3) == 'p' || fDocument.getChar(i + 3) == 'P')) { + length = i - startPosition - 1; + if (length != 0) { + initializeHTML(startPosition, length); + startPosition = i - 1; + } + htmlMode = false; + } + } else { + switch (ch) { + case '"': // double quoted string + // read until end of double quoted string + while (i < fDocument.getLength()) { + if (fDocument.getChar(i++) == '"') { + if (fDocument.getChar(i - 2) != '\\') { + break; + } + } + } + break; + case '\'': // single quoted string + // read until end of single quoted string + while (i < fDocument.getLength()) { + if (fDocument.getChar(i++) == '\'') { + if (fDocument.getChar(i - 2) != '\\') { + break; + } + } + } + break; + case '/': // line comment + if (fDocument.getChar(i) == '/') { + i++; + // read until end of line + while (i < fDocument.getLength()) { + if (fDocument.getChar(i++) == '\n') { + break; + } + } + } else if (fDocument.getChar(i) == '*') { + i++; + // read until end of comment + while (i < fDocument.getLength()) { + if (fDocument.getChar(i++) == '*') { + if (i < fDocument.getLength()) { + if (fDocument.getChar(i) == '/') { + break; + } + } + } + } + } + break; + case '#': // line comment + // read until end of line + while (i < fDocument.getLength()) { + if (fDocument.getChar(i++) == '\n') { + break; + } + } + break; + case '?': + if (fDocument.getChar(i) == '>') { + length = i - startPosition + 1; + if (length != 0) { + initializePHP(startPosition, length); + startPosition = i + 1; + } + htmlMode = true; + } + break; + } + } + } + } catch (BadLocationException x) { + // can happen but ignored + } finally { + if (startPositionoffset is smaller than the + * remembered offset, offset will from now on be remembered. If offset + length is greater than the + * remembered end offset, it will be remembered from now on. + * + * @param offset + * the offset + * @param length + * the length + */ + private void rememberRegion(int offset, int length) { + // remember start offset + if (fStartOffset == -1) + fStartOffset = offset; + else if (offset < fStartOffset) + fStartOffset = offset; + + // remember end offset + int endOffset = offset + length; + if (fEndOffset == -1) + fEndOffset = endOffset; + else if (endOffset > fEndOffset) + fEndOffset = endOffset; + } + + /** + * Remembers the given offset as the deletion offset. + * + * @param offset + * the offset + */ + private void rememberDeletedOffset(int offset) { + fDeleteOffset = offset; + } + + /** + * Creates the minimal region containing all partition changes using the remembered offset, end offset, and deletion offset. + * + * @return the minimal region containing all the partition changes + */ + private IRegion createRegion() { + if (fDeleteOffset == -1) { + if (fStartOffset == -1 || fEndOffset == -1) + return null; + return new Region(fStartOffset, fEndOffset - fStartOffset); + } else if (fStartOffset == -1 || fEndOffset == -1) { + return new Region(fDeleteOffset, 0); + } else { + int offset = Math.min(fDeleteOffset, fStartOffset); + int endOffset = Math.max(fDeleteOffset, fEndOffset); + return new Region(offset, endOffset - offset); + } + } + + /* + * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent) + * @since 2.0 + */ + public IRegion documentChanged2(DocumentEvent e) { + + try { + + IDocument d = e.getDocument(); + Position[] category = d.getPositions(fPositionCategory); + IRegion line = d.getLineInformationOfOffset(e.getOffset()); + int reparseStart = line.getOffset(); + int partitionStart = -1; + String contentType = null; + int newLength = e.getText() == null ? 0 : e.getText().length(); + + int first = d.computeIndexInCategory(fPositionCategory, reparseStart); + if (first > 0) { + TypedPosition partition = (TypedPosition) category[first - 1]; + if (partition.includes(reparseStart)) { + partitionStart = partition.getOffset(); + contentType = partition.getType(); + if (e.getOffset() == partition.getOffset() + partition.getLength()) + reparseStart = partitionStart; + --first; + } else if (reparseStart == e.getOffset() && reparseStart == partition.getOffset() + partition.getLength()) { + partitionStart = partition.getOffset(); + contentType = partition.getType(); + reparseStart = partitionStart; + --first; + } else { + partitionStart = partition.getOffset() + partition.getLength(); + contentType = IDocument.DEFAULT_CONTENT_TYPE; + } + } + + fPositionUpdater.update(e); + for (int i = first; i < category.length; i++) { + Position p = category[i]; + if (p.isDeleted) { + rememberDeletedOffset(e.getOffset()); + break; + } + } + category = d.getPositions(fPositionCategory); + + + fHTMLScanner.setPartialRange(d, reparseStart, d.getLength() - reparseStart, contentType, partitionStart); + + int lastScannedPosition = reparseStart; + IToken token = fHTMLScanner.nextToken(); + + while (!token.isEOF()) { + + contentType = getTokenContentType(token); + + if (!isSupportedContentType(contentType)) { + token = fHTMLScanner.nextToken(); + continue; + } + + int start = fHTMLScanner.getTokenOffset(); + int length = fHTMLScanner.getTokenLength(); + + lastScannedPosition = start + length - 1; + + // remove all affected positions + while (first < category.length) { + TypedPosition p = (TypedPosition) category[first]; + if (lastScannedPosition >= p.offset + p.length + || (p.overlapsWith(start, length) && (!d.containsPosition(fPositionCategory, start, length) || !contentType.equals(p + .getType())))) { + + rememberRegion(p.offset, p.length); + d.removePosition(fPositionCategory, p); + ++first; + + } else + break; + } + + // if position already exists and we have scanned at least the + // area covered by the event, we are done + if (d.containsPosition(fPositionCategory, start, length)) { + if (lastScannedPosition >= e.getOffset() + newLength) + return createRegion(); + ++first; + } else { + // insert the new type position + try { + d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); + rememberRegion(start, length); + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + } + + token = fHTMLScanner.nextToken(); + } + + // remove all positions behind lastScannedPosition since there aren't any further types + if (lastScannedPosition != reparseStart) { + // if this condition is not met, nothing has been scanned because of a deletion + ++lastScannedPosition; + } + first = d.computeIndexInCategory(fPositionCategory, lastScannedPosition); + + TypedPosition p; + while (first < category.length) { + p = (TypedPosition) category[first++]; + d.removePosition(fPositionCategory, p); + rememberRegion(p.offset, p.length); + } + + } catch (BadPositionCategoryException x) { + // should never happen on connected documents + } catch (BadLocationException x) { + } + + return createRegion(); + } + + /** + * Returns the position in the partitoner's position category which is close to the given offset. This is, the position has either + * an offset which is the same as the given offset or an offset which is smaller than the given offset. This method profits from + * the knowledge that a partitioning is a ordered set of disjoint position. + * + * @param offset + * the offset for which to search the closest position + * @return the closest position in the partitioner's category + */ + protected TypedPosition findClosestPosition(int offset) { + + try { + + int index = fDocument.computeIndexInCategory(fPositionCategory, offset); + Position[] category = fDocument.getPositions(fPositionCategory); + + if (category.length == 0) + return null; + + if (index < category.length) { + if (offset == category[index].offset) + return (TypedPosition) category[index]; + } + + if (index > 0) + index--; + + return (TypedPosition) category[index]; + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return null; + } + + /* + * @see IDocumentPartitioner#getContentType(int) + */ + public String getContentType(int offset) { + + TypedPosition p = findClosestPosition(offset); + if (p != null && p.includes(offset)) + return p.getType(); + + return IDocument.DEFAULT_CONTENT_TYPE; + } + + /* + * @see IDocumentPartitioner#getPartition(int) + */ + public ITypedRegion getPartition(int offset) { + + try { + + Position[] category = fDocument.getPositions(fPositionCategory); + + if (category == null || category.length == 0) + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + + int index = fDocument.computeIndexInCategory(fPositionCategory, offset); + + if (index < category.length) { + + TypedPosition next = (TypedPosition) category[index]; + + if (offset == next.offset) + return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); + + if (index == 0) + return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); + + TypedPosition previous = (TypedPosition) category[index - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset = previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + } + + TypedPosition previous = (TypedPosition) category[category.length - 1]; + if (previous.includes(offset)) + return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); + + int endOffset = previous.getOffset() + previous.getLength(); + return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); + + } catch (BadPositionCategoryException x) { + } catch (BadLocationException x) { + } + + return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); + } + + /* + * @see IDocumentPartitioner#computePartitioning(int, int) + */ + public ITypedRegion[] computePartitioning(int offset, int length) { + return computePartitioning(offset, length, false); + } + + /* + * @see IDocumentPartitioner#getLegalContentTypes() + */ + public String[] getLegalContentTypes() { + return fLegalContentTypes; + } + + public String[] getLegalHTMLContentTypes() { + return fLegalHTMLContentTypes; + } + + public String[] getLegalPHPContentTypes() { + return fLegalPHPContentTypes; + } + + /** + * Returns whether the given type is one of the legal content types. + * + * @param contentType + * the content type to check + * @return true if the content type is a legal content type + */ + protected boolean isSupportedContentType(String contentType) { + if (contentType != null) { + for (int i = 0; i < fLegalContentTypes.length; i++) { + if (fLegalHTMLContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns whether the given type is one of the legal content types. + * + * @param contentType + * the content type to check + * @return true if the content type is a legal content type + */ + protected boolean isSupportedHTMLContentType(String contentType) { + if (contentType != null) { + for (int i = 0; i < fLegalHTMLContentTypes.length; i++) { + if (fLegalHTMLContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns whether the given type is one of the legal content types. + * + * @param contentType + * the content type to check + * @return true if the content type is a legal content type + */ + protected boolean isSupportedPHPContentType(String contentType) { + if (contentType != null) { + for (int i = 0; i < fLegalHTMLContentTypes.length; i++) { + if (fLegalHTMLContentTypes[i].equals(contentType)) + return true; + } + } + + return false; + } + + /** + * Returns a content type encoded in the given token. If the token's data is not null and a string it is assumed + * that it is the encoded content type. + * + * @param token + * the token whose content type is to be determined + * @return the token's content type + */ + protected String getTokenContentType(IToken token) { + Object data = token.getData(); + if (data instanceof String) + return (String) data; + return null; + } + + /* zero-length partition support */ + + /* + * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getContentType(int) + * @since 3.0 + */ + public String getContentType(int offset, boolean preferOpenPartitions) { + return getPartition(offset, preferOpenPartitions).getType(); + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getPartition(int) + * @since 3.0 + */ + public ITypedRegion getPartition(int offset, boolean preferOpenPartitions) { + ITypedRegion region = getPartition(offset); + if (preferOpenPartitions) { + if (region.getOffset() == offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { + if (offset > 0) { + region = getPartition(offset - 1); + if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) + return region; + } + return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); + } + } + return region; + } + + /* + * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int, boolean) + * @since 3.0 + */ + public ITypedRegion[] computePartitioning(int offset, int length, boolean includeZeroLengthPartitions) { + List list = new ArrayList(); + + try { + + int endOffset = offset + length; + + Position[] category = fDocument.getPositions(fPositionCategory); + + TypedPosition previous = null, current = null; + int start, end, gapOffset; + Position gap = new Position(0); + + int startIndex = getFirstIndexEndingAfterOffset(category, offset); + int endIndex = getFirstIndexStartingAfterOffset(category, endOffset); + for (int i = startIndex; i < endIndex; i++) { + + current = (TypedPosition) category[i]; + + gapOffset = (previous != null) ? previous.getOffset() + previous.getLength() : 0; + gap.setOffset(gapOffset); + gap.setLength(current.getOffset() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) + || (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start = Math.max(offset, gapOffset); + end = Math.min(endOffset, gap.getOffset() + gap.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + + if (current.overlapsWith(offset, length)) { + start = Math.max(offset, current.getOffset()); + end = Math.min(endOffset, current.getOffset() + current.getLength()); + list.add(new TypedRegion(start, end - start, current.getType())); + } + + previous = current; + } + + if (previous != null) { + gapOffset = previous.getOffset() + previous.getLength(); + gap.setOffset(gapOffset); + gap.setLength(fDocument.getLength() - gapOffset); + if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) + || (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { + start = Math.max(offset, gapOffset); + end = Math.min(endOffset, fDocument.getLength()); + list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); + } + } + + if (list.isEmpty()) + list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); + + } catch (BadPositionCategoryException x) { + } + + TypedRegion[] result = new TypedRegion[list.size()]; + list.toArray(result); + return result; + } + + /** + * Returns true if the given ranges overlap with or touch each other. + * + * @param gap + * the first range + * @param offset + * the offset of the second range + * @param length + * the length of the second range + * @return true if the given ranges overlap with or touch each other + * @since 3.0 + */ + private boolean overlapsOrTouches(Position gap, int offset, int length) { + return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength(); + } + + /** + * Returns the index of the first position which ends after the given offset. + * + * @param positions + * the positions in linear order + * @param offset + * the offset + * @return the index of the first position which ends after the offset + * + * @since 3.0 + */ + private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) { + int i = -1, j = positions.length; + while (j - i > 1) { + int k = (i + j) >> 1; + Position p = positions[k]; + if (p.getOffset() + p.getLength() > offset) + j = k; + else + i = k; + } + return j; + } + + /** + * Returns the index of the first position which starts at or after the given offset. + * + * @param positions + * the positions in linear order + * @param offset + * the offset + * @return the index of the first position which starts after the offset + * + * @since 3.0 + */ + private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) { + int i = -1, j = positions.length; + while (j - i > 1) { + int k = (i + j) >> 1; + Position p = positions[k]; + if (p.getOffset() >= offset) + j = k; + else + i = k; + } + return j; + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java new file mode 100644 index 0000000..26a0bcf --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java @@ -0,0 +1,436 @@ +/** + * This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * Created on 05.03.2003 + * + * @author Stefan Langer (musk) + * @version $Revision: 1.1 $ + */ +package net.sourceforge.phpeclipse.phpeditor.php; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpdt.internal.ui.text.*; + +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IPartitionTokenScanner; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; + +/** + * + */ +public class HTMLPartitionScanner implements IPartitionTokenScanner { + private static final boolean DEBUG = false; + + private boolean fInString = false; + private boolean fInDoubString = false; + private IDocument fDocument = null; + private int fOffset = -1; + private String fContentType = IPHPPartitions.HTML; + private String fPrevContentType = IPHPPartitions.HTML; + private boolean partitionBorder = false; + private int fTokenOffset; + private int fEnd = -1; + private int fLength; + private int fCurrentLength; + private int fFileType; + private Map tokens = new HashMap(); + + public HTMLPartitionScanner() { + this(IPHPPartitions.PHP_FILE); + } + + public HTMLPartitionScanner(int fileType) { + this.tokens.put(IPHPPartitions.HTML, new Token(IPHPPartitions.HTML)); + this.tokens.put( + IPHPPartitions.HTML_MULTILINE_COMMENT, + new Token(IPHPPartitions.HTML_MULTILINE_COMMENT)); + + this.tokens.put(IPHPPartitions.SMARTY, new Token(IPHPPartitions.SMARTY)); + this.tokens.put( + IPHPPartitions.SMARTY_MULTILINE_COMMENT, + new Token(IPHPPartitions.SMARTY_MULTILINE_COMMENT)); + + this.tokens.put(IDocument.DEFAULT_CONTENT_TYPE, new Token(IDocument.DEFAULT_CONTENT_TYPE)); + fFileType = fileType; + } + + private IToken getToken(String type) { + fLength = fCurrentLength; + if (DEBUG) { + + try { + if (fLength <= 0) { + int line = fDocument.getLineOfOffset(fOffset); + System.err.println("Error at " + line + " offset:" + String.valueOf(fOffset - fDocument.getLineOffset(line))); + } + } catch (BadLocationException e) { // should never happen + // TODO Write stacktrace to log + e.printStackTrace(); + } + } + Assert.isTrue(fLength > 0, "Partition length <= 0!"); + fCurrentLength = 0; + // String can never cross partition borders so reset string detection + fInString = false; + fInDoubString = false; + IToken token = (IToken) this.tokens.get(type); + Assert.isNotNull(token, "Token for type \"" + type + "\" not found!"); + if (DEBUG) { + System.out.println("Partition: fTokenOffset=" + fTokenOffset + " fContentType=" + type + " fLength=" + fLength); + } + return token; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int) + */ + public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { + if (DEBUG) { + System.out.println("*****"); + System.out.println("PartialRange: contentType=" + contentType + " partitionOffset=" + partitionOffset); + } + + try { + if (partitionOffset > -1) { + partitionBorder = false; + // because of strings we have to parse the whole partition + this.setRange(document, partitionOffset, offset - partitionOffset + length); + // sometimes we get a wrong partition so we retrieve the partition + // directly from the document + fContentType = fDocument.getContentType(partitionOffset); + } else + this.setRange(document, offset, length); + + } catch (BadLocationException e) { + // should never happen + // TODO print stack trace to log + // fall back just scan the whole document again + this.setRange(document, 0, fDocument.getLength()); + } + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength() + */ + public int getTokenLength() { + return fLength; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + return fTokenOffset; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() + */ + public IToken nextToken() { + int c; + + // check if we are not allready at the end of the + // file + if ((c = read()) == ICharacterScanner.EOF) { + partitionBorder = false; + return Token.EOF; + } else + unread(); + + if (partitionBorder) { + fTokenOffset = fOffset; + partitionBorder = false; + } + + while ((c = read()) != ICharacterScanner.EOF) { + switch (c) { + case '<' : + if ( checkPattern(new char[] { '!', '-', '-' })) { // return previouse partition + if (fContentType != IPHPPartitions.HTML_MULTILINE_COMMENT && fCurrentLength > 4) { + unread(4); + IToken token = getToken(fContentType); + fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT; + return token; + } else + fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT; + + fTokenOffset = fOffset - 4; + fCurrentLength = 4; + } + break; + case '-' : + if (fContentType == IPHPPartitions.HTML_MULTILINE_COMMENT + && checkPattern(new char[] { '-', '>' })) { + fContentType = IPHPPartitions.HTML; + partitionBorder = true; + return getToken(IPHPPartitions.HTML_MULTILINE_COMMENT); + } + break; + case '{' : // SMARTY code starts here ? + if (fFileType == IPHPPartitions.SMARTY_FILE) { + if ((c = read()) == '*') { + if (DEBUG) { + System.out.println( + "SMARTYDOC_TOKEN start " + + fTokenOffset + + " fContentType=" + + fContentType + + " fLength=" + + fLength + + " fOffset=" + + fOffset + + " fCurrentLength=" + + fCurrentLength); + } + if (fContentType != IPHPPartitions.SMARTY_MULTILINE_COMMENT && fCurrentLength > 2) { + // SMARTY doc code starts here + unread(2); + IToken token = getToken(fContentType); + fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT; + return token; + // } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset == 2) { + // fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT; + } else { // if (fContentType == IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT) { + fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT; + fTokenOffset = fOffset - 2; + fCurrentLength = 2; + } + break; + } + if (DEBUG) { + System.out.println( + "SMARTY_TOKEN start " + + fTokenOffset + + " fContentType=" + + fContentType + + " fLength=" + + fLength + + " fOffset=" + + fOffset); + } + if (c != ICharacterScanner.EOF) { + unread(); + } + if (fContentType != IPHPPartitions.SMARTY && fCurrentLength > 1) { + unread(1); + IToken token = getToken(fContentType); + fContentType = IPHPPartitions.SMARTY; + return token; + // } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset==1) { + // fContentType = IPHPPartitionScannerConstants.SMARTY; + } else { + fContentType = IPHPPartitions.SMARTY; + fTokenOffset = fOffset - 1; + fCurrentLength = 1; + } + } + break; + case '}' : // SMARTY code ends here ? + if (fFileType == IPHPPartitions.SMARTY_FILE && fContentType == IPHPPartitions.SMARTY) { + if (DEBUG) { + System.out.println( + "SMARTY_TOKEN end " + + fTokenOffset + + " fContentType=" + + fContentType + + " fLength=" + + fLength + + " fOffset=" + + fOffset); + } + fContentType = IPHPPartitions.HTML; + partitionBorder = true; + return getToken(IPHPPartitions.SMARTY); + } + break; +// case '/' : +// if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read()) == '*') { // MULTINE COMMENT JAVASCRIPT, CSS, PHP +// if (fContentType == IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 2) { +// unread(2); +// IToken token = getToken(fContentType); +// fContentType = IPHPPartitions.PHP_PHPDOC_COMMENT; +// return token; +// } else if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) { +// fTokenOffset = fOffset - 2; +// fCurrentLength = 2; +// } +// +// } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c != ICharacterScanner.EOF) +// unread(); +// break; + case '*' : + if (fFileType == IPHPPartitions.SMARTY_FILE && (c = read()) == '}') { + if (DEBUG) { + System.out.println( + "SMARTYDOC_TOKEN end " + + fTokenOffset + + " fContentType=" + + fContentType + + " fLength=" + + fLength + + " fOffset=" + + fOffset); + } + if (fContentType == IPHPPartitions.SMARTY_MULTILINE_COMMENT) { + fContentType = IPHPPartitions.HTML; + partitionBorder = true; + return getToken(IPHPPartitions.SMARTY_MULTILINE_COMMENT); + } + } + break; + case '\'' : + if (!fInDoubString) + fInString = !fInString; + break; + case '"' : + // toggle String mode + if (!fInString) + fInDoubString = !fInDoubString; + break; + } + } // end of file reached but we have to return the + // last partition. + return getToken(fContentType); + } + /* (non-Javadoc) + * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + if (DEBUG) { + System.out.println("SET RANGE: offset=" + offset + " length=" + length); + } + + fDocument = document; + fOffset = offset; + fTokenOffset = offset; + fCurrentLength = 0; + fLength = 0; + fEnd = fOffset + length; + fInString = false; + fInDoubString = false; + fContentType = IPHPPartitions.HTML; + // String[] prev = getPartitionStack(offset); + } + + private int read() { + try { + if (fOffset < fEnd) { + fCurrentLength++; + return fDocument.getChar(fOffset++); + } + return ICharacterScanner.EOF; + } catch (BadLocationException e) { + // should never happen + // TODO write stacktrace to log + fOffset = fEnd; + return ICharacterScanner.EOF; + } + } + + private void unread() { + --fOffset; + --fCurrentLength; + } + + private void unread(int num) { + fOffset -= num; + fCurrentLength -= num; + } + + private boolean checkPattern(char[] pattern) { + return checkPattern(pattern, false); + } + + /** + * Check if next character sequence read from document is equals to + * the provided pattern. Pattern is read from left to right until the + * first character read doesn't match. If this happens all read characters are + * unread. + * @param pattern The pattern to check. + * @return true if pattern is equals else returns false. + */ + private boolean checkPattern(char[] pattern, boolean ignoreCase) { + int prevOffset = fOffset; + int prevLength = fCurrentLength; + for (int i = 0; i < pattern.length; i++) { + int c = read(); + + if (c == ICharacterScanner.EOF || !letterEquals(c, pattern[i], ignoreCase)) { + fOffset = prevOffset; + fCurrentLength = prevLength; + return false; + } + } + + return true; + } + + private boolean letterEquals(int test, char letter, boolean ignoreCase) { + if (test == letter) + return true; + else if (ignoreCase && Character.isLowerCase(letter) && test == Character.toUpperCase(letter)) + return true; + else if (ignoreCase && Character.isUpperCase(letter) && test == Character.toLowerCase(letter)) + return true; + + return false; + } + + /** + * Checks wether the offset is in a String and the specified + * contenttype is the current content type. + * Strings are delimited, mutual exclusive, by a " or by a '. + * + * @param contentType The contenttype to check. + * @return true if the current offset is in a string else + * returns false. + */ + private boolean isInString(String contentType) { + if (fContentType == contentType) + return (fInString || fInDoubString); + else + return false; + } + + /** + * Returns the previouse partition stack for the given offset. + * + * @param offset The offset to return the previouse partitionstack for. + * + * @return The stack as a string array. + */ + private String[] getPartitionStack(int offset) { + ArrayList types = new ArrayList(); + int tmpOffset = 0; + try { + ITypedRegion region = fDocument.getPartition(offset); + tmpOffset = region.getOffset(); + while (tmpOffset - 1 > 0) { + region = fDocument.getPartition(tmpOffset - 1); + tmpOffset = region.getOffset(); + types.add(0, region.getType()); + } + } catch (BadLocationException e) { + if (DEBUG) { + e.printStackTrace(); + } + } + + String[] retVal = new String[types.size()]; + + retVal = (String[]) types.toArray(retVal); + return retVal; + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java index 0e657f7..5e324f1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java @@ -15,7 +15,6 @@ import java.util.ArrayList; import java.util.List; import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner; -import net.sourceforge.phpdt.internal.ui.text.CombinedWordRule; import net.sourceforge.phpdt.ui.text.IColorManager; import net.sourceforge.phpeclipse.IPreferenceConstants; import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr; @@ -428,8 +427,8 @@ public class PHPCodeScanner extends AbstractJavaScanner { wordRule.addWord("return", token); // Add rule for operators and brackets (at the end !) - token= getToken(IPreferenceConstants.PHP_OPERATOR); - rules.add(new OperatorRule(token)); + token= getToken(IPreferenceConstants.PHP_OPERATOR); + rules.add(new OperatorRule(token)); rules.add(wordRule); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java index a38b36d..8ea69f7 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java @@ -589,7 +589,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor { IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault() .getIndexManager(project); SortedMap sortedMap = indexManager.getIdentifierMap(); - declarationEngine = new DeclarationEngine(contextType, + declarationEngine = new DeclarationEngine(project, contextType, lastSignificantToken, file); declarationEngine.complete(viewer, offset, sortedMap); declarationResults = declarationEngine.getResults(); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java new file mode 100644 index 0000000..c408f3b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java @@ -0,0 +1,93 @@ +/********************************************************************** +Copyright (c) 2002 Widespace, OU and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://solareclipse.sourceforge.net/legal/cpl-v10.html + +Contributors: + Igor Malinin - initial contribution + +$Id: PHPDocumentPartitioner.java,v 1.1 2004-09-02 18:32:34 jsurfer Exp $ +**********************************************************************/ +package net.sourceforge.phpeclipse.phpeditor.php; + +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.ui.text.rules.FlatNode; +import net.sourceforge.phpeclipse.ui.text.rules.MultiViewPartitioner; +import net.sourceforge.phpeclipse.ui.text.rules.ViewNode; + +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentPartitioner; +import org.eclipse.jface.text.rules.IPartitionTokenScanner; + + +/** + * + * + * @author Igor Malinin + */ +public class PHPDocumentPartitioner extends MultiViewPartitioner { + public static final String PHP_TEMPLATE_DATA = "__php_template_data"; + public static final String PHP_SCRIPT_CODE = "__php_script_code"; + + private IPartitionTokenScanner scriptScanner; + + public PHPDocumentPartitioner( + IPartitionTokenScanner scanner, IPartitionTokenScanner scriptScanner + ) { + super(scanner); + + this.scriptScanner = scriptScanner; + } + + protected FlatNode createNode(String type, int offset, int length) { + if (type.equals(PHPPartitionScanner.PHP_SCRIPTING_AREA) + ) { + if (DEBUG) { + Assert.isTrue(offset>=0); + } + ViewNode node = new ViewNode(type); + node.offset = offset; + node.length = length; + return node; + } + + return super.createNode(type, offset, length); + } + + /* + * @see net.sf.solareclipse.text.rules.DocumentViewPartitioner#createPartitioner(String) + */ + protected IDocumentPartitioner createPartitioner(String contentType) { + if (contentType == null) { +// return JavaTextTools.createHTMLPartitioner(); + return PHPeclipsePlugin.getDefault().getJavaTextTools() + .getXMLTextTools().createXMLPartitioner(); + } + + if (contentType.equals(PHPPartitionScanner.PHP_SCRIPTING_AREA) + ) { + return PHPeclipsePlugin.getDefault().getJavaTextTools().createPHPPartitioner(); + } + return null; + } + + /* + * @see net.sf.solareclipse.text.rules.DocumentViewPartitioner#getContentType(String, String) + */ + protected String getContentType(String parent, String view) { + if (parent == null) { + if (view == IDocument.DEFAULT_CONTENT_TYPE) { + return PHP_TEMPLATE_DATA; + } + } else { + if (view == IDocument.DEFAULT_CONTENT_TYPE) { + return PHP_SCRIPT_CODE; + } + } + + return super.getContentType(parent, view); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java index 2cb2eb9..8d0de49 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java @@ -1,25 +1,26 @@ -/** - * This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * Created on 05.03.2003 - * - * @author Stefan Langer (musk) - * @version $Revision: 1.24 $ - */ +/********************************************************************** + Copyright (c) 2002 Widespace, OU and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Common Public License v1.0 + which accompanies this distribution, and is available at + http://solareclipse.sourceforge.net/legal/cpl-v10.html + + Contributors: + Igor Malinin - initial contribution + + $Id: PHPPartitionScanner.java,v 1.25 2004-09-02 18:32:34 jsurfer Exp $ + **********************************************************************/ package net.sourceforge.phpeclipse.phpeditor.php; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import net.sourceforge.phpdt.internal.ui.text.*; +import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner; +import org.eclipse.core.internal.indexing.AbstractPagePolicy; import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IPartitionTokenScanner; import org.eclipse.jface.text.rules.IToken; @@ -27,478 +28,362 @@ import org.eclipse.jface.text.rules.Token; /** * + * + * @author Igor Malinin */ public class PHPPartitionScanner implements IPartitionTokenScanner { - private static final boolean DEBUG = false; - - private boolean fInString = false; - private boolean fInDoubString = false; - private IDocument fDocument = null; - private int fOffset = -1; - private String fContentType = IPHPPartitions.HTML; - private String fPrevContentType = IPHPPartitions.HTML; - private boolean partitionBorder = false; - private int fTokenOffset; - private int fEnd = -1; - private int fLength; - private int fCurrentLength; - private int fFileType; - private Map tokens = new HashMap(); + // public static final String JSP_DIRECTIVE = "__jsp_directive"; + // public static final String JSP_COMMENT = "__jsp_comment"; + //// public static final String JSP_TAG = "__jsp_tag"; + // public static final String JSP_DECLARATION = "__jsp_declaration"; + public static final String PHP_SCRIPTING_AREA = "__php_scripting_area "; - public PHPPartitionScanner() { - this(IPHPPartitions.PHP_FILE); - } - - public PHPPartitionScanner(int fileType) { - this.tokens.put(IPHPPartitions.PHP_PARTITIONING, new Token(IPHPPartitions.PHP_PARTITIONING)); - this.tokens.put(IPHPPartitions.PHP_STRING_DQ, new Token(IPHPPartitions.PHP_STRING_DQ)); - this.tokens.put( - IPHPPartitions.PHP_PHPDOC_COMMENT, - new Token(IPHPPartitions.PHP_PHPDOC_COMMENT)); - this.tokens.put(IPHPPartitions.HTML, new Token(IPHPPartitions.HTML)); - this.tokens.put( - IPHPPartitions.HTML_MULTILINE_COMMENT, - new Token(IPHPPartitions.HTML_MULTILINE_COMMENT)); - - this.tokens.put(IPHPPartitions.SMARTY, new Token(IPHPPartitions.SMARTY)); - this.tokens.put( - IPHPPartitions.SMARTY_MULTILINE_COMMENT, - new Token(IPHPPartitions.SMARTY_MULTILINE_COMMENT)); - - this.tokens.put(IDocument.DEFAULT_CONTENT_TYPE, new Token(IDocument.DEFAULT_CONTENT_TYPE)); - fFileType = fileType; - } + // public static final String JSP_EXPRESSION = "__jsp_expression"; - private IToken getToken(String type) { - fLength = fCurrentLength; - if (DEBUG) { + public static final int STATE_DEFAULT = 0; - try { - if (fLength <= 0) { - int line = fDocument.getLineOfOffset(fOffset); - System.err.println("Error at " + line + " offset:" + String.valueOf(fOffset - fDocument.getLineOffset(line))); - } - } catch (BadLocationException e) { // should never happen - // TODO Write stacktrace to log - e.printStackTrace(); - } - } - Assert.isTrue(fLength > 0, "Partition length <= 0!"); - fCurrentLength = 0; - // String can never cross partition borders so reset string detection - fInString = false; - fInDoubString = false; - IToken token = (IToken) this.tokens.get(type); - Assert.isNotNull(token, "Token for type \"" + type + "\" not found!"); - if (DEBUG) { - System.out.println("Partition: fTokenOffset=" + fTokenOffset + " fContentType=" + type + " fLength=" + fLength); - } - return token; - } + // public static final int STATE_TAG = 1; + // public static final int STATE_SCRIPT = 2; - /* (non-Javadoc) - * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int) - */ - public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { - if (DEBUG) { - System.out.println("*****"); - System.out.println("PartialRange: contentType=" + contentType + " partitionOffset=" + partitionOffset); - } + private IDocument document; - try { - if (partitionOffset > -1) { - partitionBorder = false; - // because of strings we have to parse the whole partition - this.setRange(document, partitionOffset, offset - partitionOffset + length); - // sometimes we get a wrong partition so we retrieve the partition - // directly from the document - fContentType = fDocument.getContentType(partitionOffset); - } else - this.setRange(document, offset, length); + private int begin; - } catch (BadLocationException e) { - // should never happen - // TODO print stack trace to log - // fall back just scan the whole document again - this.setRange(document, 0, fDocument.getLength()); - } + private int end; - } + private int offset; - /* (non-Javadoc) - * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength() - */ - public int getTokenLength() { - return fLength; - } + private int length; - /* (non-Javadoc) - * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset() - */ - public int getTokenOffset() { - return fTokenOffset; + private int position; + + private int state; + + private Map tokens = new HashMap(); + + public PHPPartitionScanner() { } - /* (non-Javadoc) + /* * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() */ public IToken nextToken() { - int c; + offset += length; + + /* + * switch (state) { case STATE_TAG: return nextTagToken(); } + */ + + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(null); + + case '<': + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(null); + + case '?': // <%SCRIPLET <%@DIRECTIVE <%!DECLARATION <%=EXPRESSION <%--COMMENT + int ch = read(); + // if (Character.isWhitespace((char)ch)) { + // return nextJSPToken(PHP_SCRIPTING_AREA); + // } + switch (ch) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(PHP_SCRIPTING_AREA); + + // case '-': // <%- <%--COMMENT + // switch (read()) { + // case ICharacterScanner.EOF: + // case '-': // <%-- + // return nextCommentToken(); + // } + // + // break; + } - // check if we are not allready at the end of the - // file - if ((c = read()) == ICharacterScanner.EOF) { - partitionBorder = false; - return Token.EOF; - } else - unread(); + return scanUntilPHPEndToken(PHP_SCRIPTING_AREA); + } - if (partitionBorder) { - fTokenOffset = fOffset; - partitionBorder = false; + unread(); } - while ((c = read()) != ICharacterScanner.EOF) { - switch (c) { - case '<' : - if (!isInString(IPHPPartitions.PHP_PARTITIONING) - && fContentType != IPHPPartitions.PHP_PHPDOC_COMMENT - && checkPattern(new char[] { '?', 'p', 'h', 'p' }, true)) { - if (fContentType != IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 5) { - unread(5); - IToken token = getToken(fContentType); - // save previouse contenttype - //TODO build stack for previouse contenttype - fPrevContentType = fContentType; - - fContentType = IPHPPartitions.PHP_PARTITIONING; - - return token; - } else - fContentType = IPHPPartitions.PHP_PARTITIONING; - - // remember offset of this partition - fTokenOffset = fOffset - 5; - fCurrentLength = 5; - } else if ( - !isInString(IPHPPartitions.PHP_PARTITIONING) - && fContentType != IPHPPartitions.PHP_PHPDOC_COMMENT - && checkPattern(new char[] { '?' }, false)) { - if (fContentType != IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 2) { - unread(2); - IToken token = getToken(fContentType); - // save previouse contenttype - fPrevContentType = fContentType; - fContentType = IPHPPartitions.PHP_PARTITIONING; - return token; - } else - fContentType = IPHPPartitions.PHP_PARTITIONING; - // remember offset of this partition - fTokenOffset = fOffset - 2; - fCurrentLength = 2; - } else if ( - !isInString(IPHPPartitions.PHP_PARTITIONING) - && (fContentType != IPHPPartitions.PHP_PARTITIONING) // BUG #769044 - && (fContentType != IPHPPartitions.PHP_PHPDOC_COMMENT) // BUG #769044 - && checkPattern(new char[] { '!', '-', '-' })) { // return previouse partition - if (fContentType != IPHPPartitions.HTML_MULTILINE_COMMENT && fCurrentLength > 4) { - unread(4); - IToken token = getToken(fContentType); - fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT; - return token; - } else - fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT; - - fTokenOffset = fOffset - 4; - fCurrentLength = 4; - } - break; - case '?' : - if (!isInString(IPHPPartitions.PHP_PARTITIONING) && fContentType == IPHPPartitions.PHP_PARTITIONING) { - if ((c = read()) == '>') { - if (fPrevContentType != null) - fContentType = fPrevContentType; - else - fContentType = IPHPPartitions.HTML; - partitionBorder = true; - return getToken(IPHPPartitions.PHP_PARTITIONING); - } else if (c != ICharacterScanner.EOF) - unread(); - } - break; - case '-' : - if (!isInString(IPHPPartitions.PHP_PARTITIONING) - && fContentType == IPHPPartitions.HTML_MULTILINE_COMMENT - && checkPattern(new char[] { '-', '>' })) { - fContentType = IPHPPartitions.HTML; - partitionBorder = true; - return getToken(IPHPPartitions.HTML_MULTILINE_COMMENT); - } - break; - case '{' : // SMARTY code starts here ? - if (fFileType == IPHPPartitions.SMARTY_FILE) { - if ((c = read()) == '*') { - if (DEBUG) { - System.out.println( - "SMARTYDOC_TOKEN start " - + fTokenOffset - + " fContentType=" - + fContentType - + " fLength=" - + fLength - + " fOffset=" - + fOffset - + " fCurrentLength=" - + fCurrentLength); - } - if (fContentType != IPHPPartitions.SMARTY_MULTILINE_COMMENT && fCurrentLength > 2) { - // SMARTY doc code starts here - unread(2); - IToken token = getToken(fContentType); - fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT; - return token; - // } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset == 2) { - // fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT; - } else { // if (fContentType == IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT) { - fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT; - fTokenOffset = fOffset - 2; - fCurrentLength = 2; - } - break; - } - if (DEBUG) { - System.out.println( - "SMARTY_TOKEN start " - + fTokenOffset - + " fContentType=" - + fContentType - + " fLength=" - + fLength - + " fOffset=" - + fOffset); - } - if (c != ICharacterScanner.EOF) { - unread(); - } - if (fContentType != IPHPPartitions.SMARTY && fCurrentLength > 1) { - unread(1); - IToken token = getToken(fContentType); - fContentType = IPHPPartitions.SMARTY; - return token; - // } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset==1) { - // fContentType = IPHPPartitionScannerConstants.SMARTY; - } else { - fContentType = IPHPPartitions.SMARTY; - fTokenOffset = fOffset - 1; - fCurrentLength = 1; - } - } - break; - case '}' : // SMARTY code ends here ? - if (fFileType == IPHPPartitions.SMARTY_FILE && fContentType == IPHPPartitions.SMARTY) { - if (DEBUG) { - System.out.println( - "SMARTY_TOKEN end " - + fTokenOffset - + " fContentType=" - + fContentType - + " fLength=" - + fLength - + " fOffset=" - + fOffset); - } - fContentType = IPHPPartitions.HTML; - partitionBorder = true; - return getToken(IPHPPartitions.SMARTY); - } - break; - case '/' : - if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read()) == '*') { // MULTINE COMMENT JAVASCRIPT, CSS, PHP - if (fContentType == IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 2) { - unread(2); - IToken token = getToken(fContentType); - fContentType = IPHPPartitions.PHP_PHPDOC_COMMENT; - return token; - } else if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) { - fTokenOffset = fOffset - 2; - fCurrentLength = 2; - } - - } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c != ICharacterScanner.EOF) - unread(); + loop: while (true) { + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(null); + + case '<': + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(null); + + case '?': + unread(); break; - case '*' : - if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read()) == '/') { - if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) { - fContentType = IPHPPartitions.PHP_PARTITIONING; - partitionBorder = true; - return getToken(IPHPPartitions.PHP_PHPDOC_COMMENT); - } else if (fContentType == IPHPPartitions.CSS_MULTILINE_COMMENT) { - } else if (fContentType == IPHPPartitions.JS_MULTILINE_COMMENT) { - } - } else if (fFileType == IPHPPartitions.SMARTY_FILE && (c = read()) == '}') { - if (DEBUG) { - System.out.println( - "SMARTYDOC_TOKEN end " - + fTokenOffset - + " fContentType=" - + fContentType - + " fLength=" - + fLength - + " fOffset=" - + fOffset); - } - if (fContentType == IPHPPartitions.SMARTY_MULTILINE_COMMENT) { - fContentType = IPHPPartitions.HTML; - partitionBorder = true; - return getToken(IPHPPartitions.SMARTY_MULTILINE_COMMENT); - } - } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c != ICharacterScanner.EOF) { - unread(); - } + + case '<': + unread(); + + default: + continue loop; + } + + unread(); + + state = STATE_DEFAULT; + return getToken(null); + } + } + } + + private IToken scanUntilPHPEndToken(String token) { + int ch = read(); + while (true) { + switch (ch) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(token); + case '"': // double quoted string + // read until end of double quoted string + readUntilEscaped('"'); + break; + case '\'': // single quoted string + // read until end of single quoted string + readUntilEscaped('\''); + break; + case '/': // comment start? + ch = read(); + switch (ch) { + case ICharacterScanner.EOF: break; - case '\'' : - if (!fInDoubString) - fInString = !fInString; + case '/': + // read until end of line + readSingleLine(); break; - case '"' : - // toggle String mode - if (!fInString) - fInDoubString = !fInDoubString; + case '*': + // read until end of comment + readMultiLineComment(); break; + default: + continue; + } + break; + case '#': // line comment + // read until end of line + readSingleLine(); + break; + case '?': + ch = read(); + switch (ch) { + case ICharacterScanner.EOF: + case '>': + state = STATE_DEFAULT; + return getToken(token); + + case '?': + continue; + } } - } // end of file reached but we have to return the - // last partition. - return getToken(fContentType); + + ch = read(); + } } - /* (non-Javadoc) - * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int) - */ - public void setRange(IDocument document, int offset, int length) { - if (DEBUG) { - System.out.println("SET RANGE: offset=" + offset + " length=" + length); + + // private IToken nextCommentToken() { + // int ch = read(); + // loop: while (true) { + // switch (ch) { + // case ICharacterScanner.EOF: + // break loop; + // + // case '-': // - --%> + // ch = read(); + // switch (ch) { + // case ICharacterScanner.EOF: + // break loop; + // + // case '-': // -- --%> + // ch = read(); + // switch (ch) { + // case ICharacterScanner.EOF: + // break loop; + // + // case '%': // --% --%> + // ch = read(); + // switch (ch) { + // case ICharacterScanner.EOF: + // case '>': + // break loop; + // } + // + // continue loop; + // + // case '-': // --- ---%> + // unread(); + // continue loop; + // } + // + // ch = read(); + // continue loop; + // } + // } + // + // ch = read(); + // } + // + // return getToken(JSP_COMMENT); + // } + + private IToken getToken(String type) { + length = position - offset; + + if (length == 0) { + return Token.EOF; + } + + if (type == null) { + return Token.UNDEFINED; + } + + IToken token = (IToken) tokens.get(type); + if (token == null) { + token = new Token(type); + tokens.put(type, token); } - fDocument = document; - fOffset = offset; - fTokenOffset = offset; - fCurrentLength = 0; - fLength = 0; - fEnd = fOffset + length; - fInString = false; - fInDoubString = false; - fContentType = IPHPPartitions.HTML; - // String[] prev = getPartitionStack(offset); + return token; } private int read() { - try { - if (fOffset < fEnd) { - fCurrentLength++; - return fDocument.getChar(fOffset++); - } + if (position >= end) { return ICharacterScanner.EOF; + } + + try { + return document.getChar(position++); } catch (BadLocationException e) { - // should never happen - // TODO write stacktrace to log - fOffset = fEnd; + --position; return ICharacterScanner.EOF; } } - private void unread() { - --fOffset; - --fCurrentLength; + private void readUntilEscaped(char ch) { + if (position >= end) { + return; + } + try { + while (true) { + if (document.getChar(position++) == ch) { + if (position < 2 || document.getChar(position - 2) != '\\') { + break; + } + } + } + } catch (BadLocationException e) { + --position; + return; + } } - private void unread(int num) { - fOffset -= num; - fCurrentLength -= num; - } + private void readSingleLine() { + if (position >= end) { + return; + } + try { + while (document.getChar(position++) != '\n') { - private boolean checkPattern(char[] pattern) { - return checkPattern(pattern, false); + } + } catch (BadLocationException e) { + --position; + return; + } } - /** - * Check if next character sequence read from document is equals to - * the provided pattern. Pattern is read from left to right until the - * first character read doesn't match. If this happens all read characters are - * unread. - * @param pattern The pattern to check. - * @return true if pattern is equals else returns false. - */ - private boolean checkPattern(char[] pattern, boolean ignoreCase) { - int prevOffset = fOffset; - int prevLength = fCurrentLength; - for (int i = 0; i < pattern.length; i++) { - int c = read(); - - if (c == ICharacterScanner.EOF || !letterEquals(c, pattern[i], ignoreCase)) { - fOffset = prevOffset; - fCurrentLength = prevLength; - return false; + private void readMultiLineComment() { + if (position >= end) { + return; + } + try { + char ch; + while (true) { + ch = document.getChar(position++); + if (ch == '*') { + if (document.getChar(position) == '/') { + position++; + break; + } + } } + } catch (BadLocationException e) { + --position; + return; } - - return true; } - private boolean letterEquals(int test, char letter, boolean ignoreCase) { - if (test == letter) - return true; - else if (ignoreCase && Character.isLowerCase(letter) && test == Character.toUpperCase(letter)) - return true; - else if (ignoreCase && Character.isUpperCase(letter) && test == Character.toLowerCase(letter)) - return true; + private void unread() { + --position; + } - return false; + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + if (AbstractPartitioner.DEBUG) { + Assert.isTrue(offset >= 0, Integer.toString(offset)); + } + return offset; } - /** - * Checks wether the offset is in a String and the specified - * contenttype is the current content type. - * Strings are delimited, mutual exclusive, by a " or by a '. - * - * @param contentType The contenttype to check. - * @return true if the current offset is in a string else - * returns false. + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength() */ - private boolean isInString(String contentType) { - if (fContentType == contentType) - return (fInString || fInDoubString); - else - return false; + public int getTokenLength() { + return length; } - /** - * Returns the previouse partition stack for the given offset. - * - * @param offset The offset to return the previouse partitionstack for. - * - * @return The stack as a string array. + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int) */ - private String[] getPartitionStack(int offset) { - ArrayList types = new ArrayList(); - int tmpOffset = 0; - try { - ITypedRegion region = fDocument.getPartition(offset); - tmpOffset = region.getOffset(); - while (tmpOffset - 1 > 0) { - region = fDocument.getPartition(tmpOffset - 1); - tmpOffset = region.getOffset(); - types.add(0, region.getType()); - } - } catch (BadLocationException e) { - if (DEBUG) { - e.printStackTrace(); - } - } + public void setRange(IDocument document, int offset, int length) { + this.document = document; + this.begin = offset; + this.end = offset + length; - String[] retVal = new String[types.size()]; + this.offset = offset; + this.position = offset; + this.length = 0; + } - retVal = (String[]) types.toArray(retVal); - return retVal; + /* + * @see org.eclipse.jface.text.rules.IPartitionTokenScanner + */ + public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { + state = STATE_DEFAULT; + // if (partitionOffset > -1) { + // int delta= offset - partitionOffset; + // if (delta > 0) { + // this.setRange(document, partitionOffset, length + delta); + // return; + // } + // } + setRange(document, partitionOffset, length); } -} + // private boolean isContinuationPartition(IDocument document, int offset) { + // try { + // String type = document.getContentType(offset - 1); + // + // if (type != IDocument.DEFAULT_CONTENT_TYPE) { + // return true; + // } + // } catch (BadLocationException e) {} + // + // return false; + // } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/views/browser/BrowserView.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/views/browser/BrowserView.java index f97ae34..7363fd9 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/views/browser/BrowserView.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/views/browser/BrowserView.java @@ -9,13 +9,14 @@ * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpeclipse.views.browser; +import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowser; +import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowserUIPlugin; +import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowserUtil; + import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; -import org.eclipse.webbrowser.internal.WebBrowser; -import org.eclipse.webbrowser.internal.WebBrowserUIPlugin; -import org.eclipse.webbrowser.internal.WebBrowserUtil; /** * BrowserView is a simple demonstration of the SWT Browser * widget. It consists of a workbench view and tab folder where each tab in the