mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42: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);
|
||||
TokenList firstExpansion= new TokenList();
|
||||
|
||||
firstExpansion.append(new ExpansionBoundary(macro, true));
|
||||
expandOne(identifier, macro, forbidden, input, firstExpansion, null);
|
||||
firstExpansion.append(new ExpansionBoundary(macro, false));
|
||||
TokenList result;
|
||||
try {
|
||||
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);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -455,11 +465,17 @@ public class MacroExpander {
|
|||
case IToken.tEND_OF_INPUT:
|
||||
assert nesting >= 0;
|
||||
if (fCompletionMode) {
|
||||
t.setType(IToken.tCOMPLETION);
|
||||
if (idx < result.length) {
|
||||
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
||||
}
|
||||
throw new OffsetLimitReachedException(ORIGIN, null);
|
||||
}
|
||||
break loop;
|
||||
case IToken.tCOMPLETION:
|
||||
if (idx < result.length) {
|
||||
result[idx].append(t);
|
||||
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
||||
}
|
||||
throw new OffsetLimitReachedException(ORIGIN, t);
|
||||
|
||||
case Lexer.tNEWLINE:
|
||||
|
@ -840,13 +856,12 @@ public class MacroExpander {
|
|||
case IToken.tCHAR:
|
||||
case IToken.tLCHAR:
|
||||
final char[] image= t.getCharImage();
|
||||
for (int i = 0; i < image.length; i++) {
|
||||
final char c = image[i];
|
||||
if (c == '"' || c == '\\') {
|
||||
buf.append('\\');
|
||||
for (final char c : image) {
|
||||
if (c == '"' || c == '\\') {
|
||||
buf.append('\\');
|
||||
}
|
||||
buf.append(c);
|
||||
}
|
||||
buf.append(c);
|
||||
}
|
||||
space= false;
|
||||
break;
|
||||
|
||||
|
@ -911,6 +926,12 @@ public class MacroExpander {
|
|||
case CPreprocessor.tNOSPACE:
|
||||
replacement.removeBehind(l);
|
||||
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);
|
||||
l= t;
|
||||
|
|
|
@ -1059,4 +1059,39 @@ public class CompletionTests extends AbstractContentAssistTest {
|
|||
};
|
||||
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);
|
||||
}
|
||||
|
||||
// #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