mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
Content Assist within macro arguments, bug 200208.
This commit is contained in:
parent
7481b864e5
commit
a0169fac0d
4 changed files with 135 additions and 14 deletions
|
@ -0,0 +1,34 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when content assist is used within the parameter list of a macro expansion.
|
||||||
|
* It transports the token list of the current parameter for further use in attempting
|
||||||
|
* a completion.
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public class CompletionInMacroExpansionException extends OffsetLimitReachedException {
|
||||||
|
|
||||||
|
private TokenList fParameterTokens;
|
||||||
|
|
||||||
|
public CompletionInMacroExpansionException(int origin, IToken lastToken, TokenList paramTokens) {
|
||||||
|
super(origin, lastToken);
|
||||||
|
fParameterTokens = paramTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TokenList getParameterTokens() {
|
||||||
|
return fParameterTokens;
|
||||||
|
}
|
||||||
|
}
|
|
@ -170,15 +170,25 @@ public class MacroExpander {
|
||||||
TokenSource input= new TokenSource(lexer, stopAtNewline);
|
TokenSource input= new TokenSource(lexer, stopAtNewline);
|
||||||
TokenList firstExpansion= new TokenList();
|
TokenList firstExpansion= new TokenList();
|
||||||
|
|
||||||
firstExpansion.append(new ExpansionBoundary(macro, true));
|
TokenList result;
|
||||||
expandOne(identifier, macro, forbidden, input, firstExpansion, null);
|
try {
|
||||||
firstExpansion.append(new ExpansionBoundary(macro, false));
|
firstExpansion.append(new ExpansionBoundary(macro, true));
|
||||||
|
expandOne(identifier, macro, forbidden, input, firstExpansion, null);
|
||||||
|
firstExpansion.append(new ExpansionBoundary(macro, false));
|
||||||
|
|
||||||
input.prepend(firstExpansion);
|
input.prepend(firstExpansion);
|
||||||
|
|
||||||
TokenList result= expandAll(input, forbidden, isPPCondition, null);
|
result= expandAll(input, forbidden, isPPCondition, null);
|
||||||
|
}
|
||||||
|
catch (CompletionInMacroExpansionException e) {
|
||||||
|
// for content assist in macro expansions, we return the list of tokens of the
|
||||||
|
// parameter at the current cursor position and hope that they make sense if
|
||||||
|
// they are inserted at the position of the expansion.
|
||||||
|
// For a better solution one would have to perform the expansion with artificial
|
||||||
|
// parameters and then check where the completion token ends up in the expansion.
|
||||||
|
result= e.getParameterTokens().cloneTokens();
|
||||||
|
}
|
||||||
postProcessTokens(result);
|
postProcessTokens(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,11 +465,17 @@ public class MacroExpander {
|
||||||
case IToken.tEND_OF_INPUT:
|
case IToken.tEND_OF_INPUT:
|
||||||
assert nesting >= 0;
|
assert nesting >= 0;
|
||||||
if (fCompletionMode) {
|
if (fCompletionMode) {
|
||||||
t.setType(IToken.tCOMPLETION);
|
if (idx < result.length) {
|
||||||
|
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
||||||
|
}
|
||||||
throw new OffsetLimitReachedException(ORIGIN, null);
|
throw new OffsetLimitReachedException(ORIGIN, null);
|
||||||
}
|
}
|
||||||
break loop;
|
break loop;
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
|
if (idx < result.length) {
|
||||||
|
result[idx].append(t);
|
||||||
|
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
||||||
|
}
|
||||||
throw new OffsetLimitReachedException(ORIGIN, t);
|
throw new OffsetLimitReachedException(ORIGIN, t);
|
||||||
|
|
||||||
case Lexer.tNEWLINE:
|
case Lexer.tNEWLINE:
|
||||||
|
@ -840,13 +856,12 @@ public class MacroExpander {
|
||||||
case IToken.tCHAR:
|
case IToken.tCHAR:
|
||||||
case IToken.tLCHAR:
|
case IToken.tLCHAR:
|
||||||
final char[] image= t.getCharImage();
|
final char[] image= t.getCharImage();
|
||||||
for (int i = 0; i < image.length; i++) {
|
for (final char c : image) {
|
||||||
final char c = image[i];
|
if (c == '"' || c == '\\') {
|
||||||
if (c == '"' || c == '\\') {
|
buf.append('\\');
|
||||||
buf.append('\\');
|
}
|
||||||
|
buf.append(c);
|
||||||
}
|
}
|
||||||
buf.append(c);
|
|
||||||
}
|
|
||||||
space= false;
|
space= false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -911,6 +926,12 @@ public class MacroExpander {
|
||||||
case CPreprocessor.tNOSPACE:
|
case CPreprocessor.tNOSPACE:
|
||||||
replacement.removeBehind(l);
|
replacement.removeBehind(l);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case IToken.tCOMPLETION:
|
||||||
|
// we need to preserve the length of the completion token.
|
||||||
|
t.setOffset(offset, offset+t.getLength());
|
||||||
|
t.setNext(null);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
t.setOffset(offset, ++offset);
|
t.setOffset(offset, ++offset);
|
||||||
l= t;
|
l= t;
|
||||||
|
|
|
@ -1059,4 +1059,39 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
};
|
};
|
||||||
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
|
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define INIT_PTR(PtrName) (PtrName) = 0;
|
||||||
|
// class CCApp {
|
||||||
|
// public:
|
||||||
|
// int pIShell;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int main(void) {
|
||||||
|
// CCApp *pThis = 0;
|
||||||
|
//
|
||||||
|
// INIT_PTR(pTh/*cursor*/);
|
||||||
|
// }
|
||||||
|
public void testCompletionInMacroArguments1_Bug200208() throws Exception {
|
||||||
|
final String[] expected= {"pThis"};
|
||||||
|
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #define INIT_PTR(PtrName) (PtrName) = 0;
|
||||||
|
// #define COPY_PTR(pTarget, pSource) (pTarget) = (pSource)
|
||||||
|
//
|
||||||
|
// class CCApp {
|
||||||
|
// public:
|
||||||
|
// int pIShell;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int main(void) {
|
||||||
|
// CCApp *pThis = 0;
|
||||||
|
//
|
||||||
|
// INIT_PTR(pThis);
|
||||||
|
// COPY_PTR(pThis->pIShell, pThis->pI/*cursor*/)
|
||||||
|
// }
|
||||||
|
public void testCompletionInMacroArguments2_Bug200208() throws Exception {
|
||||||
|
final String[] expected= {"pIShell"};
|
||||||
|
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -867,4 +867,35 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest {
|
||||||
assertCompletionResults(expected);
|
assertCompletionResults(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define INIT_PTR(PtrName) (PtrName) = 0;
|
||||||
|
// struct CCApp {
|
||||||
|
// int pIShell;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int main(void) {
|
||||||
|
// struct CCApp *pThis = 0;
|
||||||
|
// INIT_PTR(pTh/*cursor*/);
|
||||||
|
// }
|
||||||
|
public void testCompletionInMacroArguments1_Bug200208() throws Exception {
|
||||||
|
final String[] expected= {"pThis"};
|
||||||
|
assertCompletionResults(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #define INIT_PTR(PtrName) (PtrName) = 0;
|
||||||
|
// #define COPY_PTR(pTarget, pSource) (pTarget) = (pSource)
|
||||||
|
//
|
||||||
|
// struct CCApp {
|
||||||
|
// int pIShell;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int main(void) {
|
||||||
|
// struct CCApp *pThis = 0;
|
||||||
|
//
|
||||||
|
// INIT_PTR(pThis);
|
||||||
|
// COPY_PTR(pThis->pIShell, pThis->pI/*cursor*/)
|
||||||
|
// }
|
||||||
|
public void testCompletionInMacroArguments2_Bug200208() throws Exception {
|
||||||
|
final String[] expected= {"pIShell"};
|
||||||
|
assertCompletionResults(expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue