mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
org.eclipse.cdt.core
Added CompletionKind.UNREACHABLE_CODE to IASTCompletionNode. Updated Scanner to handle unreachable code scenarios in content assist. Added Directives class to centralize preprocessor directive strings. Added keyword completion for preprocessor lines that start with #.
This commit is contained in:
parent
695df66284
commit
0dc064bbd6
5 changed files with 137 additions and 29 deletions
|
@ -1,3 +1,9 @@
|
|||
2004-02-01 John Camelon
|
||||
Added CompletionKind.UNREACHABLE_CODE to IASTCompletionNode.
|
||||
Updated Scanner to handle unreachable code scenarios in content assist.
|
||||
Added Directives class to centralize preprocessor directive strings.
|
||||
Added keyword completion for preprocessor lines that start with #.
|
||||
|
||||
2004-01-30 John Camelon
|
||||
Partial fix for Bug 47752 - Outline does not recognize functions with full body try/catch blocks
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2002,2003 Rational Software Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v0.5
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v05.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Rational Software - Initial API and implementation
|
||||
***********************************************************************/
|
||||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
public class Directives {
|
||||
|
||||
public static final String POUND_DEFINE = "#define";
|
||||
public static final String POUND_UNDEF = "#undef";
|
||||
public static final String POUND_IF = "#if";
|
||||
public static final String POUND_IFDEF = "#ifdef";
|
||||
public static final String POUND_IFNDEF = "#ifndef";
|
||||
public static final String POUND_ELSE = "#else";
|
||||
public static final String POUND_ENDIF = "#endif";
|
||||
public static final String POUND_INCLUDE = "#include";
|
||||
public static final String POUND_LINE = "#line";
|
||||
public static final String POUND_ERROR = "#error";
|
||||
public static final String POUND_PRAGMA = "#pragma";
|
||||
public static final String POUND_ELIF = "#elif";
|
||||
public static final String POUND_BLANK = "#";
|
||||
|
||||
}
|
|
@ -70,6 +70,9 @@ public interface IASTCompletionNode {
|
|||
// after a new expression
|
||||
public static final CompletionKind NEW_TYPE_REFERENCE = new CompletionKind( 16 );
|
||||
|
||||
// inside something that does not reach the parser - (#ifdefed out/comment)
|
||||
public static final CompletionKind UNREACHABLE_CODE = new CompletionKind( 17 );
|
||||
|
||||
// error condition -- a place in the grammar where there is nothing to lookup
|
||||
public static final CompletionKind NO_SUCH_KIND = new CompletionKind( 200 );
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.StringTokenizer;
|
|||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.core.parser.BacktrackException;
|
||||
import org.eclipse.cdt.core.parser.Directives;
|
||||
import org.eclipse.cdt.core.parser.EndOfFileException;
|
||||
import org.eclipse.cdt.core.parser.IMacroDescriptor;
|
||||
import org.eclipse.cdt.core.parser.IParser;
|
||||
|
@ -350,7 +351,7 @@ public class Scanner implements IScanner {
|
|||
|
||||
}
|
||||
|
||||
protected String getRestOfPreprocessorLine() throws ScannerException {
|
||||
protected String getRestOfPreprocessorLine() throws ScannerException, EndOfFileException {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
skipOverWhitespace();
|
||||
int c = getChar();
|
||||
|
@ -887,8 +888,7 @@ public class Scanner implements IScanner {
|
|||
|
||||
while (c != NOCHAR) {
|
||||
if ( ! passOnToClient ) {
|
||||
|
||||
|
||||
|
||||
while (c != NOCHAR && c != '#' )
|
||||
{
|
||||
c = getChar();
|
||||
|
@ -910,7 +910,12 @@ public class Scanner implements IScanner {
|
|||
}
|
||||
}
|
||||
|
||||
if( c == NOCHAR ) continue;
|
||||
if( c == NOCHAR )
|
||||
{
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((c == ' ') || (c == '\r') || (c == '\t') || (c == '\n')) {
|
||||
|
@ -1251,6 +1256,7 @@ public class Scanner implements IScanner {
|
|||
contextStack.getCurrentContext());
|
||||
|
||||
} else if (c == '#') {
|
||||
|
||||
int beginningOffset = contextStack.getCurrentContext().getOffset() - 1;
|
||||
int beginningLine = contextStack.getCurrentLineNumber();
|
||||
// lets prepare for a preprocessor statement
|
||||
|
@ -1278,10 +1284,14 @@ public class Scanner implements IScanner {
|
|||
buff.append((char) c);
|
||||
c = getChar();
|
||||
}
|
||||
|
||||
ungetChar(c);
|
||||
|
||||
String token = buff.toString();
|
||||
|
||||
if( isLimitReached() )
|
||||
handleCompletionOnPreprocessorDirective(token);
|
||||
|
||||
Object directive = ppDirectives.get(token);
|
||||
if (directive == null) {
|
||||
if (true)
|
||||
|
@ -1296,6 +1306,8 @@ public class Scanner implements IScanner {
|
|||
case PreprocessorDirectives.DEFINE :
|
||||
if ( ! passOnToClient ) {
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
c = getChar();
|
||||
continue;
|
||||
}
|
||||
|
@ -1308,6 +1320,8 @@ public class Scanner implements IScanner {
|
|||
case PreprocessorDirectives.INCLUDE :
|
||||
if (! passOnToClient ) {
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
c = getChar();
|
||||
continue;
|
||||
}
|
||||
|
@ -1318,7 +1332,10 @@ public class Scanner implements IScanner {
|
|||
continue;
|
||||
case PreprocessorDirectives.UNDEFINE :
|
||||
if (! passOnToClient) {
|
||||
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
c = getChar();
|
||||
continue;
|
||||
}
|
||||
|
@ -1369,6 +1386,9 @@ public class Scanner implements IScanner {
|
|||
continue;
|
||||
case PreprocessorDirectives.ENDIF :
|
||||
String restOfLine = getRestOfPreprocessorLine().trim();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
|
||||
if( ! restOfLine.equals( "" ) )
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer("#endif ");
|
||||
|
@ -1390,7 +1410,10 @@ public class Scanner implements IScanner {
|
|||
if (getDefinition(definition2) != null) {
|
||||
// not defined
|
||||
skipOverTextUntilNewline();
|
||||
passOnToClient = branches.poundIf( false );
|
||||
passOnToClient = branches.poundIf( false );
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
|
||||
} else {
|
||||
passOnToClient = branches.poundIf( true );
|
||||
// continue along, act like nothing is wrong :-)
|
||||
|
@ -1399,7 +1422,6 @@ public class Scanner implements IScanner {
|
|||
continue;
|
||||
|
||||
case PreprocessorDirectives.ELSE :
|
||||
//TODO add in content assist stuff here
|
||||
try
|
||||
{
|
||||
passOnToClient = branches.poundElse();
|
||||
|
@ -1413,6 +1435,9 @@ public class Scanner implements IScanner {
|
|||
}
|
||||
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
|
||||
c = getChar();
|
||||
continue;
|
||||
|
||||
|
@ -1450,11 +1475,16 @@ public class Scanner implements IScanner {
|
|||
|
||||
case PreprocessorDirectives.LINE :
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
c = getChar();
|
||||
continue;
|
||||
case PreprocessorDirectives.ERROR :
|
||||
if (! passOnToClient) {
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
|
||||
c = getChar();
|
||||
continue;
|
||||
}
|
||||
|
@ -1463,6 +1493,9 @@ public class Scanner implements IScanner {
|
|||
continue;
|
||||
case PreprocessorDirectives.PRAGMA :
|
||||
skipOverTextUntilNewline();
|
||||
if( isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
|
||||
c = getChar();
|
||||
continue;
|
||||
case PreprocessorDirectives.BLANK :
|
||||
|
@ -1825,7 +1858,7 @@ public class Scanner implements IScanner {
|
|||
/**
|
||||
* @param definition
|
||||
*/
|
||||
private void handleCompletionOnDefinition(String definition) throws EndOfFileException {
|
||||
protected void handleCompletionOnDefinition(String definition) throws EndOfFileException {
|
||||
IASTCompletionNode node = new ASTCompletionNode( IASTCompletionNode.CompletionKind.MACRO_REFERENCE,
|
||||
null, null, definition, KeywordSets.getKeywords(KeywordSets.Key.EMPTY, language) );
|
||||
|
||||
|
@ -1835,7 +1868,7 @@ public class Scanner implements IScanner {
|
|||
/**
|
||||
* @param expression2
|
||||
*/
|
||||
private void handleCompletionOnExpression(String expression) throws EndOfFileException {
|
||||
protected void handleCompletionOnExpression(String expression) throws EndOfFileException {
|
||||
int completionPoint = expression.length() + 2;
|
||||
IASTCompletionNode.CompletionKind kind = IASTCompletionNode.CompletionKind.MACRO_REFERENCE;
|
||||
|
||||
|
@ -1882,6 +1915,15 @@ public class Scanner implements IScanner {
|
|||
throwEOF( node );
|
||||
}
|
||||
|
||||
protected void handleInvalidCompletion() throws EndOfFileException
|
||||
{
|
||||
throwEOF( new ASTCompletionNode( IASTCompletionNode.CompletionKind.UNREACHABLE_CODE, null, null, "", KeywordSets.getKeywords(KeywordSets.Key.EMPTY, language) ));
|
||||
}
|
||||
|
||||
protected void handleCompletionOnPreprocessorDirective( String prefix ) throws EndOfFileException
|
||||
{
|
||||
throwEOF( new ASTCompletionNode( IASTCompletionNode.CompletionKind.NO_SUCH_KIND, null, null, prefix, KeywordSets.getKeywords(KeywordSets.Key.PP_DIRECTIVE, language )));
|
||||
}
|
||||
/**
|
||||
* @param key
|
||||
*/
|
||||
|
@ -1892,7 +1934,7 @@ public class Scanner implements IScanner {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
protected void handlePragmaOperator() throws ScannerException
|
||||
protected void handlePragmaOperator() throws ScannerException, EndOfFileException
|
||||
{
|
||||
// until we know what to do with pragmas, do the equivalent as
|
||||
// to what we do for #pragma blah blah blah (ignore it)
|
||||
|
@ -2140,21 +2182,19 @@ public class Scanner implements IScanner {
|
|||
cppKeywords.put( Keywords.XOR, new Integer(IToken.t_xor));
|
||||
cppKeywords.put( Keywords.XOR_EQ, new Integer(IToken.t_xor_eq));
|
||||
|
||||
ppDirectives.put("#define", new Integer(PreprocessorDirectives.DEFINE));
|
||||
ppDirectives.put("#undef",new Integer(PreprocessorDirectives.UNDEFINE));
|
||||
ppDirectives.put("#if", new Integer(PreprocessorDirectives.IF));
|
||||
ppDirectives.put("#ifdef", new Integer(PreprocessorDirectives.IFDEF));
|
||||
ppDirectives.put("#ifndef", new Integer(PreprocessorDirectives.IFNDEF));
|
||||
ppDirectives.put("#else", new Integer(PreprocessorDirectives.ELSE));
|
||||
ppDirectives.put("#endif", new Integer(PreprocessorDirectives.ENDIF));
|
||||
ppDirectives.put(
|
||||
"#include",
|
||||
new Integer(PreprocessorDirectives.INCLUDE));
|
||||
ppDirectives.put("#line", new Integer(PreprocessorDirectives.LINE));
|
||||
ppDirectives.put("#error", new Integer(PreprocessorDirectives.ERROR));
|
||||
ppDirectives.put("#pragma", new Integer(PreprocessorDirectives.PRAGMA));
|
||||
ppDirectives.put("#elif", new Integer(PreprocessorDirectives.ELIF));
|
||||
ppDirectives.put("#", new Integer(PreprocessorDirectives.BLANK));
|
||||
ppDirectives.put(Directives.POUND_DEFINE, new Integer(PreprocessorDirectives.DEFINE));
|
||||
ppDirectives.put(Directives.POUND_UNDEF,new Integer(PreprocessorDirectives.UNDEFINE));
|
||||
ppDirectives.put(Directives.POUND_IF, new Integer(PreprocessorDirectives.IF));
|
||||
ppDirectives.put(Directives.POUND_IFDEF, new Integer(PreprocessorDirectives.IFDEF));
|
||||
ppDirectives.put(Directives.POUND_IFNDEF, new Integer(PreprocessorDirectives.IFNDEF));
|
||||
ppDirectives.put(Directives.POUND_ELSE, new Integer(PreprocessorDirectives.ELSE));
|
||||
ppDirectives.put(Directives.POUND_ENDIF, new Integer(PreprocessorDirectives.ENDIF));
|
||||
ppDirectives.put(Directives.POUND_INCLUDE, new Integer(PreprocessorDirectives.INCLUDE));
|
||||
ppDirectives.put(Directives.POUND_LINE, new Integer(PreprocessorDirectives.LINE));
|
||||
ppDirectives.put(Directives.POUND_ERROR, new Integer(PreprocessorDirectives.ERROR));
|
||||
ppDirectives.put(Directives.POUND_PRAGMA, new Integer(PreprocessorDirectives.PRAGMA));
|
||||
ppDirectives.put(Directives.POUND_ELIF, new Integer(PreprocessorDirectives.ELIF));
|
||||
ppDirectives.put(Directives.POUND_BLANK, new Integer(PreprocessorDirectives.BLANK));
|
||||
|
||||
cKeywords.put( Keywords.AUTO, new Integer(IToken.t_auto));
|
||||
cKeywords.put( Keywords.BREAK, new Integer(IToken.t_break));
|
||||
|
@ -2268,7 +2308,7 @@ public class Scanner implements IScanner {
|
|||
}
|
||||
|
||||
|
||||
protected void skipOverSinglelineComment() throws ScannerException {
|
||||
protected void skipOverSinglelineComment() throws ScannerException, EndOfFileException {
|
||||
|
||||
StringBuffer comment = new StringBuffer("//");
|
||||
int c;
|
||||
|
@ -2285,10 +2325,12 @@ public class Scanner implements IScanner {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if( c== NOCHAR && isLimitReached() )
|
||||
handleInvalidCompletion();
|
||||
|
||||
}
|
||||
|
||||
protected boolean skipOverMultilineComment() throws ScannerException {
|
||||
protected boolean skipOverMultilineComment() throws ScannerException, EndOfFileException {
|
||||
int state = 0;
|
||||
boolean encounteredNewline = false;
|
||||
StringBuffer comment = new StringBuffer("/*");
|
||||
|
@ -2319,15 +2361,17 @@ public class Scanner implements IScanner {
|
|||
comment.append((char)c);
|
||||
}
|
||||
|
||||
if (c == NOCHAR)
|
||||
if (c == NOCHAR && !isLimitReached() )
|
||||
handleProblem( IProblem.SCANNER_UNEXPECTED_EOF, null, getCurrentOffset(), false, true );
|
||||
else if( c== NOCHAR ) // limit reached
|
||||
handleInvalidCompletion();
|
||||
|
||||
ungetChar(c);
|
||||
|
||||
return encounteredNewline;
|
||||
}
|
||||
|
||||
protected void poundInclude( int beginningOffset, int startLine ) throws ScannerException {
|
||||
protected void poundInclude( int beginningOffset, int startLine ) throws ScannerException, EndOfFileException {
|
||||
StringBuffer potentialErrorLine = new StringBuffer( "#include ");
|
||||
skipOverWhitespace();
|
||||
int baseOffset = lastContext.getOffset() - lastContext.undoStackSize();
|
||||
|
@ -2539,7 +2583,7 @@ public class Scanner implements IScanner {
|
|||
}
|
||||
|
||||
|
||||
protected void poundDefine(int beginning, int beginningLine ) throws ScannerException {
|
||||
protected void poundDefine(int beginning, int beginningLine ) throws ScannerException, EndOfFileException {
|
||||
StringBuffer potentialErrorMessage = new StringBuffer( POUND_DEFINE );
|
||||
skipOverWhitespace();
|
||||
// definition
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Hashtable;
|
|||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.eclipse.cdt.core.parser.Directives;
|
||||
import org.eclipse.cdt.core.parser.Enum;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
|
@ -36,6 +37,7 @@ public class KeywordSets {
|
|||
public static final Key FUNCTION_MODIFIER = new Key( 6 );
|
||||
public static final Key NAMESPACE_ONLY = new Key(6);
|
||||
public static final Key MACRO = new Key( 7 );
|
||||
public static final Key PP_DIRECTIVE = new Key( 8 );
|
||||
/**
|
||||
* @param enumValue
|
||||
*/
|
||||
|
@ -65,6 +67,8 @@ public class KeywordSets {
|
|||
return NAMESPACE_ONLY;
|
||||
if( kind == Key.MACRO )
|
||||
return MACRO_ONLY;
|
||||
if( kind == Key.PP_DIRECTIVE )
|
||||
return PP_DIRECTIVES;
|
||||
|
||||
//TODO finish this
|
||||
return null;
|
||||
|
@ -236,4 +240,23 @@ public class KeywordSets {
|
|||
FUNCTION_MODIFIER.put( ParserLanguage.CPP, FUNCTION_MODIFIER_CPP );
|
||||
FUNCTION_MODIFIER.put( ParserLanguage.C, FUNCTION_MODIFIER_C );
|
||||
}
|
||||
|
||||
private static final Set PP_DIRECTIVES;
|
||||
static
|
||||
{
|
||||
PP_DIRECTIVES = new TreeSet();
|
||||
PP_DIRECTIVES.add(Directives.POUND_BLANK);
|
||||
PP_DIRECTIVES.add(Directives.POUND_DEFINE);
|
||||
PP_DIRECTIVES.add(Directives.POUND_UNDEF);
|
||||
PP_DIRECTIVES.add(Directives.POUND_IF);
|
||||
PP_DIRECTIVES.add(Directives.POUND_IFDEF);
|
||||
PP_DIRECTIVES.add(Directives.POUND_IFNDEF);
|
||||
PP_DIRECTIVES.add(Directives.POUND_ELSE);
|
||||
PP_DIRECTIVES.add(Directives.POUND_ENDIF);
|
||||
PP_DIRECTIVES.add(Directives.POUND_INCLUDE);
|
||||
PP_DIRECTIVES.add(Directives.POUND_LINE);
|
||||
PP_DIRECTIVES.add(Directives.POUND_ERROR);
|
||||
PP_DIRECTIVES.add(Directives.POUND_PRAGMA);
|
||||
PP_DIRECTIVES.add(Directives.POUND_ELIF);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue