Previous CloneSet | Next CloneSet | Back to Main Report |
Clone Mass | Clones in CloneSet | Parameter Count | Clone Similarity | Syntax Category [Sequence Length] |
---|---|---|---|---|
408 | 2 | 3 | 0.997 | compilation_unit |
Clone Abstraction | Parameter Bindings |
Clone Instance (Click to see clone) | Line Count | Source Line | Source File |
---|---|---|---|
1 | 408 | 11 | plugins/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java |
2 | 408 | 11 | plugins/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment2.java |
| ||||
/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.formatter.align; import org.eclipse.jdt.internal.formatter.Location; import org.eclipse.jdt.internal.formatter.Scribe; /** * Alignment management * * @since 2.1 */ public class Alignment { // name of alignment public String name; // link to enclosing alignment public Alignment enclosing; // start location of this alignment public Location location; // indentation management public int fragmentIndex; public int fragmentCount; public int[] fragmentIndentations; public boolean needRedoColumnAlignment; // chunk management public int chunkStartIndex; public int chunkKind; // break management public int originalIndentationLevel; public int breakIndentationLevel; public int shiftBreakIndentationLevel; public int[] fragmentBreaks; public boolean wasSplit; public Scribe scribe; /* * Alignment modes */ public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional) public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level) public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation) // split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN /** foobar(#fragment1, #fragment2, <ul> * <li> #fragment3, #fragment4 </li> * </ul> */ public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments /** foobar(<ul> * <li> #fragment1, #fragment2, </li> * <li> #fragment5, #fragment4, </li> * </ul> */ public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; // compact mode, but will first try to break before first fragment /** foobar(<ul> * <li> #fragment1, </li> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_ONE_PER_LINE_SPLIT = 32 + 16; // one fragment per line /** * foobar(<ul> * <li> #fragment1, </li> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further /** foobar(#fragment1, <ul> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_NEXT_PER_LINE_SPLIT = 64 + 16; // one per line, except first fragment (if possible) //64+32 //64+32+16 // mode controlling column alignments /** * <table BORDER COLS=4 WIDTH="100%" > * <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr> * <tr><td>#fragment1B</td> <td>#long-fragment2B</td> <td>#fragment3B</td> <td>#fragment4B</td></tr> * <tr><td>#very-long-fragment1C</td> <td>#fragment2C</td> <td>#fragment3C</td> <td>#fragment4C</td></tr> * </table> */ public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically public static final int M_NO_ALIGNMENT = 0; public int mode; public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT| M_NEXT_SHIFTED_SPLIT| M_COMPACT_SPLIT| M_COMPACT_FIRST_BREAK_SPLIT| M_NEXT_PER_LINE_SPLIT; // alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen public static final int R_OUTERMOST = 1; public static final int R_INNERMOST = 2; public int tieBreakRule; // alignment effects on a per fragment basis public static int NONE = 0; public static int BREAK = 1; // chunk kind public static final int CHUNK_FIELD = 1; public static final int CHUNK_METHOD = 2; public static final int CHUNK_TYPE = 3; public static final int CHUNK_ENUM = 4; // location to align and break on. public Alignment(String name, int mode, int tieBreakRule, Scribe scribe, int fragmentCount, int sourceRestart, int continuationIndent) { this.name = name; this.location = new Location(scribe, sourceRestart); this.mode = mode; this.tieBreakRule = tieBreakRule; this.fragmentCount = fragmentCount; this.scribe = scribe; this.originalIndentationLevel = this.scribe.indentationLevel; this.wasSplit = false; // initialize the break indentation level, using modes and continuationIndentationLevel preference final int indentSize = this.scribe.indentationSize; int currentColumn = this.location.outputColumn; if (currentColumn == 1) { currentColumn = this.location.outputIndentationLevel + 1; } if ((mode& M_INDENT_ON_COLUMN) != 0) { // indent broken fragments at next indentation level, based on current column this.breakIndentationLevel = this.scribe.getNextIndentationLevel(currentColumn); if (this.breakIndentationLevel == this.location.outputIndentationLevel) { this.breakIndentationLevel += (continuationIndent * indentSize); } } else if ((mode& M_INDENT_BY_ONE) != 0) { // indent broken fragments exactly one level deeper than current indentation this.breakIndentationLevel = this.location.outputIndentationLevel + indentSize; } else { this.breakIndentationLevel = this.location.outputIndentationLevel + continuationIndent * indentSize; } this.shiftBreakIndentationLevel = this.breakIndentationLevel + indentSize; this.fragmentIndentations = new int[this.fragmentCount]; this.fragmentBreaks = new int[this.fragmentCount]; // check for forced alignments if ((this.mode& M_FORCE) != 0) { couldBreak(); } } public boolean checkChunkStart(int kind, int startIndex, int sourceRestart) { if (this.chunkKind != kind) { this.chunkKind = kind; // when redoing same chunk alignment, must not reset if (startIndex != this.chunkStartIndex) { this.chunkStartIndex = startIndex; this.location.update(this.scribe, sourceRestart); reset(); } return true; } return false; } public void checkColumn() { if ((this.mode& M_MULTICOLUMN) != 0) { int currentIndentation = this.scribe.getNextIndentationLevel(this.scribe.column + (this.scribe.needSpace ? 1: 0)); int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex]; if (currentIndentation > fragmentIndentation) { this.fragmentIndentations[this.fragmentIndex] = currentIndentation; if (fragmentIndentation != 0) { for (int i = this.fragmentIndex + 1; i < this.fragmentCount; i++) { this.fragmentIndentations[i] = 0; } this.needRedoColumnAlignment = true; } } // backtrack only once all fragments got checked if (this.needRedoColumnAlignment && this.fragmentIndex == this.fragmentCount - 1) { // alignment too small // if (CodeFormatterVisitor.DEBUG){ // System.out.println("ALIGNMENT TOO SMALL"); // System.out.println(this); // } this.needRedoColumnAlignment = false; int relativeDepth = 0; Alignment targetAlignment = this.scribe.memberAlignment; while (targetAlignment != null) { if (targetAlignment == this ) { throw new AlignmentException(AlignmentException.ALIGN_TOO_SMALL, relativeDepth); } targetAlignment = targetAlignment.enclosing; relativeDepth++; } } } } public boolean couldBreak() { int i; switch (mode& SPLIT_MASK) { /* # aligned fragment * foo( * #AAAAA, #BBBBB, * #CCCC); */ case M_COMPACT_FIRST_BREAK_SPLIT: if (this.fragmentBreaks[0] == NONE) { this.fragmentBreaks[0] = BREAK; this.fragmentIndentations[0] = this.breakIndentationLevel; return wasSplit = true; } i = this.fragmentIndex; do { if (this.fragmentBreaks[i] == NONE) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; return wasSplit = true; } } while ( --i >= 0); break; /* # aligned fragment * foo(#AAAAA, #BBBBB, * #CCCC); */ case M_COMPACT_SPLIT: i = this.fragmentIndex; do { if (this.fragmentBreaks[i] == NONE) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; return wasSplit = true; } } while ( --i >= 0); break; /* # aligned fragment * foo( * #AAAAA, * #BBBBB, * #CCCC); */ case M_NEXT_SHIFTED_SPLIT: if (this.fragmentBreaks[0] == NONE) { this.fragmentBreaks[0] = BREAK; this.fragmentIndentations[0] = this.breakIndentationLevel; for (i = 1; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.shiftBreakIndentationLevel; } return wasSplit = true; } break; /* # aligned fragment * foo( * #AAAAA, * #BBBBB, * #CCCC); */ case M_ONE_PER_LINE_SPLIT: if (this.fragmentBreaks[0] == NONE) { for (i = 0; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; } return wasSplit = true; } /* # aligned fragment * foo(#AAAAA, * #BBBBB, * #CCCC); */ case M_NEXT_PER_LINE_SPLIT: if (this.fragmentBreaks[0] == NONE) { if (this.fragmentCount > 1 && this.fragmentBreaks[1] == NONE) { if ((this.mode& M_INDENT_ON_COLUMN) != 0) { this.fragmentIndentations[0] = this.breakIndentationLevel; } for (i = 1; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; } return wasSplit = true; } } break; } return false; // cannot split better } public Alignment getAlignment(String targetName) { if (targetName.equals(this.name)) return this ; if (this.enclosing == null) return null; return this.enclosing.getAlignment(targetName); } // perform alignment effect for current fragment public void performFragmentEffect() { if ((this.mode& M_MULTICOLUMN) == 0) { switch (this.mode& SPLIT_MASK) { case Alignment.M_COMPACT_SPLIT: case Alignment.M_COMPACT_FIRST_BREAK_SPLIT: case Alignment.M_NEXT_PER_LINE_SPLIT: case Alignment.M_NEXT_SHIFTED_SPLIT: case Alignment.M_ONE_PER_LINE_SPLIT: break; default: return; } } if (this.fragmentBreaks[this.fragmentIndex] == BREAK) { this.scribe.printNewLine(); } if (this.fragmentIndentations[this.fragmentIndex] > 0) { this.scribe.indentationLevel = this.fragmentIndentations[this.fragmentIndex]; } } // reset fragment indentation/break status public void reset() { if (fragmentCount > 0) { this.fragmentIndentations = new int[this.fragmentCount]; this.fragmentBreaks = new int[this.fragmentCount]; } // check for forced alignments if ((mode& M_FORCE) != 0) { couldBreak(); } } public void toFragmentsString(StringBuffer buffer) { // default implementation } public String toString() { StringBuffer buffer = new StringBuffer(10); buffer .append(getClass().getName()) .append(':') .append("<name: ") //$NON-NLS-1$ .append(this.name). append(">"); //$NON-NLS-1$ if (this.enclosing != null) { buffer .append("<enclosingName: ") //$NON-NLS-1$ .append(this.enclosing.name). append('>'); } buffer.append('\n'); for (int i = 0; i < this.fragmentCount; i++) { buffer .append(" - fragment ") //$NON-NLS-1$ .append(i) .append(": ") //$NON-NLS-1$ .append("<break: ") //$NON-NLS-1$ .append(this.fragmentBreaks[i] > 0 ? "YES": "NO") //$NON-NLS-1$ //$NON-NLS-2$ .append(">") //$NON-NLS-1$ .append("<indent: ") //$NON-NLS-1$ .append(this.fragmentIndentations[i]). append(">\n"); //$NON-NLS-1$ } buffer.append('\n'); return buffer.toString(); } public void update() { for (int i = 1; i < this.fragmentCount; i++) { if (this.fragmentBreaks[i] == BREAK) { this.fragmentIndentations[i] = this.breakIndentationLevel; } } } public boolean isWrapped() { for (int i = 0, max = this.fragmentCount; i < max; i++) { if (this.fragmentBreaks[i] == BREAK) { return true; } } return false; } } |
| ||||
/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.formatter.align; import org.eclipse.jdt.internal.formatter.Location2; import org.eclipse.jdt.internal.formatter.Scribe2; /** * Alignment management * * @since 2.1 */ public class Alignment2 { // name of alignment public String name; // link to enclosing alignment public Alignment2 enclosing; // start location of this alignment public Location2 location; // indentation management public int fragmentIndex; public int fragmentCount; public int[] fragmentIndentations; public boolean needRedoColumnAlignment; // chunk management public int chunkStartIndex; public int chunkKind; // break management public int originalIndentationLevel; public int breakIndentationLevel; public int shiftBreakIndentationLevel; public int[] fragmentBreaks; public boolean wasSplit; public Scribe2 scribe; /* * Alignment modes */ public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional) public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level) public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation) // split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN /** foobar(#fragment1, #fragment2, <ul> * <li> #fragment3, #fragment4 </li> * </ul> */ public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments /** foobar(<ul> * <li> #fragment1, #fragment2, </li> * <li> #fragment5, #fragment4, </li> * </ul> */ public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; // compact mode, but will first try to break before first fragment /** foobar(<ul> * <li> #fragment1, </li> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_ONE_PER_LINE_SPLIT = 32 + 16; // one fragment per line /** * foobar(<ul> * <li> #fragment1, </li> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further /** foobar(#fragment1, <ul> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_NEXT_PER_LINE_SPLIT = 64 + 16; // one per line, except first fragment (if possible) //64+32 //64+32+16 // mode controlling column alignments /** * <table BORDER COLS=4 WIDTH="100%" > * <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr> * <tr><td>#fragment1B</td> <td>#long-fragment2B</td> <td>#fragment3B</td> <td>#fragment4B</td></tr> * <tr><td>#very-long-fragment1C</td> <td>#fragment2C</td> <td>#fragment3C</td> <td>#fragment4C</td></tr> * </table> */ public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically public static final int M_NO_ALIGNMENT = 0; public int mode; public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT| M_NEXT_SHIFTED_SPLIT| M_COMPACT_SPLIT| M_COMPACT_FIRST_BREAK_SPLIT| M_NEXT_PER_LINE_SPLIT; // alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen public static final int R_OUTERMOST = 1; public static final int R_INNERMOST = 2; public int tieBreakRule; // alignment effects on a per fragment basis public static int NONE = 0; public static int BREAK = 1; // chunk kind public static final int CHUNK_FIELD = 1; public static final int CHUNK_METHOD = 2; public static final int CHUNK_TYPE = 3; public static final int CHUNK_ENUM = 4; // location to align and break on. public Alignment2(String name, int mode, int tieBreakRule, Scribe2 scribe, int fragmentCount, int sourceRestart, int continuationIndent) { this.name = name; this.location = new Location2(scribe, sourceRestart); this.mode = mode; this.tieBreakRule = tieBreakRule; this.fragmentCount = fragmentCount; this.scribe = scribe; this.originalIndentationLevel = this.scribe.indentationLevel; this.wasSplit = false; // initialize the break indentation level, using modes and continuationIndentationLevel preference final int indentSize = this.scribe.indentationSize; int currentColumn = this.location.outputColumn; if (currentColumn == 1) { currentColumn = this.location.outputIndentationLevel + 1; } if ((mode& M_INDENT_ON_COLUMN) != 0) { // indent broken fragments at next indentation level, based on current column this.breakIndentationLevel = this.scribe.getNextIndentationLevel(currentColumn); if (this.breakIndentationLevel == this.location.outputIndentationLevel) { this.breakIndentationLevel += (continuationIndent * indentSize); } } else if ((mode& M_INDENT_BY_ONE) != 0) { // indent broken fragments exactly one level deeper than current indentation this.breakIndentationLevel = this.location.outputIndentationLevel + indentSize; } else { this.breakIndentationLevel = this.location.outputIndentationLevel + continuationIndent * indentSize; } this.shiftBreakIndentationLevel = this.breakIndentationLevel + indentSize; this.fragmentIndentations = new int[this.fragmentCount]; this.fragmentBreaks = new int[this.fragmentCount]; // check for forced alignments if ((this.mode& M_FORCE) != 0) { couldBreak(); } } public boolean checkChunkStart(int kind, int startIndex, int sourceRestart) { if (this.chunkKind != kind) { this.chunkKind = kind; // when redoing same chunk alignment, must not reset if (startIndex != this.chunkStartIndex) { this.chunkStartIndex = startIndex; this.location.update(this.scribe, sourceRestart); reset(); } return true; } return false; } public void checkColumn() { if ((this.mode& M_MULTICOLUMN) != 0) { int currentIndentation = this.scribe.getNextIndentationLevel(this.scribe.column + (this.scribe.needSpace ? 1: 0)); int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex]; if (currentIndentation > fragmentIndentation) { this.fragmentIndentations[this.fragmentIndex] = currentIndentation; if (fragmentIndentation != 0) { for (int i = this.fragmentIndex + 1; i < this.fragmentCount; i++) { this.fragmentIndentations[i] = 0; } this.needRedoColumnAlignment = true; } } // backtrack only once all fragments got checked if (this.needRedoColumnAlignment && this.fragmentIndex == this.fragmentCount - 1) { // alignment too small // if (CodeFormatterVisitor.DEBUG){ // System.out.println("ALIGNMENT TOO SMALL"); // System.out.println(this); // } this.needRedoColumnAlignment = false; int relativeDepth = 0; Alignment2 targetAlignment = this.scribe.memberAlignment; while (targetAlignment != null) { if (targetAlignment == this ) { throw new AlignmentException(AlignmentException.ALIGN_TOO_SMALL, relativeDepth); } targetAlignment = targetAlignment.enclosing; relativeDepth++; } } } } public boolean couldBreak() { int i; switch (mode& SPLIT_MASK) { /* # aligned fragment * foo( * #AAAAA, #BBBBB, * #CCCC); */ case M_COMPACT_FIRST_BREAK_SPLIT: if (this.fragmentBreaks[0] == NONE) { this.fragmentBreaks[0] = BREAK; this.fragmentIndentations[0] = this.breakIndentationLevel; return wasSplit = true; } i = this.fragmentIndex; do { if (this.fragmentBreaks[i] == NONE) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; return wasSplit = true; } } while ( --i >= 0); break; /* # aligned fragment * foo(#AAAAA, #BBBBB, * #CCCC); */ case M_COMPACT_SPLIT: i = this.fragmentIndex; do { if (this.fragmentBreaks[i] == NONE) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; return wasSplit = true; } } while ( --i >= 0); break; /* # aligned fragment * foo( * #AAAAA, * #BBBBB, * #CCCC); */ case M_NEXT_SHIFTED_SPLIT: if (this.fragmentBreaks[0] == NONE) { this.fragmentBreaks[0] = BREAK; this.fragmentIndentations[0] = this.breakIndentationLevel; for (i = 1; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.shiftBreakIndentationLevel; } return wasSplit = true; } break; /* # aligned fragment * foo( * #AAAAA, * #BBBBB, * #CCCC); */ case M_ONE_PER_LINE_SPLIT: if (this.fragmentBreaks[0] == NONE) { for (i = 0; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; } return wasSplit = true; } /* # aligned fragment * foo(#AAAAA, * #BBBBB, * #CCCC); */ case M_NEXT_PER_LINE_SPLIT: if (this.fragmentBreaks[0] == NONE) { if (this.fragmentCount > 1 && this.fragmentBreaks[1] == NONE) { if ((this.mode& M_INDENT_ON_COLUMN) != 0) { this.fragmentIndentations[0] = this.breakIndentationLevel; } for (i = 1; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; } return wasSplit = true; } } break; } return false; // cannot split better } public Alignment2 getAlignment(String targetName) { if (targetName.equals(this.name)) return this ; if (this.enclosing == null) return null; return this.enclosing.getAlignment(targetName); } // perform alignment effect for current fragment public void performFragmentEffect() { if ((this.mode& M_MULTICOLUMN) == 0) { switch (this.mode& SPLIT_MASK) { case Alignment2.M_COMPACT_SPLIT: case Alignment2.M_COMPACT_FIRST_BREAK_SPLIT: case Alignment2.M_NEXT_PER_LINE_SPLIT: case Alignment2.M_NEXT_SHIFTED_SPLIT: case Alignment2.M_ONE_PER_LINE_SPLIT: break; default: return; } } if (this.fragmentBreaks[this.fragmentIndex] == BREAK) { this.scribe.printNewLine(); } if (this.fragmentIndentations[this.fragmentIndex] > 0) { this.scribe.indentationLevel = this.fragmentIndentations[this.fragmentIndex]; } } // reset fragment indentation/break status public void reset() { if (fragmentCount > 0) { this.fragmentIndentations = new int[this.fragmentCount]; this.fragmentBreaks = new int[this.fragmentCount]; } // check for forced alignments if ((mode& M_FORCE) != 0) { couldBreak(); } } public void toFragmentsString(StringBuffer buffer) { // default implementation } public String toString() { StringBuffer buffer = new StringBuffer(10); buffer .append(getClass().getName()) .append(':') .append("<name: ") //$NON-NLS-1$ .append(this.name). append(">"); //$NON-NLS-1$ if (this.enclosing != null) { buffer .append("<enclosingName: ") //$NON-NLS-1$ .append(this.enclosing.name). append('>'); } buffer.append('\n'); for (int i = 0; i < this.fragmentCount; i++) { buffer .append(" - fragment ") //$NON-NLS-1$ .append(i) .append(": ") //$NON-NLS-1$ .append("<break: ") //$NON-NLS-1$ .append(this.fragmentBreaks[i] > 0 ? "YES": "NO") //$NON-NLS-1$ //$NON-NLS-2$ .append(">") //$NON-NLS-1$ .append("<indent: ") //$NON-NLS-1$ .append(this.fragmentIndentations[i]). append(">\n"); //$NON-NLS-1$ } buffer.append('\n'); return buffer.toString(); } public void update() { for (int i = 1; i < this.fragmentCount; i++) { if (this.fragmentBreaks[i] == BREAK) { this.fragmentIndentations[i] = this.breakIndentationLevel; } } } public boolean isWrapped() { for (int i = 0, max = this.fragmentCount; i < max; i++) { if (this.fragmentBreaks[i] == BREAK) { return true; } } return false; } } |
| |||
/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.formatter.align; import org.eclipse.jdt.internal.formatter. [[#variablebddc7920]]; import org.eclipse.jdt.internal.formatter. [[#variablebddc78a0]]; /** * Alignment management * * @since 2.1 */ public class [[#variablebddc7840]]{ // name of alignment public String name; // link to enclosing alignment public [[#variablebddc7840]] enclosing; // start location of this alignment public [[#variablebddc7920]] location; // indentation management public int fragmentIndex; public int fragmentCount; public int[] fragmentIndentations; public boolean needRedoColumnAlignment; // chunk management public int chunkStartIndex; public int chunkKind; // break management public int originalIndentationLevel; public int breakIndentationLevel; public int shiftBreakIndentationLevel; public int[] fragmentBreaks; public boolean wasSplit; public [[#variablebddc78a0]] scribe; /* * Alignment modes */ public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional) public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level) public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation) // split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN /** foobar(#fragment1, #fragment2, <ul> * <li> #fragment3, #fragment4 </li> * </ul> */ public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments /** foobar(<ul> * <li> #fragment1, #fragment2, </li> * <li> #fragment5, #fragment4, </li> * </ul> */ public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; // compact mode, but will first try to break before first fragment /** foobar(<ul> * <li> #fragment1, </li> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_ONE_PER_LINE_SPLIT = 32 + 16; // one fragment per line /** * foobar(<ul> * <li> #fragment1, </li> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further /** foobar(#fragment1, <ul> * <li> #fragment2, </li> * <li> #fragment3 </li> * <li> #fragment4, </li> * </ul> */ public static final int M_NEXT_PER_LINE_SPLIT = 64 + 16; // one per line, except first fragment (if possible) //64+32 //64+32+16 // mode controlling column alignments /** * <table BORDER COLS=4 WIDTH="100%" > * <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr> * <tr><td>#fragment1B</td> <td>#long-fragment2B</td> <td>#fragment3B</td> <td>#fragment4B</td></tr> * <tr><td>#very-long-fragment1C</td> <td>#fragment2C</td> <td>#fragment3C</td> <td>#fragment4C</td></tr> * </table> */ public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically public static final int M_NO_ALIGNMENT = 0; public int mode; public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT|M_NEXT_SHIFTED_SPLIT|M_COMPACT_SPLIT|M_COMPACT_FIRST_BREAK_SPLIT|M_NEXT_PER_LINE_SPLIT; // alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen public static final int R_OUTERMOST = 1; public static final int R_INNERMOST = 2; public int tieBreakRule; // alignment effects on a per fragment basis public static int NONE = 0; public static int BREAK = 1; // chunk kind public static final int CHUNK_FIELD = 1; public static final int CHUNK_METHOD = 2; public static final int CHUNK_TYPE = 3; public static final int CHUNK_ENUM = 4; // location to align and break on. public [[#variablebddc7840]](String name, int mode, int tieBreakRule, [[#variablebddc78a0]] scribe, int fragmentCount, int sourceRestart, int continuationIndent) { this.name = name; this.location = new [[#variablebddc7920]](scribe, sourceRestart); this.mode = mode; this.tieBreakRule = tieBreakRule; this.fragmentCount = fragmentCount; this.scribe = scribe; this.originalIndentationLevel = this.scribe.indentationLevel; this.wasSplit = false; // initialize the break indentation level, using modes and continuationIndentationLevel preference final int indentSize = this.scribe.indentationSize; int currentColumn = this.location.outputColumn; if (currentColumn == 1) { currentColumn = this.location.outputIndentationLevel + 1; } if ((mode&M_INDENT_ON_COLUMN) != 0) { // indent broken fragments at next indentation level, based on current column this.breakIndentationLevel = this.scribe.getNextIndentationLevel(currentColumn); if (this.breakIndentationLevel == this.location.outputIndentationLevel) { this.breakIndentationLevel += (continuationIndent * indentSize); } } else if ((mode&M_INDENT_BY_ONE) != 0) { // indent broken fragments exactly one level deeper than current indentation this.breakIndentationLevel = this.location.outputIndentationLevel + indentSize; } else { this.breakIndentationLevel = this.location.outputIndentationLevel + continuationIndent * indentSize; } this.shiftBreakIndentationLevel = this.breakIndentationLevel + indentSize; this.fragmentIndentations = new int[this.fragmentCount]; this.fragmentBreaks = new int[this.fragmentCount]; // check for forced alignments if ((this.mode&M_FORCE) != 0) { couldBreak(); } } public boolean checkChunkStart(int kind, int startIndex, int sourceRestart) { if (this.chunkKind != kind) { this.chunkKind = kind; // when redoing same chunk alignment, must not reset if (startIndex != this.chunkStartIndex) { this.chunkStartIndex = startIndex; this.location.update(this.scribe, sourceRestart); reset(); } return true; } return false; } public void checkColumn() { if ((this.mode&M_MULTICOLUMN) != 0) { int currentIndentation = this.scribe.getNextIndentationLevel(this.scribe.column + (this.scribe.needSpace ? 1: 0)); int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex]; if (currentIndentation > fragmentIndentation) { this.fragmentIndentations[this.fragmentIndex] = currentIndentation; if (fragmentIndentation != 0) { for (int i = this.fragmentIndex + 1; i < this.fragmentCount; i++) { this.fragmentIndentations[i] = 0; } this.needRedoColumnAlignment = true; } } // backtrack only once all fragments got checked if (this.needRedoColumnAlignment && this.fragmentIndex == this.fragmentCount - 1) { // alignment too small // if (CodeFormatterVisitor.DEBUG){ // System.out.println("ALIGNMENT TOO SMALL"); // System.out.println(this); // } this.needRedoColumnAlignment = false; int relativeDepth = 0; [[#variablebddc7840]] targetAlignment = this.scribe.memberAlignment; while (targetAlignment != null) { if (targetAlignment == this ) { throw new AlignmentException(AlignmentException.ALIGN_TOO_SMALL, relativeDepth); } targetAlignment = targetAlignment.enclosing; relativeDepth++; } } } } public boolean couldBreak() { int i; switch (mode&SPLIT_MASK) { /* # aligned fragment * foo( * #AAAAA, #BBBBB, * #CCCC); */ case M_COMPACT_FIRST_BREAK_SPLIT: if (this.fragmentBreaks[0] == NONE) { this.fragmentBreaks[0] = BREAK; this.fragmentIndentations[0] = this.breakIndentationLevel; return wasSplit = true; } i = this.fragmentIndex; do { if (this.fragmentBreaks[i] == NONE) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; return wasSplit = true; } } while ( --i >= 0); break; /* # aligned fragment * foo(#AAAAA, #BBBBB, * #CCCC); */ case M_COMPACT_SPLIT: i = this.fragmentIndex; do { if (this.fragmentBreaks[i] == NONE) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; return wasSplit = true; } } while ( --i >= 0); break; /* # aligned fragment * foo( * #AAAAA, * #BBBBB, * #CCCC); */ case M_NEXT_SHIFTED_SPLIT: if (this.fragmentBreaks[0] == NONE) { this.fragmentBreaks[0] = BREAK; this.fragmentIndentations[0] = this.breakIndentationLevel; for (i = 1; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.shiftBreakIndentationLevel; } return wasSplit = true; } break; /* # aligned fragment * foo( * #AAAAA, * #BBBBB, * #CCCC); */ case M_ONE_PER_LINE_SPLIT: if (this.fragmentBreaks[0] == NONE) { for (i = 0; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; } return wasSplit = true; } /* # aligned fragment * foo(#AAAAA, * #BBBBB, * #CCCC); */ case M_NEXT_PER_LINE_SPLIT: if (this.fragmentBreaks[0] == NONE) { if (this.fragmentCount > 1 && this.fragmentBreaks[1] == NONE) { if ((this.mode&M_INDENT_ON_COLUMN) != 0) { this.fragmentIndentations[0] = this.breakIndentationLevel; } for (i = 1; i < this.fragmentCount; i++) { this.fragmentBreaks[i] = BREAK; this.fragmentIndentations[i] = this.breakIndentationLevel; } return wasSplit = true; } } break; } return false; // cannot split better } public [[#variablebddc7840]] getAlignment(String targetName) { if (targetName.equals(this.name)) return this ; if (this.enclosing == null) return null; return this.enclosing.getAlignment(targetName); } // perform alignment effect for current fragment public void performFragmentEffect() { if ((this.mode&M_MULTICOLUMN) == 0) { switch (this.mode&SPLIT_MASK) { case [[#variablebddc7840]].M_COMPACT_SPLIT: case [[#variablebddc7840]].M_COMPACT_FIRST_BREAK_SPLIT: case [[#variablebddc7840]].M_NEXT_PER_LINE_SPLIT: case [[#variablebddc7840]].M_NEXT_SHIFTED_SPLIT: case [[#variablebddc7840]].M_ONE_PER_LINE_SPLIT: break; default: return; } } if (this.fragmentBreaks[this.fragmentIndex] == BREAK) { this.scribe.printNewLine(); } if (this.fragmentIndentations[this.fragmentIndex] > 0) { this.scribe.indentationLevel = this.fragmentIndentations[this.fragmentIndex]; } } // reset fragment indentation/break status public void reset() { if (fragmentCount > 0) { this.fragmentIndentations = new int[this.fragmentCount]; this.fragmentBreaks = new int[this.fragmentCount]; } // check for forced alignments if ((mode&M_FORCE) != 0) { couldBreak(); } } public void toFragmentsString(StringBuffer buffer) { // default implementation } public String toString() { StringBuffer buffer = new StringBuffer(10); buffer.append(getClass().getName()).append(':').append("<name: ") //$NON-NLS-1$ .append(this.name).append(">"); //$NON-NLS-1$ if (this.enclosing != null) { buffer.append("<enclosingName: ") //$NON-NLS-1$ .append(this.enclosing.name).append('>'); } buffer.append('\n'); for (int i = 0; i < this.fragmentCount; i++) { buffer.append(" - fragment ") //$NON-NLS-1$ .append(i).append(": ") //$NON-NLS-1$ .append("<break: ") //$NON-NLS-1$ .append(this.fragmentBreaks[i] > 0 ? "YES": "NO") //$NON-NLS-1$ //$NON-NLS-2$ .append(">") //$NON-NLS-1$ .append("<indent: ") //$NON-NLS-1$ .append(this.fragmentIndentations[i]).append(">\n"); //$NON-NLS-1$ } buffer.append('\n'); return buffer.toString(); } public void update() { for (int i = 1; i < this.fragmentCount; i++) { if (this.fragmentBreaks[i] == BREAK) { this.fragmentIndentations[i] = this.breakIndentationLevel; } } } public boolean isWrapped() { for (int i = 0, max = this.fragmentCount; i < max; i++) { if (this.fragmentBreaks[i] == BREAK) { return true; } } return false; } } |
CloneAbstraction |
Parameter Index | Clone Instance | Parameter Name | Value |
---|---|---|---|
1 | 1 | [[#bddc7920]] | Location |
1 | 2 | [[#bddc7920]] | Location2 |
2 | 1 | [[#bddc78a0]] | Scribe |
2 | 2 | [[#bddc78a0]] | Scribe2 |
3 | 1 | [[#bddc7840]] | Alignment |
3 | 2 | [[#bddc7840]] | Alignment2 |