mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 45203. Added support for IWYU export pragmas.
This commit is contained in:
parent
51e56e5a8b
commit
e6bae40308
32 changed files with 576 additions and 118 deletions
|
@ -12,10 +12,10 @@ package org.eclipse.cdt.core.parser.tests.ast2;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.AbstractCharArray;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog;
|
||||
|
||||
public class TestLexerLog implements ILexerLog {
|
||||
|
||||
private ArrayList fComments= new ArrayList();
|
||||
private ArrayList fProblems= new ArrayList();
|
||||
private String fInput;
|
||||
|
@ -25,7 +25,7 @@ public class TestLexerLog implements ILexerLog {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset, AbstractCharArray input) {
|
||||
fComments.add(fInput.substring(offset, endOffset));
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ public class LocationMapTests extends BaseTestCase {
|
|||
}
|
||||
private LocationMap fLocationMap;
|
||||
private CPPASTTranslationUnit fTu;
|
||||
private CharArray fContent;
|
||||
|
||||
public static TestSuite suite() {
|
||||
return suite(LocationMapTests.class);
|
||||
|
@ -129,7 +130,8 @@ public class LocationMapTests extends BaseTestCase {
|
|||
}
|
||||
|
||||
private void init(char[] content) {
|
||||
fLocationMap.pushTranslationUnit(FN, new CharArray(content));
|
||||
fContent = new CharArray(content);
|
||||
fLocationMap.pushTranslationUnit(FN, fContent);
|
||||
fTu= new CPPASTTranslationUnit();
|
||||
fTu.setLocationResolver(fLocationMap);
|
||||
}
|
||||
|
@ -146,8 +148,7 @@ public class LocationMapTests extends BaseTestCase {
|
|||
IASTFileLocation loc= node.getFileLocation();
|
||||
checkLocation(loc, filename, offset, length, line, endline);
|
||||
assertEquals(sig, node.getRawSignature());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assertNull(node.getFileLocation());
|
||||
}
|
||||
}
|
||||
|
@ -169,8 +170,7 @@ public class LocationMapTests extends BaseTestCase {
|
|||
if (loc == null) {
|
||||
assertEquals(0, offset);
|
||||
assertEquals(0, length);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assertEquals(filename, loc.getFileName());
|
||||
assertEquals(offset, loc.getNodeOffset());
|
||||
assertEquals(length, loc.getNodeLength());
|
||||
|
@ -301,9 +301,9 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
public void testComment() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounteredComment(0, 0, false);
|
||||
fLocationMap.encounteredComment(1,3, true);
|
||||
fLocationMap.encounteredComment(5,16,true);
|
||||
fLocationMap.encounteredComment(0, 0, false, fContent);
|
||||
fLocationMap.encounteredComment(1, 3, true, fContent);
|
||||
fLocationMap.encounteredComment(5, 16, true, fContent);
|
||||
IASTComment[] comments= fLocationMap.getComments();
|
||||
assertEquals(3, comments.length);
|
||||
checkComment(comments[0], "", false, FN, 0, 0, 1, 1);
|
||||
|
@ -311,7 +311,6 @@ public class LocationMapTests extends BaseTestCase {
|
|||
checkComment(comments[2], "56789abcdef", true, FN, 5,11,1,1);
|
||||
}
|
||||
|
||||
|
||||
public void testProblems() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounterProblem(0, null, 0, 0);
|
||||
|
@ -479,9 +478,9 @@ public class LocationMapTests extends BaseTestCase {
|
|||
IASTName name2= fLocationMap.encounterImplicitMacroExpansion(macro2, null);
|
||||
ILocationCtx me = fLocationMap.pushMacroExpansion(110, 115, 125, 30, macro3, new IASTName[]{name1, name2}, new ImageLocationInfo[0]);
|
||||
// Comment in expansion
|
||||
fLocationMap.encounteredComment(116, 120, false);
|
||||
fLocationMap.encounteredComment(116, 120, false, fContent);
|
||||
// Comment right after expansion, reported before expansion completes.
|
||||
fLocationMap.encounteredComment(125, 140, false);
|
||||
fLocationMap.encounteredComment(125, 140, false, fContent);
|
||||
fLocationMap.popContext(me);
|
||||
checkComment(fLocationMap.getComments()[0], new String(LONGDIGITS, 116, 4), false, FN, 116, 4, 2, 2);
|
||||
checkComment(fLocationMap.getComments()[1], new String(LONGDIGITS, 125, 15), false, FN, 125, 15, 2, 2);
|
||||
|
@ -513,14 +512,14 @@ public class LocationMapTests extends BaseTestCase {
|
|||
// number: [6,15)[25,26)
|
||||
ILocationCtx i1= fLocationMap.pushInclusion(0, 2, 4, 6, new CharArray("b1b2b3b4b5"), "pre1", "pre1".toCharArray(), false, false, false);
|
||||
assertEquals("pre1", fLocationMap.getCurrentFilePath());
|
||||
fLocationMap.encounteredComment(2,4,true);
|
||||
fLocationMap.encounteredComment(2, 4, true, fContent);
|
||||
// number: [15,25)
|
||||
ILocationCtx i2= fLocationMap.pushInclusion(6, 7, 8, 9, new CharArray("c1c2c3c4c5"), "pre11", "pre11".toCharArray(), false, false, false);
|
||||
assertEquals("pre11", fLocationMap.getCurrentFilePath());
|
||||
fLocationMap.encounteredComment(2,6,true);
|
||||
fLocationMap.encounteredComment(2, 6, true, fContent);
|
||||
fLocationMap.popContext(i2);
|
||||
// add a comment before the include
|
||||
fLocationMap.encounteredComment(4,6,false);
|
||||
fLocationMap.encounteredComment(4, 6, false, fContent);
|
||||
|
||||
assertEquals("pre1", fLocationMap.getCurrentFilePath());
|
||||
fLocationMap.popContext(i1);
|
||||
|
@ -530,12 +529,11 @@ public class LocationMapTests extends BaseTestCase {
|
|||
// number [36, 46)
|
||||
ILocationCtx i3= fLocationMap.pushInclusion(0, 2, 4, 6, new CharArray("d1d2d3d4d5"), "pre2", "pre2".toCharArray(), false, false, false);
|
||||
assertEquals("pre2", fLocationMap.getCurrentFilePath());
|
||||
fLocationMap.encounteredComment(0,2,true);
|
||||
fLocationMap.encounteredComment(0, 2, true, fContent);
|
||||
fLocationMap.popContext(i3);
|
||||
fLocationMap.popContext(pre1);
|
||||
assertEquals(FN, fLocationMap.getCurrentFilePath());
|
||||
|
||||
|
||||
IASTComment[] comments= fLocationMap.getComments();
|
||||
checkComment(comments[0], "b2", true, "pre1", 2, 2, 1, 1);
|
||||
checkComment(comments[1], "c2c3", true, "pre11", 2, 4, 1, 1);
|
||||
|
|
|
@ -14,15 +14,15 @@ package org.eclipse.cdt.core.testplugin;
|
|||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
|
||||
public class TestScannerInfo implements IExtendedScannerInfo {
|
||||
public class TestScannerInfo extends ExtendedScannerInfo {
|
||||
private static final String[] EMPTY = {};
|
||||
private String[] fIncludes;
|
||||
private String[] fIncludeFiles;
|
||||
private String[] fMacroFiles;
|
||||
|
||||
public TestScannerInfo(String[] includes, String[] includeFiles, String[] macroFiles) {
|
||||
public TestScannerInfo(String[] includes, String[] macroFiles, String[] includeFiles) {
|
||||
fIncludes= includes;
|
||||
fIncludeFiles= includeFiles;
|
||||
fMacroFiles= macroFiles;
|
||||
|
|
|
@ -29,7 +29,7 @@ public class TestScannerProvider extends AbstractCExtension implements IScannerI
|
|||
|
||||
@Override
|
||||
public IScannerInfo getScannerInformation(IResource resource) {
|
||||
return new TestScannerInfo(sIncludes, sIncludeFiles, sMacroFiles);
|
||||
return new TestScannerInfo(sIncludes, sMacroFiles, sIncludeFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.core.model.IContributedModelBuilder;
|
|||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.AbstractCharArray;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||
|
@ -42,7 +43,8 @@ public class AsmModelBuilder implements IContributedModelBuilder {
|
|||
|
||||
private static final class LexerLog implements ILexerLog {
|
||||
@Override
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset,
|
||||
AbstractCharArray input) {
|
||||
}
|
||||
@Override
|
||||
public void handleProblem(int problemID, char[] info, int offset, int endOffset) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2012 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2013 QNX Software Systems 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
|
||||
|
@ -58,13 +58,13 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
|
|||
import org.eclipse.cdt.core.model.IUsing;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.IParserLogService;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
|
||||
|
@ -1045,14 +1045,15 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
return scanInfo;
|
||||
}
|
||||
if (force) {
|
||||
return new ScannerInfo();
|
||||
return new ExtendedScannerInfo();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the language of the context this file was parsed in. Works only after using
|
||||
* {@link #getAST(IIndex, int, IProgressMonitor)} with the flag {@link ITranslationUnit#AST_CONFIGURE_USING_SOURCE_CONTEXT}.
|
||||
* {@link #getAST(IIndex, int, IProgressMonitor)} with the flag
|
||||
* {@link ITranslationUnit#AST_CONFIGURE_USING_SOURCE_CONTEXT}.
|
||||
*/
|
||||
public ILanguage getLanguageOfContext() throws CoreException {
|
||||
final ILanguage result= fLanguageOfContext;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2012 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2013 IBM Corporation 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
|
||||
|
@ -106,6 +106,14 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatem
|
|||
*/
|
||||
public boolean isErrorInIncludedFile();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the included file is exported by the including header.
|
||||
*
|
||||
* @see "https://code.google.com/p/include-what-you-use/wiki/IWYUPragmas"
|
||||
* @since 5.5
|
||||
*/
|
||||
public boolean isIncludedFileExported();
|
||||
|
||||
/**
|
||||
* Returns {@code true}, if an attempt will be or has been made to create AST for the target
|
||||
* of this inclusion.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2013 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
|
||||
|
@ -97,21 +97,28 @@ public interface IIndexInclude {
|
|||
* Test whether this include has been resolved (found in the file system).
|
||||
* Inactive includes are not resolved, unless they constitute a hidden dependency.
|
||||
* This is the case when an include is inactive because it has been included before:
|
||||
* <code>
|
||||
* <pre>
|
||||
* #ifndef _header_h
|
||||
* #include "header.h"
|
||||
* #endif
|
||||
* <code>
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @return whether this is a resolved include
|
||||
* @throws CoreException
|
||||
*/
|
||||
boolean isResolved() throws CoreException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests whether this include has been resolved using a heuristics rather than relying on
|
||||
* the include search path.
|
||||
* @since 5.1
|
||||
*/
|
||||
boolean isResolvedByHeuristics() throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the included file is exported by the including header.
|
||||
* @see "https://code.google.com/p/include-what-you-use/wiki/IWYUPragmas"
|
||||
* @since 5.5
|
||||
*/
|
||||
boolean isIncludedFileExported() throws CoreException;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ public class IndexLocationFactory {
|
|||
public static IIndexFileLocation getIFL(ITranslationUnit tu) {
|
||||
IResource res = tu.getResource();
|
||||
if (res instanceof IFile) {
|
||||
return getWorkspaceIFL((IFile)res);
|
||||
return getWorkspaceIFL((IFile) res);
|
||||
}
|
||||
IPath location = tu.getLocation();
|
||||
if (location != null) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2009 IBM Corporation and others.
|
||||
* Copyright (c) 2005, 2013 IBM Corporation 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Rational Software - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
|
@ -16,12 +17,14 @@ import java.util.Map;
|
|||
/**
|
||||
* Implementation for the {@link IExtendedScannerInfo} interface. Allows to configure
|
||||
* the preprocessor.
|
||||
* @since 5.5
|
||||
*/
|
||||
public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScannerInfo {
|
||||
private static final String[] EMPTY_STRING_ARRAY = {};
|
||||
private String[] macroFiles;
|
||||
private String[] includeFiles;
|
||||
private String[] localIncludePaths;
|
||||
private IncludeExportPatterns includeExportPatterns;
|
||||
|
||||
public ExtendedScannerInfo() {
|
||||
}
|
||||
|
@ -56,6 +59,9 @@ public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScanner
|
|||
includeFiles = einfo.getIncludeFiles();
|
||||
localIncludePaths = einfo.getLocalIncludePath();
|
||||
}
|
||||
if (info instanceof ExtendedScannerInfo) {
|
||||
includeExportPatterns = ((ExtendedScannerInfo) info).includeExportPatterns;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,4 +84,26 @@ public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScanner
|
|||
return EMPTY_STRING_ARRAY;
|
||||
return localIncludePaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the regular expression patterns matching export directives for included files.
|
||||
* @see IncludeExportPatterns
|
||||
*
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @since 5.5
|
||||
*/
|
||||
public IncludeExportPatterns getIncludeExportPatterns() {
|
||||
return includeExportPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the regular expression patterns matching export directives for included files.
|
||||
* @see IncludeExportPatterns
|
||||
*
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @since 5.5
|
||||
*/
|
||||
public void setIncludeExportPatterns(IncludeExportPatterns patterns) {
|
||||
includeExportPatterns= patterns;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003, 2009 IBM Corporation and others.
|
||||
* Copyright (c) 2003, 2013 IBM Corporation 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
|
||||
|
@ -8,24 +8,19 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
|
||||
|
||||
/**
|
||||
* Interface between the parser and the preprocessor.
|
||||
* <p>
|
||||
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
|
||||
* part of a work in progress. There is no guarantee that this API will
|
||||
* work or that it will remain the same. Please do not use this API without
|
||||
* consulting with the CDT team.
|
||||
* </p>
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
|
@ -75,12 +70,25 @@ public interface IScanner {
|
|||
|
||||
/**
|
||||
* Turns on/off creation of image locations.
|
||||
* @see IASTName#getImageLocation()
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTName#getImageLocation()
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void setComputeImageLocations(boolean val);
|
||||
|
||||
|
||||
/**
|
||||
* Turns on/off tracking if exported included files.
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement#isIncludedFileExported()
|
||||
* @see IncludeExportPatterns
|
||||
*
|
||||
* @param patterns if not {{@code null}, include export tracking is enabled, otherwise it is
|
||||
* disabled
|
||||
*
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @since 5.5
|
||||
*/
|
||||
public void setTrackIncludeExport(IncludeExportPatterns patterns);
|
||||
|
||||
/**
|
||||
* Toggles generation of tokens for inactive code branches. When turned on,
|
||||
* each inactive code branch is preceded by a token of kind {@link IToken#tINACTIVE_CODE_START} and
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Google, 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:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* Container for include export patterns, for example "IWYU pragma: export",
|
||||
* "IWYU pragma: begin_exports" and "IWYU pragma: end_exports".
|
||||
* @see "https://code.google.com/p/include-what-you-use/wiki/IWYUPragmas"
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
public class IncludeExportPatterns {
|
||||
private final Pattern includeExportPattern;
|
||||
private final Pattern includeBeginExportsPattern;
|
||||
private final Pattern includeEndExportsPattern;
|
||||
|
||||
public IncludeExportPatterns(String exportPattern, String beginExportsPattern,
|
||||
String endExportsPattern) {
|
||||
this.includeExportPattern = compilePattern(exportPattern);
|
||||
this.includeBeginExportsPattern = compilePattern(beginExportsPattern);
|
||||
this.includeEndExportsPattern = compilePattern(endExportsPattern);
|
||||
}
|
||||
|
||||
private Pattern compilePattern(String pattern) {
|
||||
try {
|
||||
return pattern == null ? null : Pattern.compile(pattern);
|
||||
} catch (PatternSyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the include export pattern, e.g. "IWYU pragma: export".
|
||||
*/
|
||||
public Pattern getIncludeExportPattern() {
|
||||
return includeExportPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the include export pattern, e.g. "IWYU pragma: begin_exports".
|
||||
*/
|
||||
public Pattern getIncludeBeginExportsPattern() {
|
||||
return includeBeginExportsPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the include export pattern, e.g. "IWYU pragma: end_exports".
|
||||
*/
|
||||
public Pattern getIncludeEndExportsPattern() {
|
||||
return includeEndExportsPattern;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2012 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2013 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
|
||||
|
@ -291,6 +291,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
private final boolean fIsResolved;
|
||||
private final boolean fIsSystemInclude;
|
||||
private final boolean fFoundByHeuristics;
|
||||
private final boolean fIncludedFileExported;
|
||||
private final IFileNomination fNominationDelegate;
|
||||
private boolean fPragmaOnce;
|
||||
private boolean fCreatesAST;
|
||||
|
@ -305,7 +306,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
public ASTInclusionStatement(IASTTranslationUnit parent,
|
||||
int startNumber, int nameStartNumber, int nameEndNumber, int endNumber,
|
||||
char[] headerName, String filePath, boolean userInclude, boolean active, boolean heuristic,
|
||||
IFileNomination nominationDelegate) {
|
||||
boolean exportedFile, IFileNomination nominationDelegate) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||
fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME,
|
||||
nameStartNumber, nameEndNumber, headerName, null);
|
||||
|
@ -315,6 +316,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
fFoundByHeuristics= heuristic;
|
||||
fSignificantMacros= ISignificantMacros.NONE;
|
||||
fNominationDelegate= nominationDelegate;
|
||||
fIncludedFileExported= exportedFile;
|
||||
if (!active) {
|
||||
setInactive();
|
||||
}
|
||||
|
@ -459,6 +461,11 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
fErrorInIncludedFile= error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedFileExported() {
|
||||
return fIncludedFileExported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createsAST() {
|
||||
return fCreatesAST;
|
||||
|
|
|
@ -48,11 +48,18 @@ public abstract class AbstractCharArray {
|
|||
public abstract char get(int offset);
|
||||
|
||||
/**
|
||||
* Copy a range of characters to the given destination. Subclasses do not have to do any
|
||||
* Copies a range of characters to the given destination. Subclasses do not have to do any
|
||||
* range checks.
|
||||
*/
|
||||
public abstract void arraycopy(int offset, char[] destination, int destinationPos, int length);
|
||||
|
||||
/**
|
||||
* Returns the {@link CharSequence} representing a range in the character array.
|
||||
*/
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return new SubArray(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if there were I/O errors while retrieving contents of this array.
|
||||
*/
|
||||
|
@ -69,4 +76,40 @@ public abstract class AbstractCharArray {
|
|||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private class SubArray implements CharSequence {
|
||||
private final int start;
|
||||
private final int end;
|
||||
|
||||
SubArray(int start, int end) {
|
||||
checkStartEnd(start, end);
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charAt(int index) {
|
||||
return get(start + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
checkStartEnd(start, end);
|
||||
if (end > this.end - this.start)
|
||||
throw new IndexOutOfBoundsException(String.valueOf(end));
|
||||
return new SubArray(this.start + start, this.start + end);
|
||||
}
|
||||
|
||||
private void checkStartEnd(int start, int end) {
|
||||
if (start < 0)
|
||||
throw new IndexOutOfBoundsException(String.valueOf(start));
|
||||
if (end < start)
|
||||
throw new IndexOutOfBoundsException(String.valueOf(end) + " < " + String.valueOf(start)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2012 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2013 IBM Corporation 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
|
||||
|
@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
|
|||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.parser.AbstractParserLogService;
|
||||
import org.eclipse.cdt.core.parser.EndOfFileException;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IMacro;
|
||||
|
@ -42,6 +43,7 @@ import org.eclipse.cdt.core.parser.IScanner;
|
|||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.IncludeExportPatterns;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||
|
@ -290,6 +292,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
fLexOptions.fSupportSlashPercentComments= configuration.supportSlashPercentComments();
|
||||
fLexOptions.fSupportUTFLiterals = configuration.supportUTFLiterals();
|
||||
fLexOptions.fSupportRawStringLiterals = configuration.supportRawStringLiterals();
|
||||
if (info instanceof ExtendedScannerInfo)
|
||||
fLexOptions.fIncludeExportPatterns = ((ExtendedScannerInfo) info).getIncludeExportPatterns();
|
||||
fLocationMap= new LocationMap(fLexOptions);
|
||||
fKeywords= new CharArrayIntMap(40, -1);
|
||||
fPPKeywords= new CharArrayIntMap(40, -1);
|
||||
|
@ -349,6 +353,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
fLexOptions.fCreateImageLocations= val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrackIncludeExport(IncludeExportPatterns patterns) {
|
||||
fLexOptions.fIncludeExportPatterns= patterns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentAssistMode(int offset) {
|
||||
fContentAssistLimit= offset;
|
||||
|
@ -1205,8 +1214,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
|
||||
fLocationMap.encounteredComment(offset, endOffset, isBlockComment);
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset, AbstractCharArray input) {
|
||||
fLocationMap.encounteredComment(offset, endOffset, isBlockComment, input);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.eclipse.cdt.core.parser.IProblem;
|
|||
public interface ILexerLog {
|
||||
ILexerLog NULL = new ILexerLog() {
|
||||
@Override
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset) {}
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset, AbstractCharArray input) {}
|
||||
@Override
|
||||
public void handleProblem(int problemID, char[] info, int offset, int endOffset) {}
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ public interface ILexerLog {
|
|||
* @param source the input of the lexer.
|
||||
* @param offset the offset where the comment starts
|
||||
* @param endOffset the offset where the comment ends
|
||||
* @param input the contents of the file being parsed
|
||||
*/
|
||||
void handleComment(boolean isBlockComment, int offset, int endOffset);
|
||||
void handleComment(boolean isBlockComment, int offset, int endOffset, AbstractCharArray input);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.parser.scanner;
|
|||
import org.eclipse.cdt.core.parser.IGCCToken;
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.IncludeExportPatterns;
|
||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
||||
|
@ -56,6 +57,7 @@ final public class Lexer implements ITokenSequence {
|
|||
public boolean fSupportSlashPercentComments= false;
|
||||
public boolean fSupportUTFLiterals= true;
|
||||
public boolean fSupportRawStringLiterals= false;
|
||||
public IncludeExportPatterns fIncludeExportPatterns;
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
|
@ -694,21 +696,21 @@ final public class Lexer implements ITokenSequence {
|
|||
}
|
||||
|
||||
private void blockComment(final int start, final char trigger) {
|
||||
// we can ignore line-splices, trigraphs and windows newlines when searching for the '*'
|
||||
// We can ignore line-splices, trigraphs and windows newlines when searching for the '*'
|
||||
int pos= fEndOffset;
|
||||
while (isValidOffset(pos)) {
|
||||
if (fInput.get(pos++) == trigger) {
|
||||
fEndOffset= pos;
|
||||
if (nextCharPhase3() == '/') {
|
||||
nextCharPhase3();
|
||||
fLog.handleComment(true, start, fOffset);
|
||||
fLog.handleComment(true, start, fOffset, fInput);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
fCharPhase3= END_OF_INPUT;
|
||||
fOffset= fEndOffset= pos;
|
||||
fLog.handleComment(true, start, pos);
|
||||
fLog.handleComment(true, start, pos, fInput);
|
||||
}
|
||||
|
||||
private void lineComment(final int start) {
|
||||
|
@ -717,7 +719,7 @@ final public class Lexer implements ITokenSequence {
|
|||
switch (c) {
|
||||
case END_OF_INPUT:
|
||||
case '\n':
|
||||
fLog.handleComment(false, start, fOffset);
|
||||
fLog.handleComment(false, start, fOffset, fInput);
|
||||
return;
|
||||
}
|
||||
c= nextCharPhase3();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2013 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
@ -24,6 +25,8 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
private final String fFilename;
|
||||
private final ASTInclusionStatement fASTInclude;
|
||||
private final boolean fIsSource;
|
||||
private boolean fInsideIncludeExportBlock;
|
||||
private int fOffsetOfIncludeExport = -1;
|
||||
|
||||
public LocationCtxFile(LocationCtxContainer parent, String filename, AbstractCharArray source,
|
||||
int parentOffset, int parentEndOffset, int sequenceNumber,
|
||||
|
@ -46,9 +49,9 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
|
||||
@Override
|
||||
public ASTFileLocation findMappedFileLocation(int sequenceNumber, int length) {
|
||||
// try to delegate to a child.
|
||||
// Try to delegate to a child.
|
||||
final int testEnd= length > 1 ? sequenceNumber + length - 1 : sequenceNumber;
|
||||
final int sequenceEnd= sequenceNumber+length;
|
||||
final int sequenceEnd= sequenceNumber + length;
|
||||
final LocationCtx child1= findChildLessOrEqualThan(sequenceNumber, false);
|
||||
final LocationCtx child2= testEnd == sequenceNumber ?
|
||||
child1 : findChildLessOrEqualThan(testEnd, false);
|
||||
|
@ -58,17 +61,17 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
return child1.findMappedFileLocation(sequenceNumber, length);
|
||||
}
|
||||
|
||||
// handle here
|
||||
// Handle here.
|
||||
int startOffset;
|
||||
int endOffset;
|
||||
|
||||
if (child1 == null) {
|
||||
startOffset= sequenceNumber-fSequenceNumber;
|
||||
startOffset= sequenceNumber - fSequenceNumber;
|
||||
} else {
|
||||
int childSequenceEnd= child1.fSequenceNumber + child1.getSequenceLength();
|
||||
if (sequenceNumber < childSequenceEnd) {
|
||||
startOffset= child1.fOffsetInParent;
|
||||
} else { // start beyond child1
|
||||
} else { // Start beyond child1
|
||||
startOffset= child1.fEndOffsetInParent + sequenceNumber - childSequenceEnd;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +79,7 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
endOffset= sequenceEnd - fSequenceNumber;
|
||||
} else {
|
||||
int childSequenceEnd= child2.fSequenceNumber + child2.getSequenceLength();
|
||||
if (childSequenceEnd < sequenceEnd) { // beyond child2
|
||||
if (childSequenceEnd < sequenceEnd) { // Beyond child2
|
||||
endOffset= child2.fEndOffsetInParent + sequenceEnd - childSequenceEnd;
|
||||
} else {
|
||||
endOffset= child2.fEndOffsetInParent;
|
||||
|
@ -112,12 +115,12 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
ArrayList<IASTPreprocessorMacroExpansion> list) {
|
||||
Collection<LocationCtx> children= getChildren();
|
||||
for (LocationCtx ctx : children) {
|
||||
// context must start before the end of the search range
|
||||
// Context must start before the end of the search range.
|
||||
if (ctx.fOffsetInParent >= offset+length) {
|
||||
break;
|
||||
}
|
||||
if (ctx instanceof LocationCtxMacroExpansion) {
|
||||
// expansion must end after the search start
|
||||
// Expansion must end after the search start.
|
||||
if (ctx.fEndOffsetInParent > offset) {
|
||||
IASTNode macroExpansion =
|
||||
((LocationCtxMacroExpansion) ctx).getMacroReference().getParent();
|
||||
|
@ -136,4 +139,20 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
public String toString() {
|
||||
return fFilename;
|
||||
}
|
||||
|
||||
public boolean isInsideIncludeExportBlock() {
|
||||
return fInsideIncludeExportBlock;
|
||||
}
|
||||
|
||||
public void setInsideIncludeExportBlock(boolean fInsideIncludeExportBlock) {
|
||||
this.fInsideIncludeExportBlock = fInsideIncludeExportBlock;
|
||||
}
|
||||
|
||||
public int getOffsetOfIncludeExport() {
|
||||
return fOffsetOfIncludeExport;
|
||||
}
|
||||
|
||||
public void setOffsetOfIncludeExport(int fOffsetOfIncludeExport) {
|
||||
this.fOffsetOfIncludeExport = fOffsetOfIncludeExport;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2013 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - Initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
@ -32,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IncludeExportPatterns;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
@ -126,17 +128,21 @@ public class LocationMap implements ILocationResolver {
|
|||
* @param name name of the include without delimiters ("" or <>)
|
||||
* @param userInclude <code>true</code> when specified with double-quotes.
|
||||
*/
|
||||
public ILocationCtx pushInclusion(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||
AbstractCharArray buffer, String filename, char[] name, boolean userInclude, boolean heuristic, boolean isSource) {
|
||||
public ILocationCtx pushInclusion(int startOffset, int nameOffset, int nameEndOffset,
|
||||
int endOffset, AbstractCharArray buffer, String filename, char[] name,
|
||||
boolean userInclude, boolean heuristic, boolean isSource) {
|
||||
assert fCurrentContext instanceof LocationCtxContainer;
|
||||
int startNumber= getSequenceNumberForOffset(startOffset);
|
||||
int nameNumber= getSequenceNumberForOffset(nameOffset);
|
||||
int nameEndNumber= getSequenceNumberForOffset(nameEndOffset);
|
||||
int endNumber= getSequenceNumberForOffset(endOffset);
|
||||
boolean exported = isExportedIncludeAt(endOffset);
|
||||
final ASTInclusionStatement inclusionStatement=
|
||||
new ASTInclusionStatement(fTranslationUnit, startNumber, nameNumber, nameEndNumber, endNumber, name, filename, userInclude, true, heuristic, null);
|
||||
new ASTInclusionStatement(fTranslationUnit, startNumber, nameNumber, nameEndNumber,
|
||||
endNumber, name, filename, userInclude, true, heuristic, exported, null);
|
||||
fDirectives.add(inclusionStatement);
|
||||
fCurrentContext= new LocationCtxFile((LocationCtxContainer) fCurrentContext, filename, buffer, startOffset, endOffset, endNumber, inclusionStatement, isSource);
|
||||
fCurrentContext= new LocationCtxFile((LocationCtxContainer) fCurrentContext, filename, buffer,
|
||||
startOffset, endOffset, endNumber, inclusionStatement, isSource);
|
||||
fLastChildInsertionOffset= 0;
|
||||
return fCurrentContext;
|
||||
}
|
||||
|
@ -230,21 +236,70 @@ public class LocationMap implements ILocationResolver {
|
|||
* @param userInclude <code>true</code> when specified with double-quotes.
|
||||
* @param active <code>true</code> when include appears in active code.
|
||||
*/
|
||||
public ASTInclusionStatement encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||
char[] name, String filename, boolean userInclude, boolean active, boolean heuristic,
|
||||
IFileNomination nominationDelegate) {
|
||||
public ASTInclusionStatement encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset,
|
||||
int endOffset, char[] name, String filename, boolean userInclude, boolean active,
|
||||
boolean heuristic, IFileNomination nominationDelegate) {
|
||||
boolean exported = isExportedIncludeAt(endOffset);
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
||||
endOffset= getSequenceNumberForOffset(endOffset);
|
||||
final ASTInclusionStatement inc = new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset,
|
||||
nameEndOffset, endOffset, name, filename, userInclude, active, heuristic, nominationDelegate);
|
||||
final ASTInclusionStatement inc = new ASTInclusionStatement(fTranslationUnit, startOffset,
|
||||
nameOffset, nameEndOffset, endOffset, name, filename, userInclude, active, heuristic,
|
||||
exported, nominationDelegate);
|
||||
fDirectives.add(inc);
|
||||
return inc;
|
||||
}
|
||||
|
||||
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
||||
fComments.add(new ASTComment(fTranslationUnit, getCurrentFilePath(), offset, endOffset, isBlockComment));
|
||||
private boolean isExportedIncludeAt(int includeEndOffset) {
|
||||
boolean exported = false;
|
||||
if (fLexerOptions.fIncludeExportPatterns != null && fCurrentContext instanceof LocationCtxFile) {
|
||||
LocationCtxFile context = (LocationCtxFile) fCurrentContext;
|
||||
exported = context.isInsideIncludeExportBlock();
|
||||
if (!exported) {
|
||||
int distance = context.getOffsetOfIncludeExport() - includeEndOffset;
|
||||
if (distance >= 0 &&
|
||||
CharArrayUtils.indexOf('\n', context.getSource(includeEndOffset, distance)) < 0) {
|
||||
exported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return exported;
|
||||
}
|
||||
|
||||
public void encounteredComment(int offset, int endOffset, boolean isBlockComment, AbstractCharArray input) {
|
||||
ASTComment comment = new ASTComment(fTranslationUnit, getCurrentFilePath(), offset, endOffset, isBlockComment);
|
||||
if (fLexerOptions.fIncludeExportPatterns != null && fCurrentContext instanceof LocationCtxFile) {
|
||||
CharSequence text = getTrimmedCommentText(input.subSequence(offset, endOffset), isBlockComment);
|
||||
IncludeExportPatterns patterns = fLexerOptions.fIncludeExportPatterns;
|
||||
if (patterns.getIncludeExportPattern() != null
|
||||
&& patterns.getIncludeExportPattern().matcher(text).matches()) {
|
||||
((LocationCtxFile) fCurrentContext).setOffsetOfIncludeExport(offset);
|
||||
} else if (patterns.getIncludeBeginExportsPattern() != null
|
||||
&& patterns.getIncludeBeginExportsPattern().matcher(text).matches()) {
|
||||
((LocationCtxFile) fCurrentContext).setInsideIncludeExportBlock(true);
|
||||
} else if (patterns.getIncludeEndExportsPattern() != null
|
||||
&& patterns.getIncludeEndExportsPattern().matcher(text).matches()) {
|
||||
((LocationCtxFile) fCurrentContext).setInsideIncludeExportBlock(false);
|
||||
}
|
||||
}
|
||||
fComments.add(comment);
|
||||
}
|
||||
|
||||
private CharSequence getTrimmedCommentText(CharSequence comment, boolean isBlockComment) {
|
||||
int end = comment.length() - (isBlockComment ? 2 : 0);
|
||||
int begin;
|
||||
for (begin = 2; begin < end; begin++) {
|
||||
if (!Character.isWhitespace(comment.charAt(begin)))
|
||||
break;
|
||||
}
|
||||
if (end <= begin)
|
||||
return ""; //$NON-NLS-1$
|
||||
while (--end >= begin) {
|
||||
if (!Character.isWhitespace(comment.charAt(end)))
|
||||
break;
|
||||
}
|
||||
return comment.subSequence(begin, end + 1);
|
||||
}
|
||||
|
||||
public void encounterProblem(int id, char[] arg, int offset, int endOffset) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2012 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2013 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
|
||||
|
@ -42,10 +42,12 @@ import org.eclipse.cdt.core.index.IndexLocationFactory;
|
|||
import org.eclipse.cdt.core.model.AbstractLanguage;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.IParserLogService;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IncludeExportPatterns;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||
|
@ -394,6 +396,10 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected IncludeExportPatterns getIncludeExportPatterns() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of linkage IDs that shall be parsed
|
||||
*/
|
||||
|
@ -483,6 +489,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
fASTOptions= ILanguage.OPTION_NO_IMAGE_LOCATIONS
|
||||
| ILanguage.OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS;
|
||||
|
||||
if (getSkipReferences() == SKIP_ALL_REFERENCES) {
|
||||
fASTOptions |= ILanguage.OPTION_SKIP_FUNCTION_BODIES;
|
||||
}
|
||||
|
@ -826,7 +833,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (monitor.isCanceled() || hasUrgentTasks())
|
||||
return;
|
||||
final Object tu = locTask.fTu;
|
||||
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, tu);
|
||||
final IScannerInfo scannerInfo = getScannerInfo(linkageID, tu);
|
||||
parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor);
|
||||
}
|
||||
}
|
||||
|
@ -860,7 +867,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (monitor.isCanceled() || hasUrgentTasks())
|
||||
return;
|
||||
final Object tu = locTask.fTu;
|
||||
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, tu);
|
||||
final IScannerInfo scannerInfo= getScannerInfo(linkageID, tu);
|
||||
parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor);
|
||||
if (locTask.isCompleted())
|
||||
it.remove();
|
||||
|
@ -904,7 +911,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
final int safeguardSize= safeGuard.size();
|
||||
while (true) {
|
||||
// Look for a context and parse the file
|
||||
// Look for a context and parse the file.
|
||||
IIndexFragmentFile ctxFile = findContextFile(linkageID, map, versionTask, safeGuard, monitor);
|
||||
if (ctxFile == null || ctxFile == headerFile)
|
||||
return;
|
||||
|
@ -913,7 +920,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (contextTu == null)
|
||||
return;
|
||||
|
||||
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, contextTu);
|
||||
final IScannerInfo scannerInfo = getScannerInfo(linkageID, contextTu);
|
||||
final AbstractLanguage language = getLanguage(contextTu, linkageID);
|
||||
final FileContext ctx= new FileContext(ctxFile, headerFile);
|
||||
Set<IIndexFile> dependencies= null;
|
||||
|
@ -923,7 +930,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
DependsOnOutdatedFileException d= parseFile(tu, language, ifl, scannerInfo, ctx, monitor);
|
||||
if (d != null) {
|
||||
// File was not parsed, because there is a dependency that needs to be
|
||||
// handled before
|
||||
// handled before.
|
||||
if (dependencies == null)
|
||||
dependencies= new HashSet<IIndexFile>();
|
||||
if (dependencies.add(d.fIndexFile)) {
|
||||
|
@ -940,6 +947,14 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private IScannerInfo getScannerInfo(int linkageID, Object contextTu) {
|
||||
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, contextTu);
|
||||
if (scannerInfo instanceof ExtendedScannerInfo) {
|
||||
((ExtendedScannerInfo) scannerInfo).setIncludeExportPatterns(getIncludeExportPatterns());
|
||||
}
|
||||
return scannerInfo;
|
||||
}
|
||||
|
||||
private void restoreSet(LinkedHashSet<?> set, int restoreSize) {
|
||||
for (Iterator<?> it = set.iterator(); it.hasNext();) {
|
||||
it.next();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2006, 2013 QNX Software Systems 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
|
||||
|
@ -46,6 +46,7 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
|||
private static final int FLAG_INACTIVE_INCLUDE = 0x02;
|
||||
private static final int FLAG_RESOLVED_BY_HEURISTICS= 0x04;
|
||||
private static final int FLAG_DEDUCIBLE_NAME = 0x08;
|
||||
private static final int FLAG_EXPORTED_FILE = 0x10;
|
||||
|
||||
private final PDOMLinkage linkage;
|
||||
private final long record;
|
||||
|
@ -97,6 +98,9 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
|||
} else if (include.isResolvedByHeuristics()) {
|
||||
flags |= FLAG_RESOLVED_BY_HEURISTICS;
|
||||
}
|
||||
if (include.isIncludedFileExported()) {
|
||||
flags |= FLAG_EXPORTED_FILE;
|
||||
}
|
||||
if (deducible_name) {
|
||||
flags |= FLAG_DEDUCIBLE_NAME;
|
||||
}
|
||||
|
@ -254,6 +258,11 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
|||
return (getFlag() & FLAG_RESOLVED_BY_HEURISTICS) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedFileExported() throws CoreException {
|
||||
return (getFlag() & FLAG_EXPORTED_FILE) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNameOffset() throws CoreException {
|
||||
return linkage.getDB().get3ByteUnsignedInt(record + NODE_OFFSET);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2013 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
|
||||
|
@ -54,13 +54,13 @@ public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
|
|||
|
||||
@Override
|
||||
public boolean needsToRebuildForProperties(Properties props) {
|
||||
for (Map.Entry<Object,Object> entry : fProperties.entrySet()) {
|
||||
for (Map.Entry<Object, Object> entry : fProperties.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
String myval = (String) entry.getValue();
|
||||
String val = (String) entry.getValue();
|
||||
|
||||
if (myval != null) { // relevant property
|
||||
if (val != null) { // relevant property
|
||||
String v2= (String) props.get(key);
|
||||
if (v2 != null && !myval.equals(v2)) {
|
||||
if (v2 != null && !val.equals(v2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
|
|||
|
||||
@Override
|
||||
public void setProperties(Properties props) {
|
||||
// only set relevant properties as initialized in the constructor
|
||||
for (Map.Entry<Object,Object> entry : props.entrySet()) {
|
||||
// Only set relevant properties as initialized in the constructor.
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
String val = (String) entry.getValue();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2013 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
|
||||
|
@ -17,11 +17,13 @@ import java.util.Comparator;
|
|||
import java.util.HashSet;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||
import org.eclipse.cdt.core.dom.IPDOMIndexer;
|
||||
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.IncludeExportPatterns;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
|
||||
import org.eclipse.cdt.internal.core.model.CProject;
|
||||
|
@ -181,6 +183,20 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
|
|||
return new TodoTaskUpdater();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final IncludeExportPatterns getIncludeExportPatterns() {
|
||||
ICProject project = getCProject();
|
||||
String exportPattern = CCorePreferenceConstants.getPreference(
|
||||
CCorePreferenceConstants.INCLUDE_EXPORT_PATTERN, project, null);
|
||||
String beginExportsPattern = CCorePreferenceConstants.getPreference(
|
||||
CCorePreferenceConstants.INCLUDE_BEGIN_EXPORTS_PATTERN, project, null);
|
||||
String endExportsPattern = CCorePreferenceConstants.getPreference(
|
||||
CCorePreferenceConstants.INCLUDE_END_EXPORTS_PATTERN, project, null);
|
||||
if (exportPattern == null && beginExportsPattern == null && endExportsPattern == null)
|
||||
return null;
|
||||
return new IncludeExportPatterns(exportPattern, beginExportsPattern, endExportsPattern);
|
||||
}
|
||||
|
||||
protected void traceEnd(long start, IWritableIndex index, boolean wasCancelled) {
|
||||
// log entry
|
||||
if (fWriteInfoToLog && !wasCancelled && index != null) {
|
||||
|
|
|
@ -25,9 +25,9 @@ import org.eclipse.cdt.core.model.ICProject;
|
|||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.CCoreInternals;
|
||||
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
|
||||
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.UnusedHeaderStrategy;
|
||||
|
@ -156,7 +156,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
|
|||
public IScannerInfo getBuildConfiguration(int linkageID, Object tu) {
|
||||
IScannerInfo info= ((ITranslationUnit) tu).getScannerInfo(true);
|
||||
if (info == null) {
|
||||
info= new ScannerInfo();
|
||||
info= new ExtendedScannerInfo();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2012 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2013 QNX Software Systems 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
|
||||
|
@ -173,6 +173,50 @@ public class CCorePreferenceConstants {
|
|||
*/
|
||||
public static final String PREF_BUILD_CONFIGS_RESOURCE_CHANGES = "build.proj.ref.configs.enabled"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Default value for {@link #INCLUDE_EXPORT_PATTERN}.
|
||||
* @since 5.5
|
||||
*/
|
||||
public static final String DEFAULT_INCLUDE_EXPORT_PATTERN = "IWYU\\s+(pragma:?\\s+)?export"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Preference key for the regular expression pattern that, when appears in a comment on the same
|
||||
* line as include statement, indicates the the included header file is exported.
|
||||
* @see "https://code.google.com/p/include-what-you-use/wiki/IWYUPragmas"
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
public static final String INCLUDE_EXPORT_PATTERN = "includes.exportPattern"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Default value for {@link #INCLUDE_BEGIN_EXPORTS_PATTERN}.
|
||||
* @since 5.5
|
||||
*/
|
||||
public static final String DEFAULT_INCLUDE_BEGIN_EXPORTS_PATTERN = "IWYU\\s+(pragma:?\\s+)?begin_exports?"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Preference key for the regular expression pattern that, when appears in a comment, marks
|
||||
* the beginning of a sequence of include statements that export the included header files.
|
||||
* @see "https://code.google.com/p/include-what-you-use/wiki/IWYUPragmas"
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
public static final String INCLUDE_BEGIN_EXPORTS_PATTERN = "includes.beginExportsPattern"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Default value for {@link #INCLUDE_END_EXPORTS_PATTERN}.
|
||||
* @since 5.5
|
||||
*/
|
||||
public static final String DEFAULT_INCLUDE_END_EXPORTS_PATTERN = "IWYU\\s+(pragma:?\\s+)?end_exports?"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Preference key for the regular expression pattern that, when appears in a comment, marks
|
||||
* the end of a sequence of include statements that export the included header files.
|
||||
* @see "https://code.google.com/p/include-what-you-use/wiki/IWYUPragmas"
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
public static final String INCLUDE_END_EXPORTS_PATTERN = "includes.endExportsPattern"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Returns the node in the preference in the given context.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2011 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2013 QNX Software Systems 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
|
||||
|
@ -28,18 +28,14 @@ import org.eclipse.core.runtime.preferences.DefaultScope;
|
|||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
|
||||
public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
|
||||
*/
|
||||
@Override
|
||||
public void initializeDefaultPreferences() {
|
||||
HashSet<String> optionNames = CModelManager.OptionNames;
|
||||
|
||||
// Formatter settings
|
||||
// Formatter settings.
|
||||
Map<String, String> defaultOptionsMap = DefaultCodeFormatterConstants.getDefaultSettings(); // code formatter defaults
|
||||
|
||||
// Compiler settings
|
||||
// Compiler settings.
|
||||
defaultOptionsMap.put(CCorePreferenceConstants.TODO_TASK_TAGS, CCorePreferenceConstants.DEFAULT_TASK_TAGS);
|
||||
defaultOptionsMap.put(CCorePreferenceConstants.TODO_TASK_PRIORITIES, CCorePreferenceConstants.DEFAULT_TASK_PRIORITY);
|
||||
defaultOptionsMap.put(CCorePreferenceConstants.TODO_TASK_CASE_SENSITIVE, CCorePreferenceConstants.DEFAULT_TASK_CASE_SENSITIVE);
|
||||
|
@ -49,7 +45,7 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
|
|||
defaultOptionsMap.put(CCorePreferenceConstants.WORKSPACE_LANGUAGE_MAPPINGS, CCorePreferenceConstants.DEFAULT_WORKSPACE_LANGUAGE_MAPPINGS);
|
||||
defaultOptionsMap.put(CodeReaderCache.CODE_READER_BUFFER, CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB_STRING);
|
||||
|
||||
// Store default values to default preferences
|
||||
// Store default values to default preferences.
|
||||
IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID);
|
||||
for (Map.Entry<String, String> entry : defaultOptionsMap.entrySet()) {
|
||||
String optionName = entry.getKey();
|
||||
|
@ -62,11 +58,14 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
|
|||
defaultPreferences.putBoolean(CCorePreferenceConstants.FILE_PATH_CANONICALIZATION, true);
|
||||
defaultPreferences.putBoolean(CCorePreferenceConstants.SHOW_SOURCE_ROOTS_AT_TOP_LEVEL_OF_PROJECT, true);
|
||||
|
||||
// build defaults
|
||||
// Build defaults.
|
||||
defaultPreferences.putBoolean(CCorePreferenceConstants.PREF_BUILD_ALL_CONFIGS, false);
|
||||
defaultPreferences.putBoolean(CCorePreferenceConstants.PREF_BUILD_CONFIGS_RESOURCE_CHANGES, false);
|
||||
|
||||
// indexer defaults
|
||||
// Indexer defaults.
|
||||
IndexerPreferences.initializeDefaultPreferences(defaultPreferences);
|
||||
defaultPreferences.put(CCorePreferenceConstants.INCLUDE_EXPORT_PATTERN, CCorePreferenceConstants.DEFAULT_INCLUDE_EXPORT_PATTERN);
|
||||
defaultPreferences.put(CCorePreferenceConstants.INCLUDE_BEGIN_EXPORTS_PATTERN, CCorePreferenceConstants.DEFAULT_INCLUDE_BEGIN_EXPORTS_PATTERN);
|
||||
defaultPreferences.put(CCorePreferenceConstants.INCLUDE_END_EXPORTS_PATTERN, CCorePreferenceConstants.DEFAULT_INCLUDE_END_EXPORTS_PATTERN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,20 +26,20 @@ import org.eclipse.cdt.internal.ui.refactoring.includes.IHeaderChooser;
|
|||
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeOrganizer;
|
||||
|
||||
/**
|
||||
* Tests for Extract Function refactoring.
|
||||
* Tests for IncludeOrganizer.
|
||||
*/
|
||||
public class OrganizeIncludesTest extends IncludesTestBase {
|
||||
public class IncludeOrganizerTest extends IncludesTestBase {
|
||||
|
||||
public OrganizeIncludesTest() {
|
||||
public IncludeOrganizerTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OrganizeIncludesTest(String name) {
|
||||
public IncludeOrganizerTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return suite(OrganizeIncludesTest.class);
|
||||
return suite(IncludeOrganizerTest.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -295,4 +295,38 @@ public class OrganizeIncludesTest extends IncludesTestBase {
|
|||
getPreferenceStore().setValue(PreferenceConstants.INCLUDES_ALLOW_REORDERING, false);
|
||||
assertExpectedResults();
|
||||
}
|
||||
|
||||
//h1.h
|
||||
//class A {};
|
||||
|
||||
//h2.h
|
||||
//class B {};
|
||||
|
||||
//h3.h
|
||||
//#include "h2.h" // IWYU pragma: export
|
||||
//class C {};
|
||||
|
||||
//h4.h
|
||||
//#include "h1.h"
|
||||
///* IWYU pragma: begin_exports */
|
||||
//#include "h3.h"
|
||||
///* IWYU pragma: end_exports */
|
||||
//class D {};
|
||||
|
||||
//source.cpp
|
||||
//A a;
|
||||
//B b;
|
||||
//C c;
|
||||
//D d;
|
||||
//====================
|
||||
//#include "h1.h"
|
||||
//#include "h4.h"
|
||||
//
|
||||
//A a;
|
||||
//B b;
|
||||
//C c;
|
||||
//D d;
|
||||
public void testHeaderExport() throws Exception {
|
||||
assertExpectedResults();
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ public class IncludesTestSuite extends TestSuite {
|
|||
public static Test suite() throws Exception {
|
||||
IncludesTestSuite suite = new IncludesTestSuite();
|
||||
suite.addTest(BindingClassifierTest.suite());
|
||||
suite.addTest(OrganizeIncludesTest.suite());
|
||||
suite.addTest(IncludeOrganizerTest.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,16 +10,28 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.refactoring.includes;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.ui.IMemento;
|
||||
import org.eclipse.ui.WorkbenchException;
|
||||
import org.eclipse.ui.XMLMemento;
|
||||
|
||||
class IncludeMap {
|
||||
private static final String TAG_CPP_ONLY = "cpp_only"; //$NON-NLS-1$
|
||||
private static final String TAG_FORCED_REPLACEMENT = "forced_replacement"; //$NON-NLS-1$
|
||||
private static final String TAG_MAPPING = "mapping"; //$NON-NLS-1$
|
||||
private static final String TAG_KEY = "key"; //$NON-NLS-1$
|
||||
private static final String TAG_VALUE = "value"; //$NON-NLS-1$
|
||||
|
||||
private final boolean forcedReplacement;
|
||||
private final Map<IncludeInfo, List<IncludeInfo>> map;
|
||||
private final boolean cppOnly;
|
||||
private final Map<IncludeInfo, List<IncludeInfo>> map;
|
||||
|
||||
public IncludeMap(boolean forcedReplacement, boolean cppOnly) {
|
||||
this.forcedReplacement = forcedReplacement;
|
||||
|
@ -113,4 +125,39 @@ class IncludeMap {
|
|||
public boolean isCppOnly() {
|
||||
return cppOnly;
|
||||
}
|
||||
|
||||
// XXX Define a class containing two Includemaps, week and strong
|
||||
public void saveToMemento(IMemento memento) {
|
||||
memento.putBoolean(TAG_CPP_ONLY, cppOnly);
|
||||
memento.putBoolean(TAG_FORCED_REPLACEMENT, forcedReplacement);
|
||||
for (Entry<IncludeInfo, List<IncludeInfo>> entry : map.entrySet()) {
|
||||
String key = entry.getKey().toString();
|
||||
for (IncludeInfo value : entry.getValue()) {
|
||||
IMemento mapping = memento.createChild(TAG_MAPPING);
|
||||
mapping.putString(TAG_KEY, key);
|
||||
mapping.putString(TAG_VALUE, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IncludeMap fromMemento(IMemento memento) {
|
||||
Boolean cppOnly = memento.getBoolean(TAG_CPP_ONLY);
|
||||
Boolean forcedReplacement = memento.getBoolean(TAG_FORCED_REPLACEMENT);
|
||||
IncludeMap includeMap = new IncludeMap(cppOnly, forcedReplacement);
|
||||
for (IMemento mapping : memento.getChildren(TAG_MAPPING)) {
|
||||
includeMap.addMapping(mapping.getString(TAG_KEY), mapping.getString(TAG_VALUE));
|
||||
}
|
||||
return includeMap;
|
||||
}
|
||||
|
||||
public static IncludeMap fromString(String str) {
|
||||
StringReader reader = new StringReader(str);
|
||||
XMLMemento memento;
|
||||
try {
|
||||
memento = XMLMemento.createReadRoot(reader);
|
||||
} catch (WorkbenchException e) {
|
||||
return null;
|
||||
}
|
||||
return fromMemento(memento);
|
||||
}
|
||||
}
|
|
@ -875,7 +875,7 @@ public class IncludeOrganizer {
|
|||
}
|
||||
|
||||
private void processInclusionRequests(List<InclusionRequest> requests,
|
||||
HeaderSubstitutor headerSubstitutor) {
|
||||
HeaderSubstitutor headerSubstitutor) throws CoreException {
|
||||
// Add partner header if necessary.
|
||||
HashSet<IIndexFile> includedByPartner = fContext.getPreferences().allowPartnerIndirectInclusion ?
|
||||
new HashSet<IIndexFile>() : null;
|
||||
|
@ -954,8 +954,6 @@ public class IncludeOrganizer {
|
|||
}
|
||||
|
||||
// Resolve ambiguous inclusion requests.
|
||||
|
||||
// Maps a set of header files presented to the user to the file selected by the user.
|
||||
for (InclusionRequest request : requests) {
|
||||
if (!request.isResolved()) {
|
||||
List<IPath> candidatePaths = request.getCandidatePaths();
|
||||
|
@ -976,9 +974,12 @@ public class IncludeOrganizer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove headers that are exported by other headers.
|
||||
fContext.removeExportedHeaders();
|
||||
}
|
||||
|
||||
private IPath getPath(IIndexFileLocation location) {
|
||||
private static IPath getPath(IIndexFileLocation location) {
|
||||
return IndexLocationFactory.getAbsolutePath(location);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public class IncludePreferences {
|
|||
public final boolean forwardDeclareCompositeTypes;
|
||||
public final boolean forwardDeclareEnums;
|
||||
public final boolean forwardDeclareFunctions;
|
||||
// TODO(sprigogin): Create a preference.
|
||||
// TODO(sprigogin): Create a preference for this.
|
||||
public final boolean forwardDeclareExternalVariables = false;
|
||||
public final boolean forwardDeclareTemplates;
|
||||
public final boolean forwardDeclareNamespaceElements;
|
||||
|
|
|
@ -11,16 +11,21 @@
|
|||
package org.eclipse.cdt.internal.ui.refactoring.includes;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
|
@ -149,6 +154,43 @@ public class InclusionContext {
|
|||
return include;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes headers that are exported by other headers that will be included
|
||||
*/
|
||||
public void removeExportedHeaders() throws CoreException {
|
||||
// Index files keyed by their absolute paths.
|
||||
Map<IPath, IIndexFile> filesByPath = new HashMap<IPath, IIndexFile>();
|
||||
for (IIndexFile file : fIndex.getAllFiles()) {
|
||||
IPath path = getPath(file);
|
||||
filesByPath.put(path, file);
|
||||
}
|
||||
|
||||
Set<IPath> exportedHeaders = new HashSet<IPath>();
|
||||
for (IPath path : fHeadersToInclude) {
|
||||
if (!exportedHeaders.contains(path)) {
|
||||
IIndexFile file = filesByPath.get(path);
|
||||
ArrayDeque<IIndexFile> queue = new ArrayDeque<IIndexFile>();
|
||||
queue.add(file);
|
||||
while ((file = queue.pollFirst()) != null) {
|
||||
for (IIndexInclude include : file.getIncludes()) {
|
||||
if (include.isIncludedFileExported()) {
|
||||
file = fIndex.resolveInclude(include);
|
||||
if (file != null) {
|
||||
if (exportedHeaders.add(getPath(file)))
|
||||
queue.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fHeadersToInclude.removeAll(exportedHeaders);
|
||||
}
|
||||
|
||||
private static IPath getPath(IIndexFile file) throws CoreException {
|
||||
return IndexLocationFactory.getAbsolutePath(file.getLocation());
|
||||
}
|
||||
|
||||
private static boolean fileExists(String absolutePath) {
|
||||
return new File(absolutePath).exists();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue