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