mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Auto indentation in calls to template functions. Bug 314995.
This commit is contained in:
parent
06c859eb03
commit
74af047e4a
5 changed files with 70 additions and 40 deletions
|
@ -255,6 +255,21 @@ public class CIndenterTest extends BaseUITestCase {
|
|||
assertIndenterResult();
|
||||
}
|
||||
|
||||
//new pair<int, int>(a,
|
||||
//b);
|
||||
|
||||
//new pair<int, int>(a,
|
||||
// b);
|
||||
public void testCallOfTemplateFunction() throws Exception {
|
||||
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
|
||||
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "2");
|
||||
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, "2");
|
||||
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
|
||||
DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_COMPACT,
|
||||
DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
|
||||
assertIndenterResult();
|
||||
}
|
||||
|
||||
//struct x {
|
||||
// int f1 : 1;
|
||||
// int f2 : 1;
|
||||
|
|
|
@ -513,12 +513,9 @@ public final class CHeuristicScanner implements Symbols {
|
|||
}
|
||||
|
||||
return getToken(identOrKeyword);
|
||||
|
||||
|
||||
}
|
||||
// operators, number literals etc
|
||||
return TokenOTHER;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -541,7 +538,7 @@ public final class CHeuristicScanner implements Symbols {
|
|||
if (fPos >= 0) {
|
||||
try {
|
||||
return fDocument.getChar(fPos);
|
||||
} catch (BadLocationException exc) {
|
||||
} catch (BadLocationException e) {
|
||||
}
|
||||
}
|
||||
return (char)-1;
|
||||
|
@ -588,14 +585,16 @@ public final class CHeuristicScanner implements Symbols {
|
|||
return TokenCATCH;
|
||||
if ("class".equals(s)) //$NON-NLS-1$
|
||||
return TokenCLASS;
|
||||
if ("const".equals(s)) //$NON-NLS-1$
|
||||
return TokenCONST;
|
||||
if ("while".equals(s)) //$NON-NLS-1$
|
||||
return TokenWHILE;
|
||||
if ("union".equals(s)) //$NON-NLS-1$
|
||||
return TokenUNION;
|
||||
if ("using".equals(s)) //$NON-NLS-1$
|
||||
return TokenUSING;
|
||||
if ("throw".equals(s)) //$NON-NLS-1$
|
||||
return TokenTHROW;
|
||||
if ("const".equals(s)) //$NON-NLS-1$
|
||||
return TokenCONST;
|
||||
break;
|
||||
case 6:
|
||||
if ("delete".equals(s)) //$NON-NLS-1$
|
||||
|
@ -618,12 +617,18 @@ public final class CHeuristicScanner implements Symbols {
|
|||
return TokenDEFAULT;
|
||||
if ("private".equals(s)) //$NON-NLS-1$
|
||||
return TokenPRIVATE;
|
||||
if ("typedef".equals(s)) //$NON-NLS-1$
|
||||
return TokenTYPEDEF;
|
||||
if ("virtual".equals(s)) //$NON-NLS-1$
|
||||
return TokenVIRTUAL;
|
||||
break;
|
||||
case 8:
|
||||
if ("operator".equals(s)) //$NON-NLS-1$
|
||||
return TokenOPERATOR;
|
||||
if ("template".equals(s)) //$NON-NLS-1$
|
||||
return TokenTEMPLATE;
|
||||
if ("typename".equals(s)) //$NON-NLS-1$
|
||||
return TokenTYPENAME;
|
||||
break;
|
||||
case 9:
|
||||
if ("namespace".equals(s)) //$NON-NLS-1$
|
||||
|
@ -635,8 +640,8 @@ public final class CHeuristicScanner implements Symbols {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the closing peer character (forward search). Any scopes introduced by opening peers
|
||||
* are skipped. All peers accounted for must reside in the default partition.
|
||||
* Returns the position of the closing peer character (forward search). Any scopes introduced
|
||||
* by opening peers are skipped. All peers accounted for must reside in the default partition.
|
||||
*
|
||||
* <p>Note that <code>start</code> must not point to the opening peer, but to the first
|
||||
* character being searched.</p>
|
||||
|
@ -1089,7 +1094,6 @@ public final class CHeuristicScanner implements Symbols {
|
|||
* <code>bound</code> < <code>start</code>, or <code>UNBOUND</code>
|
||||
* @return <code>true</code> if the current position looks like a composite type definition
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public boolean looksLikeCompositeTypeDefinitionBackward(int start, int bound) {
|
||||
int token= previousToken(start - 1, bound);
|
||||
switch (token) {
|
||||
|
@ -1140,7 +1144,7 @@ public final class CHeuristicScanner implements Symbols {
|
|||
switch (token) {
|
||||
case Symbols.TokenVIRTUAL:
|
||||
token= previousToken(getPosition(), bound);
|
||||
/* fallthrough */
|
||||
//$FALL-THROUGH$
|
||||
case Symbols.TokenPUBLIC:
|
||||
case Symbols.TokenPROTECTED:
|
||||
case Symbols.TokenPRIVATE:
|
||||
|
@ -1162,7 +1166,7 @@ public final class CHeuristicScanner implements Symbols {
|
|||
}
|
||||
if (token != Symbols.TokenCOLON) // colon after class def identifier
|
||||
return false;
|
||||
/* fallthrough */
|
||||
//$FALL-THROUGH$
|
||||
case Symbols.TokenCOLON:
|
||||
token= previousToken(getPosition(), bound);
|
||||
break outerWhile;
|
||||
|
|
|
@ -984,6 +984,7 @@ public final class CIndenter {
|
|||
if (!skipScope())
|
||||
fPosition= pos;
|
||||
return skipToStatementStart(danglingElse, false);
|
||||
|
||||
case Symbols.TokenSEMICOLON:
|
||||
// this is the 90% case: after a statement block
|
||||
// the end of the previous statement / block previous.end
|
||||
|
@ -1049,6 +1050,12 @@ public final class CIndenter {
|
|||
case Symbols.TokenTRY:
|
||||
return skipToStatementStart(danglingElse, false);
|
||||
|
||||
case Symbols.TokenRETURN:
|
||||
case Symbols.TokenTYPEDEF:
|
||||
case Symbols.TokenUSING:
|
||||
fIndent = fPrefs.prefContinuationIndent;
|
||||
return fPosition;
|
||||
|
||||
case Symbols.TokenCONST:
|
||||
nextToken();
|
||||
if (fToken != Symbols.TokenRPAREN) {
|
||||
|
@ -1086,18 +1093,14 @@ public final class CIndenter {
|
|||
return skipToPreviousListItemOrListStart();
|
||||
|
||||
case Symbols.TokenCOMMA:
|
||||
// inside a list of some type
|
||||
// easy if there is already a list item before with its own indentation - we just align
|
||||
// if not: take the start of the list ( LPAREN, LBRACE, LBRACKET ) and either align or
|
||||
// indent by list-indent
|
||||
// Inside a list of some type.
|
||||
// Easy if there is already a list item before with its own indentation - we just align.
|
||||
// If not: take the start of the list (LPAREN, LBRACE, LBRACKET) and either align or
|
||||
// indent by list-indent.
|
||||
return skipToPreviousListItemOrListStart();
|
||||
|
||||
case Symbols.TokenRETURN:
|
||||
fIndent = fPrefs.prefContinuationIndent;
|
||||
return fPosition;
|
||||
|
||||
default:
|
||||
// inside whatever we don't know about: similar to the list case:
|
||||
// Inside whatever we don't know about: similar to the list case:
|
||||
// if we are inside a continued expression, then either align with a previous line that
|
||||
// has indentation or indent from the expression start line (either a scope introducer
|
||||
// or the start of the expression).
|
||||
|
@ -1361,7 +1364,6 @@ public final class CIndenter {
|
|||
case Symbols.TokenEOF:
|
||||
if (isInBlock)
|
||||
fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
|
||||
// else: fIndent set by previous calls
|
||||
return fPreviousPos;
|
||||
|
||||
case Symbols.TokenCOLON:
|
||||
|
@ -1611,9 +1613,9 @@ public final class CIndenter {
|
|||
private int skipToPreviousListItemOrListStart() {
|
||||
int startLine= fLine;
|
||||
int startPosition= fPosition;
|
||||
boolean seenEqual = fToken == Symbols.TokenEQUAL;
|
||||
boolean seenShiftLeft = fToken == Symbols.TokenSHIFTLEFT;
|
||||
boolean seenRightParen = fToken == Symbols.TokenRPAREN;
|
||||
boolean continuationLineCandidate =
|
||||
fToken == Symbols.TokenEQUAL || fToken == Symbols.TokenSHIFTLEFT ||
|
||||
fToken == Symbols.TokenRPAREN;
|
||||
while (true) {
|
||||
nextToken();
|
||||
|
||||
|
@ -1624,7 +1626,7 @@ public final class CIndenter {
|
|||
int bound= Math.min(fDocument.getLength(), startPosition + 1);
|
||||
if ((fToken == Symbols.TokenSEMICOLON || fToken == Symbols.TokenRBRACE ||
|
||||
fToken == Symbols.TokenLBRACE && !looksLikeArrayInitializerIntro() && !looksLikeEnumDeclaration()) &&
|
||||
(seenEqual || seenShiftLeft || seenRightParen)) {
|
||||
continuationLineCandidate) {
|
||||
fIndent = fPrefs.prefContinuationIndent;
|
||||
} else {
|
||||
fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, bound);
|
||||
|
@ -1642,7 +1644,7 @@ public final class CIndenter {
|
|||
switch (fToken) {
|
||||
// scopes: skip them
|
||||
case Symbols.TokenRPAREN:
|
||||
seenRightParen = true;
|
||||
continuationLineCandidate = true;
|
||||
//$FALL-THROUGH$
|
||||
case Symbols.TokenRBRACKET:
|
||||
case Symbols.TokenRBRACE:
|
||||
|
@ -1667,22 +1669,21 @@ public final class CIndenter {
|
|||
return fPosition;
|
||||
|
||||
case Symbols.TokenEQUAL:
|
||||
seenEqual = true;
|
||||
case Symbols.TokenSHIFTLEFT:
|
||||
continuationLineCandidate = true;
|
||||
break;
|
||||
|
||||
case Symbols.TokenSHIFTLEFT:
|
||||
seenShiftLeft = true;
|
||||
break;
|
||||
case Symbols.TokenRETURN:
|
||||
case Symbols.TokenTYPEDEF:
|
||||
case Symbols.TokenUSING:
|
||||
fIndent = fPrefs.prefContinuationIndent;
|
||||
return fPosition;
|
||||
|
||||
case Symbols.TokenEOF:
|
||||
if (seenEqual || seenShiftLeft || seenRightParen) {
|
||||
if (continuationLineCandidate) {
|
||||
fIndent = fPrefs.prefContinuationIndent;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case Symbols.TokenRETURN:
|
||||
fIndent = fPrefs.prefContinuationIndent;
|
||||
return fPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1712,11 +1713,13 @@ public final class CIndenter {
|
|||
nextToken();
|
||||
switch (fToken) {
|
||||
case Symbols.TokenIDENT:
|
||||
fPosition = storedPosition;
|
||||
if (skipScope(Symbols.TokenLESSTHAN, Symbols.TokenGREATERTHAN))
|
||||
return true;
|
||||
break;
|
||||
case Symbols.TokenQUESTIONMARK:
|
||||
case Symbols.TokenGREATERTHAN:
|
||||
fPosition = storedPosition;
|
||||
if (skipScope(Symbols.TokenLESSTHAN, Symbols.TokenGREATERTHAN))
|
||||
return true;
|
||||
break;
|
||||
|
@ -2233,9 +2236,9 @@ public final class CIndenter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the current tokens look like a method
|
||||
* call header (i.e. an identifier as opposed to a keyword taking parenthesized
|
||||
* parameters such as <code>if</code>).
|
||||
* Returns <code>true</code> if the current tokens look like beginning of a method
|
||||
* call (i.e. an identifier as opposed to a keyword taking parenthesized parameters
|
||||
* such as <code>if</code>).
|
||||
* <p>The heuristic calls <code>nextToken</code> and expects an identifier
|
||||
* (method name).
|
||||
*
|
||||
|
@ -2243,8 +2246,12 @@ public final class CIndenter {
|
|||
* header.
|
||||
*/
|
||||
private boolean looksLikeMethodCall() {
|
||||
// TODO add awareness for constructor calls with templates: new complex<float>()
|
||||
nextToken();
|
||||
if (fToken == Symbols.TokenGREATERTHAN) {
|
||||
if (!skipScope())
|
||||
return false;
|
||||
nextToken();
|
||||
}
|
||||
return fToken == Symbols.TokenIDENT; // method name
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ public class CPairMatcher extends DefaultCharacterPairMatcher {
|
|||
*/
|
||||
private boolean isTemplateParameterOpenBracket(int offset, IDocument document, CHeuristicScanner scanner) {
|
||||
int prevToken= scanner.previousToken(offset - 1, Math.max(0, offset - ANGLE_BRACKETS_SEARCH_BOUND));
|
||||
if (prevToken == Symbols.TokenIDENT) {
|
||||
if (prevToken == Symbols.TokenIDENT || prevToken == Symbols.TokenTEMPLATE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,5 +68,9 @@ public interface Symbols {
|
|||
int TokenTHROW= 1035;
|
||||
int TokenCONST= 1036;
|
||||
int TokenEXTERN= 1037;
|
||||
int TokenTYPEDEF= 1038;
|
||||
int TokenUSING= 1039;
|
||||
int TokenTEMPLATE= 1040;
|
||||
int TokenTYPENAME= 1041;
|
||||
int TokenIDENT= 2000;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue