1
0
Fork 0
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:
Markus Schorn 2008-04-21 14:02:40 +00:00
parent 7481b864e5
commit a0169fac0d
4 changed files with 135 additions and 14 deletions

View file

@ -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;
}
}

View file

@ -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);
TokenList result= expandAll(input, forbidden, isPPCondition, null);
input.prepend(firstExpansion);
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;

View file

@ -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);
}
}

View file

@ -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);
}
}