From 29a1fcb59c9291ffc625efa195b4e982a35874f1 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Mon, 29 Nov 2004 21:00:32 +0000 Subject: [PATCH] Patch for Devin Steffler. Fixed 79339 - Selection search fails on SDL/SDL.h --- .../parser/tests/CompleteParsePluginTest.java | 35 +++++++++++++++++++ .../core/parser/tests/FileBasePluginTest.java | 30 +++++++++++++++- .../org/eclipse/cdt/core/parser/IScanner.java | 1 + .../cdt/internal/core/parser/Parser.java | 6 ++-- .../ast/complete/CompleteParseASTFactory.java | 20 +++++------ .../core/parser/scanner2/Scanner2.java | 6 ++++ 6 files changed, 85 insertions(+), 13 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java index 3d0e7557675..911348f1382 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParsePluginTest.java @@ -14,6 +14,8 @@ */ package org.eclipse.cdt.core.parser.tests; +import java.io.StringWriter; +import java.io.Writer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -21,6 +23,9 @@ import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.ast.IASTFunction; +import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTVariable; import org.eclipse.core.resources.IFile; @@ -187,4 +192,34 @@ public class CompleteParsePluginTest extends FileBasePluginTest { assertEquals( i.next(), CallbackTracker.EXIT_COMPILATION_UNIT ); assertFalse( i.hasNext() ); } + + public void testBug79339() throws Exception{ + Writer writer = new StringWriter(); + writer.write("#ifndef _HEADER_\n"); //$NON-NLS-1$ + writer.write("#define _HEADER_\n"); //$NON-NLS-1$ + writer.write("#define ONE 1\n"); //$NON-NLS-1$ + writer.write("int foo(int);\n"); //$NON-NLS-1$ + writer.write("#endif // _HEADER_\n"); //$NON-NLS-1$ + String header = writer.toString(); + importFile( "header.h", header ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "#include \"header.h\" \n"); //$NON-NLS-1$ + writer.write( "int foo2(){\n"); //$NON-NLS-1$ + writer.write( " return foo(ONE);\n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "test.cpp", source ); //$NON-NLS-1$ + + int start = source.indexOf( "foo(ONE)" ); //$NON-NLS-1$ + + List calls = new ArrayList(); + IASTNode node = parse( cpp, calls, start, start + 3 ); //$NON-NLS-1$ + assertTrue(node instanceof IASTFunction); + IASTFunction foo = (IASTFunction)node; + assertEquals(foo.getStartingLine(), 4); + assertEquals(foo.getNameOffset(), 52); + assertEquals(foo.getName(), "foo"); //$NON-NLS-1$ + assertTrue(new String(foo.getFilename()).indexOf("header.h") > 0); //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java index b98f8774946..cea515dc9bd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FileBasePluginTest.java @@ -18,6 +18,7 @@ import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -31,6 +32,7 @@ import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.ISourceElementRequestor; import org.eclipse.cdt.core.parser.NullLogService; +import org.eclipse.cdt.core.parser.NullSourceElementRequestor; import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; @@ -58,6 +60,7 @@ import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTMethodReference; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; import org.eclipse.cdt.core.parser.ast.IASTNamespaceReference; +import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTParameterReference; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration; @@ -332,5 +335,30 @@ public class FileBasePluginTest extends TestCase { } return callback.getCompilationUnit(); } - + + protected IASTNode parse(IFile code, List callbacks, int start, int end) throws Exception + { + return parse(code, callbacks, start, end, true, ParserLanguage.CPP); + + } + + protected IASTNode parse(IFile code, List callbacks, int offset1, int offset2, boolean expectedToPass, ParserLanguage language) throws Exception { + callback = new CallbackTracker( callbacks ); + + IParser parser = ParserFactory.createParser( + ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), code.getCharset() ), new ScannerInfo(), //$NON-NLS-1$ + ParserMode.SELECTION_PARSE, language, callback, new NullLogService(), null ), callback, ParserMode.SELECTION_PARSE, language, null + ); + + IParser.ISelectionParseResult result =parser.parse( offset1, offset2 ); + if( expectedToPass ) + { + assertNotNull( result ); + String filename = result.getFilename(); + assertNotNull( filename ); + assertTrue( !filename.equals( "")); //$NON-NLS-1$ + return (IASTNode) result.getOffsetableNamedElement(); + } + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java index a5b219c06bc..cc6918418fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java @@ -37,4 +37,5 @@ public interface IScanner { public boolean isOnTopContext(); public CharArrayObjectMap getRealDefinitions(); public void cancel(); + public char[] getMainFilename(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index d188fb05426..96851a17a5a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -106,6 +106,7 @@ public class Parser implements IParserData, IParser protected int firstErrorLine = FIRST_ERROR_UNSET; private BacktrackException backtrack = new BacktrackException(); private int backtrackCount = 0; + private char[] parserStartFilename = null; protected final void throwBacktrack( IProblem problem ) throws BacktrackException { ++backtrackCount; @@ -2909,6 +2910,7 @@ public class Parser implements IParserData, IParser ISourceElementRequestor callback, ParserLanguage language, IParserLogService log, IParserExtension extension ) { + this.parserStartFilename = scanner.getMainFilename(); this.scanner = scanner; this.language = language; this.log = log; @@ -6576,7 +6578,7 @@ public class Parser implements IParserData, IParser */ protected void handleNewToken(IToken value) { if( mode != ParserMode.SELECTION_PARSE ) return; - if( value != null && scanner.isOnTopContext() ) + if( value != null && CharArrayUtils.equals(value.getFilename(), parserStartFilename)) { TraceUtil.outputTrace(log, "IToken provided w/offsets ", null, value.getOffset(), " & ", value.getEndOffset() ); //$NON-NLS-1$ //$NON-NLS-2$ boolean change = false; @@ -6749,7 +6751,7 @@ public class Parser implements IParserData, IParser protected void setGreaterNameContext(ITokenDuple tokenDuple) { if( mode != ParserMode.SELECTION_PARSE ) return; if( pastPointOfSelection ) return; - if( greaterContextDuple == null && scanner.isOnTopContext() && lastTokenOfDuple != null && firstTokenOfDuple != null ) + if( greaterContextDuple == null && lastTokenOfDuple != null && firstTokenOfDuple != null && CharArrayUtils.equals(tokenDuple.getFilename(), parserStartFilename)) { if( tokenDuple.getStartOffset() > lastTokenOfDuple.getEndOffset() ) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index 44a366a7232..6420fc84aaf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -1395,14 +1395,14 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto // 5.6 Multiplicative Operators: The operands of * and / shall have arithmetic or enumeration type; the operands of % shall have integral or enumeration type. if (kind == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY || kind == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE) { if( !lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); if( !rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); } else if (kind == IASTExpression.Kind.MULTIPLICATIVE_MODULUS) { if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // 5.7 Additive Operators: // For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a @@ -1416,24 +1416,24 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if (!((isLhsPointer && (isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ))) || (isRhsPointer && (isIntegralType(lhs, isRhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ))))) { if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); } } else if (kind == IASTExpression.Kind.ADDITIVE_MINUS) { if (!(isLhsPointer && (isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )))) { if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); } // 5.11, 5.12, 5.13: The operator applies only to integral or enumeration operands. } else if (kind == IASTExpression.Kind.ANDEXPRESSION || kind == IASTExpression.Kind.EXCLUSIVEOREXPRESSION || kind == IASTExpression.Kind.INCLUSIVEOREXPRESSION) { if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) ) - handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true + handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); } ITypeInfo info = TypeInfoProvider.newTypeInfo( ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java index 707bf7db0b1..36e07ee5743 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java @@ -3228,6 +3228,12 @@ public class Scanner2 implements IScanner, IScannerData { return workingCopies.iterator(); } + public char[] getMainFilename() { + if( bufferData != null && bufferData[0] != null && bufferData[0] instanceof CodeReader ) + return ((CodeReader)bufferData[0]).filename; + + return emptyCharArray; + } public final char[] getCurrentFilename() { for( int i = bufferStackPos; i >= 0; --i )