1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 19:25:38 +02:00

Bug 412380: Flag for indicating whether AST contains all nodes

Possible approach for providing a way to check in refactorings whether
the AST might miss important nodes for rewriting. Including scalability
option, configurable in the preferences.

Change-Id: I0b56a24f103a5cf764afbf39b644780081459853
Reviewed-on: https://git.eclipse.org/r/14404
Reviewed-by: Thomas Corbat <tcorbat@hsr.ch>
IP-Clean: Thomas Corbat <tcorbat@hsr.ch>
Tested-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
Thomas Corbat 2013-07-09 16:40:36 +02:00
parent 2001e49bf3
commit b40866ce32
24 changed files with 505 additions and 132 deletions

View file

@ -128,7 +128,7 @@ public class AST2TemplateTests extends AST2TestBase {
}
protected IASTTranslationUnit parseAndCheckImplicitNameBindings() throws Exception {
IASTTranslationUnit tu = parse(getAboveComment(), CPP, false, true, false);
IASTTranslationUnit tu = parse(getAboveComment(), CPP, false, true);
NameCollector col = new NameCollector(true /* visit implicit names */);
tu.accept(col);
assertNoProblemBindings(col);

View file

@ -157,11 +157,11 @@ public class AST2TestBase extends BaseTestCase {
protected IASTTranslationUnit parse(String code, ParserLanguage lang, boolean useGNUExtensions,
boolean expectNoProblems) throws ParserException {
return parse(code, lang, useGNUExtensions, expectNoProblems, false);
return parse(code, lang, useGNUExtensions, expectNoProblems, Integer.MAX_VALUE);
}
protected IASTTranslationUnit parse(String code, ParserLanguage lang, boolean useGNUExtensions,
boolean expectNoProblems, boolean skipTrivialInitializers) throws ParserException {
boolean expectNoProblems, int limitTrivialInitializers) throws ParserException {
IScanner scanner = createScanner(FileContent.create(TEST_CODE, code.toCharArray()), lang, ParserMode.COMPLETE_PARSE,
createScannerInfo(useGNUExtensions));
configureScanner(scanner);
@ -185,8 +185,7 @@ public class AST2TestBase extends BaseTestCase {
parser = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config, null);
}
if (skipTrivialInitializers)
parser.setSkipTrivialExpressionsInAggregateInitializers(true);
parser.setMaximumTrivialExpressionsInAggregateInitializers(limitTrivialInitializers);
IASTTranslationUnit tu = parser.parse();
assertTrue(tu.isFrozen());
@ -750,12 +749,12 @@ public class AST2TestBase extends BaseTestCase {
}
final protected IASTTranslationUnit parseAndCheckBindings(String code, ParserLanguage lang, boolean useGnuExtensions) throws Exception {
return parseAndCheckBindings(code, lang, useGnuExtensions, false);
return parseAndCheckBindings(code, lang, useGnuExtensions, Integer.MAX_VALUE);
}
final protected IASTTranslationUnit parseAndCheckBindings(String code, ParserLanguage lang, boolean useGnuExtensions,
boolean skipTrivialInitializers) throws Exception {
IASTTranslationUnit tu = parse(code, lang, useGnuExtensions, true, skipTrivialInitializers);
int limitTrvialInitializers) throws Exception {
IASTTranslationUnit tu = parse(code, lang, useGnuExtensions, true, limitTrvialInitializers);
NameCollector col = new NameCollector();
tu.accept(col);
assertNoProblemBindings(col);

View file

@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
@ -40,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
@ -54,6 +56,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
@ -5850,19 +5853,12 @@ public class AST2Tests extends AST2TestBase {
sValidateCopy = false;
final int AMOUNT = 250000;
final CharSequence[] input = getContents(3);
StringBuilder buf= new StringBuilder();
buf.append(input[0].toString());
final String line= input[1].toString();
for (int i = 0; i < AMOUNT/10; i++) {
buf.append(line);
}
buf.append(input[2].toString());
final String code= buf.toString();
final String code = concatInput(input, new int[] { 1, AMOUNT / 10, 1 });
for (ParserLanguage lang : ParserLanguage.values()) {
long mem = memoryUsed();
IASTTranslationUnit tu= parse(code, lang, false, true, true);
IASTTranslationUnit tu = parse(code, lang, false, true, 0);
long diff = memoryUsed() - mem;
// allow a copy of the buffer + less than 2 bytes per initializer
// Allow a copy of the buffer, plus less than 1.5 bytes per initializer.
final int expected = code.length() * 2 + AMOUNT + AMOUNT / 2;
assertTrue(String.valueOf(diff) + " expected < " + expected, diff < expected);
assertTrue(tu.isFrozen());
@ -5883,25 +5879,72 @@ public class AST2Tests extends AST2TestBase {
sValidateCopy = false;
final int AMOUNT = 250000;
final CharSequence[] input = getContents(3);
StringBuilder buf= new StringBuilder();
buf.append(input[0].toString());
final String line= input[1].toString();
for (int i = 0; i < AMOUNT/10; i++) {
buf.append(line);
}
buf.append(input[2].toString());
final String code= buf.toString();
final String code = concatInput(input, new int[] { 1, AMOUNT / 10, 1 });
for (ParserLanguage lang : ParserLanguage.values()) {
long mem = memoryUsed();
IASTTranslationUnit tu= parse(code, lang, false, true, true);
IASTTranslationUnit tu = parse(code, lang, false, true, 0);
long diff = memoryUsed() - mem;
// allow a copy of the buffer + not even 1 byte per initializer
// Allow a copy of the buffer, plus less than 1.5 bytes per initializer.
final int expected = code.length() * 2 + AMOUNT + AMOUNT / 2;
assertTrue(String.valueOf(diff) + " expected < " + expected, diff < expected);
assertTrue(tu.isFrozen());
}
}
// int a[]= {
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// };
public void testMaximumTrivialExpressionsInInitializers_412380() throws Exception {
sValidateCopy = false;
final int AMOUNT = 250000;
final int maximumTrivialExpressionsInInitializer = 1000;
final int additionalBytesPerInitializer = 90;
final CharSequence[] input = getContents(3);
final String code = concatInput(input, new int[] { 1, AMOUNT / 10, 1 });
for (ParserLanguage lang : ParserLanguage.values()) {
long mem = memoryUsed();
IASTTranslationUnit tu = parse(code, lang, false, true, maximumTrivialExpressionsInInitializer);
long diff = memoryUsed() - mem;
final int initializerSize = maximumTrivialExpressionsInInitializer * additionalBytesPerInitializer;
// Allow a copy of the buffer, plus less than 1.5 bytes per initializer.
final int expected = code.length() * 2 + AMOUNT + AMOUNT / 2 + initializerSize;
assertTrue(String.valueOf(diff) + " expected < " + expected, diff < expected);
assertTrue(tu.isFrozen());
tu.accept(new ASTVisitor() {
{
shouldVisitInitializers = true;
}
@Override
public int visit(IASTInitializer initializer) {
if (initializer instanceof IASTEqualsInitializer) {
IASTEqualsInitializer equalsInitializer = (IASTEqualsInitializer) initializer;
IASTInitializerClause initClause = equalsInitializer.getInitializerClause();
if (initClause instanceof IASTInitializerList) {
IASTInitializerList initList = (IASTInitializerList) initClause;
assertEquals(maximumTrivialExpressionsInInitializer, initList.getClauses().length);
}
}
return ASTVisitor.PROCESS_CONTINUE;
}
});
}
}
private String concatInput(CharSequence[] snippets, int[] snippetOccurences) {
final StringBuilder result = new StringBuilder();
final int snippetsToConcat = Math.min(snippets.length, snippetOccurences.length);
for (int i = 0; i < snippetsToConcat; i++) {
final CharSequence string = snippets[i];
for (int times = 0; times < snippetOccurences[i]; times++) {
result.append(string);
}
}
return result.toString();
}
private long memoryUsed() throws InterruptedException {
final Runtime runtime = Runtime.getRuntime();
long mem= runtime.totalMemory()-runtime.freeMemory();
@ -5921,7 +5964,7 @@ public class AST2Tests extends AST2TestBase {
public void testNonTrivialInitializer_253690() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(code, lang, false, true, true);
IASTTranslationUnit tu= parse(code, lang, false, true, 0);
IASTSimpleDeclaration d= getDeclaration(tu, 0);
IBinding b= d.getDeclarators()[0].getName().resolveBinding();
IASTName[] refs = tu.getReferences(b);
@ -7148,7 +7191,23 @@ public class AST2Tests extends AST2TestBase {
// static a[2]= {0,0};
public void testSkipAggregateInitializer_297550() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, C, false, true);
IASTTranslationUnit tu = parseAndCheckBindings(code, C, false, 0);
assertTrue(tu.hasNodesOmitted());
}
// static a[2]= {0,0};
public void testNoSkipTrivialAggregateInitializer_412380() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu = parseAndCheckBindings(code, C, false);
assertFalse(tu.hasNodesOmitted());
}
// static int i = 0;
// static a[1]= {i};
public void testNoSkipNonTrivialAggregateInitializer_412380() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu = parseAndCheckBindings(code, C, false, 0);
assertFalse(tu.hasNodesOmitted());
}
// typeof(b(1)) b(int);

View file

@ -22,15 +22,19 @@ import java.util.Map.Entry;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CCorePreferenceConstants;
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsChangeEvent;
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsChangeListener;
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IParserSettings;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.ParserSettings;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.cdt.core.settings.model.ICMacroEntry;
@ -38,6 +42,7 @@ import org.eclipse.cdt.core.settings.model.ICPathEntry;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
import org.eclipse.cdt.internal.core.settings.model.SettingsModelMessages;
import org.eclipse.cdt.utils.EFSExtensionManager;
@ -128,7 +133,24 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider
definedMacros.put(name, value);
}
return new ExtendedScannerInfo(definedMacros, includePaths, macroFiles, includeFiles, includePathsLocal);
ExtendedScannerInfo extendedScannerInfo = new ExtendedScannerInfo(definedMacros, includePaths, macroFiles, includeFiles, includePathsLocal);
IParserSettings parserSettings = createParserSettings(project);
extendedScannerInfo.setParserSettings(parserSettings);
return extendedScannerInfo;
}
private IParserSettings createParserSettings(IProject project) {
ParserSettings parserSettings = new ParserSettings();
ICProject cProject = CModelManager.getDefault().create(project);
if (CCorePreferenceConstants.getPreference(CCorePreferenceConstants.SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS, cProject,
CCorePreferenceConstants.DEFAULT_SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS)) {
int maximumNumberOfTrivialExpressionsInAggregateInitializers = CCorePreferenceConstants.getPreference(
CCorePreferenceConstants.SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS, cProject,
CCorePreferenceConstants.DEFAULT_SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS);
parserSettings.setMaximumTrivialExpressionsInAggregateInitializers(maximumNumberOfTrivialExpressionsInAggregateInitializers);
}
return parserSettings;
}
private String expandVariables(String pathStr, ICConfigurationDescription cfgDescription) {

View file

@ -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
@ -9,6 +9,7 @@
* Doug Schaefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@ -365,4 +366,16 @@ public interface IASTTranslationUnit extends IASTDeclarationListOwner, IFileNomi
* @noreference This method is not intended to be referenced by clients.
*/
public void setPragmaOnceSemantics(boolean value);
/**
* Returns {@code true} if the parser has skipped any nodes while creating the AST.
* @since 5.6
*/
public boolean hasNodesOmitted();
/**
* Sets whether the parser has skipped any nodes while creating the AST for the translation unit.
* @since 5.6
*/
public void setHasNodesOmitted(boolean nodesOmitted);
}

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.parser.c.GCCScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.c.ICParserExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IParserSettings;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserLanguage;
@ -95,6 +96,19 @@ public class GCCLanguage extends AbstractCLikeLanguage {
return new GNUCSourceParser(scanner, parserMode, logService, getParserExtensionConfiguration(), index);
}
@Override
protected ISourceCodeParser createParser(IScanner scanner, ParserMode parserMode, IParserLogService logService, IIndex index,
int options, IParserSettings settings) {
GNUCSourceParser parser = new GNUCSourceParser(scanner, parserMode, logService, getParserExtensionConfiguration(), index);
if (settings != null) {
int maximumTrivialExpressions = settings.getMaximumTrivialExpressionsInAggregateInitializers();
if (maximumTrivialExpressions >= 0 && (options & OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS) != 0) {
parser.setMaximumTrivialExpressionsInAggregateInitializers(maximumTrivialExpressions);
}
}
return parser;
}
@Override
protected ParserLanguage getParserLanguage() {
return ParserLanguage.C;

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.parser.cpp.GPPScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IParserSettings;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserLanguage;
@ -102,6 +103,19 @@ public class GPPLanguage extends AbstractCLikeLanguage {
return new GNUCPPSourceParser(scanner, parserMode, logService, getParserExtensionConfiguration(), index);
}
@Override
protected ISourceCodeParser createParser(IScanner scanner, ParserMode parserMode, IParserLogService logService, IIndex index,
int options, IParserSettings settings) {
GNUCPPSourceParser parser = new GNUCPPSourceParser(scanner, parserMode, logService, getParserExtensionConfiguration(), index);
if (settings != null) {
int maximumTrivialExpressions = settings.getMaximumTrivialExpressionsInAggregateInitializers();
if (maximumTrivialExpressions >= 0 && (options & OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS) != 0) {
parser.setMaximumTrivialExpressionsInAggregateInitializers(maximumTrivialExpressions);
}
}
return parser;
}
@Override
protected ParserLanguage getParserLanguage() {
return ParserLanguage.CPP;

View file

@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems)
* Mike Kucera (IBM)
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.core.dom.parser;
@ -30,12 +31,12 @@ 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.IParserSettings;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
import org.eclipse.cdt.internal.core.util.ICancelable;
import org.eclipse.cdt.internal.core.util.ICanceler;
@ -101,6 +102,15 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
protected abstract ISourceCodeParser createParser(IScanner scanner, ParserMode parserMode,
IParserLogService logService, IIndex index);
/**
* @returns the actual parser object, configured with additional settings.
* @since 5.6
*/
protected ISourceCodeParser createParser(IScanner scanner, ParserMode parserMode,
IParserLogService logService, IIndex index, int options, IParserSettings settings) {
return createParser(scanner, parserMode, logService, index);
}
/**
* @return The ParserLanguage value corresponding to the language supported.
*/
@ -131,7 +141,12 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
scanner.setComputeImageLocations((options & OPTION_NO_IMAGE_LOCATIONS) == 0);
scanner.setProcessInactiveCode((options & OPTION_PARSE_INACTIVE_CODE) != 0);
final ISourceCodeParser parser= createParser(scanner, log, index, false, options);
IParserSettings parserSettings= null;
if (scanInfo instanceof ExtendedScannerInfo) {
ExtendedScannerInfo extendedScannerInfo = (ExtendedScannerInfo) scanInfo;
parserSettings = extendedScannerInfo.getParserSettings();
}
final ISourceCodeParser parser= createParser(scanner, log, index, false, options, parserSettings);
// Make it possible to cancel parser by reconciler - http://bugs.eclipse.org/226682
ICanceler canceler= null;
@ -193,22 +208,36 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
* @return an instance of ISourceCodeParser
*/
protected ISourceCodeParser createParser(IScanner scanner, IParserLogService log, IIndex index, boolean forCompletion, int options) {
ParserMode mode;
if (forCompletion) {
mode= ParserMode.COMPLETION_PARSE;
} else if ((options & OPTION_SKIP_FUNCTION_BODIES) != 0) {
mode= ParserMode.STRUCTURAL_PARSE;
} else {
mode= ParserMode.COMPLETE_PARSE;
ParserMode mode = createParserMode(forCompletion, options);
return createParser(scanner, mode, log, index);
}
ISourceCodeParser parser= createParser(scanner, mode, log, index);
if ((options & OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS) != 0) {
if (parser instanceof AbstractGNUSourceCodeParser) {
((AbstractGNUSourceCodeParser) parser).setSkipTrivialExpressionsInAggregateInitializers(true);
/**
* Create the parser with additional settings.
*
* @param scanner the IScanner to get tokens from
* @param log the parser log service
* @param index the index to help resolve bindings
* @param forCompletion whether the parser is used for code completion
* @param options for valid options see
* {@link AbstractLanguage#getASTTranslationUnit(FileContent, IScannerInfo, IncludeFileContentProvider, IIndex, int, IParserLogService)}
* @param settings for the parser
* @return an instance of ISourceCodeParser
* @since 5.6
*/
protected ISourceCodeParser createParser(IScanner scanner, IParserLogService log, IIndex index, boolean forCompletion, int options, IParserSettings settings) {
ParserMode mode = createParserMode(forCompletion, options);
return createParser(scanner, mode, log, index, options, settings);
}
private ParserMode createParserMode(boolean forCompletion, int options) {
if (forCompletion) {
return ParserMode.COMPLETION_PARSE;
} else if ((options & OPTION_SKIP_FUNCTION_BODIES) != 0) {
return ParserMode.STRUCTURAL_PARSE;
} else {
return ParserMode.COMPLETE_PARSE;
}
return parser;
}
/**

View file

@ -25,6 +25,7 @@ public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScanner
private String[] includeFiles;
private String[] localIncludePaths;
private IncludeExportPatterns includeExportPatterns;
private IParserSettings parserSettings;
public ExtendedScannerInfo() {
}
@ -60,7 +61,9 @@ public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScanner
localIncludePaths = einfo.getLocalIncludePath();
}
if (info instanceof ExtendedScannerInfo) {
includeExportPatterns = ((ExtendedScannerInfo) info).includeExportPatterns;
ExtendedScannerInfo extendedScannerInfo = (ExtendedScannerInfo) info;
includeExportPatterns = extendedScannerInfo.includeExportPatterns;
parserSettings = extendedScannerInfo.parserSettings;
}
}
@ -106,4 +109,20 @@ public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScanner
public void setIncludeExportPatterns(IncludeExportPatterns patterns) {
includeExportPatterns= patterns;
}
/**
* Returns additional settings for the parser.
* @since 5.6
*/
public IParserSettings getParserSettings() {
return parserSettings;
}
/**
* Sets additional settings for configuring the parser.
* @since 5.6
*/
public void setParserSettings(IParserSettings parserSettings) {
this.parserSettings = parserSettings;
}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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:
* Thomas Corbat (IFS) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser;
/**
* Interface for providing settings for the parser.
* @since 5.6
*/
public interface IParserSettings {
/**
* Returns the maximum number of trivial expressions in aggregate initializers. Exceeding numbers
* of trivial aggregate initializers should be skipped by the parser for performance reasons.
* A negative number indicates that the parser shall not skip any initializers.
*/
public int getMaximumTrivialExpressionsInAggregateInitializers();
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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:
* Thomas Corbat (IFS) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser;
/**
* Implementation for the {@link IParserSettings} interface. Allows to configure
* the parser with additional settings.
* @since 5.6
*/
public class ParserSettings implements IParserSettings {
private int maximumTrivialExpressionsInAggregateInitializers = -1;
@Override
public int getMaximumTrivialExpressionsInAggregateInitializers() {
return maximumTrivialExpressionsInAggregateInitializers;
}
/**
* Sets the maximum number of trivial expressions in aggregate initializers.
* @param value The new maximum number of trivial expressions in aggregate initializers.
*/
public void setMaximumTrivialExpressionsInAggregateInitializers(int value) {
maximumTrivialExpressionsInAggregateInitializers = value;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 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
@ -14,7 +14,6 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -65,15 +64,15 @@ public class ASTQueries {
private static NameSearch NAME_SEARCH= new NameSearch();
/**
* Tests whether the given expression can contain ast-names, suitable to be used before ambiguity
* Tests whether the given node can contain ast-names, suitable to be used before ambiguity
* resolution.
*/
public static boolean canContainName(IASTExpression expr) {
if (expr == null)
public static boolean canContainName(IASTNode node) {
if (node == null)
return false;
NAME_SEARCH.reset();
expr.accept(NAME_SEARCH);
node.accept(NAME_SEARCH);
return NAME_SEARCH.foundName();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2011 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 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
@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -82,6 +83,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
/** The semaphore controlling exclusive access to the AST. */
private final Semaphore fSemaphore= new Semaphore(1);
private boolean fBasedOnIncompleteIndex;
private boolean fNodesOmitted;
@Override
public final IASTTranslationUnit getTranslationUnit() {
@ -428,6 +430,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
copy.setLocationResolver(fLocationResolver);
copy.fForContentAssist = fForContentAssist;
copy.fOriginatingTranslationUnit = fOriginatingTranslationUnit;
copy.fNodesOmitted = fNodesOmitted;
for (IASTDeclaration declaration : getDeclarations()) {
copy.addDeclaration(declaration == null ? null : declaration.copy(style));
@ -545,4 +548,15 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
IASTFileLocation nodeLocation = node.getFileLocation();
return nodeLocation != null ? nodeLocation.getEndingLineNumber() : 0;
}
@Override
public boolean hasNodesOmitted() {
return fNodesOmitted;
}
@Override
public void setHasNodesOmitted(boolean hasNodesOmitted) {
assertNotFrozen();
fNodesOmitted = hasNodesOmitted;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2012 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
@ -11,6 +11,7 @@
* Ed Swartz (Nokia)
* Mike Kucera (IBM) - bug #206952
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -188,7 +189,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected final IBuiltinBindingsProvider builtinBindingsProvider;
protected boolean functionCallCanBeLValue= false;
protected boolean skipTrivialExpressionsInAggregateInitializers= false;
protected int maximumTrivialExpressionsInAggregateInitializers= Integer.MAX_VALUE;
/**
* Marks the beginning of the current declaration. It is important to clear the mark whenever we
@ -232,10 +233,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
/**
* Instructs the parser not to create ast nodes for expressions within aggregate initializers
* when they do not contain names.
* when they do not contain names beyond the given limit.
*/
public void setSkipTrivialExpressionsInAggregateInitializers(boolean val) {
skipTrivialExpressionsInAggregateInitializers= val;
public void setMaximumTrivialExpressionsInAggregateInitializers(int limit) {
maximumTrivialExpressionsInAggregateInitializers= limit;
}
private AbstractParserLogService wrapLogService(IParserLogService logService) {
@ -676,8 +677,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract void nullifyTranslationUnit();
protected IToken skipOverCompoundStatement() throws BacktrackException, EndOfFileException {
protected IToken skipOverCompoundStatement(boolean hasSkippedNodes) throws BacktrackException, EndOfFileException {
// speed up the parser by skipping the body, simply look for matching brace and return
if (hasSkippedNodes)
getTranslationUnit().setHasNodesOmitted(true);
final boolean isActive = isActiveCode();
final int codeBranchNesting= getCodeBranchNesting();
@ -904,13 +907,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTExpression compoundStatementExpression() throws EndOfFileException, BacktrackException {
int startingOffset = consume().getOffset(); // tLPAREN always
IASTCompoundStatement compoundStatement = null;
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode())
skipOverCompoundStatement();
else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) {
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode()) {
skipOverCompoundStatement(true);
} else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) {
if (scanner.isOnTopContext())
compoundStatement();
else
skipOverCompoundStatement();
skipOverCompoundStatement(true);
} else if (mode == ParserMode.COMPLETE_PARSE)
compoundStatement = compoundStatement();
@ -1428,7 +1431,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
declarationMark= null;
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode()) {
int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement();
IToken last = skipOverCompoundStatement(true);
IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
setRange(cs, offset, last.getEndOffset());
return cs;
@ -1436,7 +1439,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if (scanner.isOnTopContext())
return functionBody();
int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement();
IToken last = skipOverCompoundStatement(true);
IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
setRange(cs, offset, last.getEndOffset());
return cs;
@ -1770,7 +1773,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throwBacktrack(offset, LA(1).getEndOffset() - offset);
final int compoundOffset= LA(1).getOffset();
final int endOffset= skipOverCompoundStatement().getEndOffset();
final int endOffset= skipOverCompoundStatement(false).getEndOffset();
IASTCompoundStatement cs = nodeFactory.newCompoundStatement(); //createCompoundStatement();
((ASTNode)cs).setOffsetAndLength(compoundOffset, endOffset - compoundOffset);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2012 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
@ -11,6 +11,7 @@
* Ed Swartz (Nokia)
* Mike Kucera (IBM) - bug #206952
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -140,23 +141,17 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
protected IASTInitializer optionalInitializer(IASTDeclarator dtor, DeclarationOptions options) throws EndOfFileException, BacktrackException {
if (LTcatchEOF(1) == IToken.tASSIGN) {
final int offset= consume().getOffset();
IASTInitializerClause initClause = initClause(false);
IASTInitializerClause initClause = initClause();
IASTEqualsInitializer result= nodeFactory.newEqualsInitializer(initClause);
return setRange(result, offset, calculateEndOffset(initClause));
}
return null;
}
private IASTInitializerClause initClause(boolean inAggregate) throws EndOfFileException, BacktrackException {
private IASTInitializerClause initClause() throws EndOfFileException, BacktrackException {
final int offset = LA(1).getOffset();
if (LT(1) != IToken.tLBRACE) {
IASTExpression assignmentExpression= expression(ExprKind.eAssignment);
if (inAggregate && skipTrivialExpressionsInAggregateInitializers) {
if (!ASTQueries.canContainName(assignmentExpression))
return null;
}
return assignmentExpression;
}
if (LT(1) != IToken.tLBRACE)
return expression(ExprKind.eAssignment);
// it's an aggregate initializer
consume(IToken.tLBRACE);
@ -175,7 +170,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// get designator list
List<? extends ICASTDesignator> designator= designatorList();
if (designator == null) {
IASTInitializerClause clause= initClause(true);
IASTInitializerClause clause= initClause();
if (result.getSize() >= maximumTrivialExpressionsInAggregateInitializers && !ASTQueries.canContainName(clause)) {
translationUnit.setHasNodesOmitted(true);
clause= null;
}
// depending on value of skipTrivialItemsInCompoundInitializers initializer may be null
// in any way add the initializer such that the actual size can be tracked.
result.addClause(clause);
@ -191,7 +190,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tASSIGN)
consume(IToken.tASSIGN);
IASTInitializerClause clause= initClause(false);
IASTInitializerClause clause= initClause();
desigInitializer.setOperand(clause);
adjustLength(desigInitializer, clause);
}
@ -630,7 +629,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTTypeId t= typeId(DeclarationOptions.TYPEID);
consume(IToken.tRPAREN);
if (LT(1) == IToken.tLBRACE) {
IASTInitializer i = (IASTInitializerList) initClause(false);
IASTInitializer i = (IASTInitializerList) initClause();
firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i);
setRange(firstExpression, offset, calculateEndOffset(i));
break;

View file

@ -3592,12 +3592,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// assignment expression
TemplateIdStrategy strat= fTemplateParameterListStrategy;
final BinaryExprCtx ctx= strat != null ? BinaryExprCtx.eInTemplateID : BinaryExprCtx.eNotInTemplateID;
IASTExpression assignmentExpression = expression(ExprKind.eAssignment, ctx, null, strat);
if (allowSkipping && skipTrivialExpressionsInAggregateInitializers) {
if (!ASTQueries.canContainName(assignmentExpression))
return null;
}
return assignmentExpression;
return expression(ExprKind.eAssignment, ctx, null, strat);
}
/**
@ -3638,6 +3633,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
loop: while (true) {
// Clause may be null, add to initializer anyways, such that the size can be computed.
IASTInitializerClause clause = initClause(allowSkipping);
if (allowSkipping && result.size() >= maximumTrivialExpressionsInAggregateInitializers
&& !ASTQueries.canContainName(clause)) {
translationUnit.setHasNodesOmitted(true);
clause= null;
}
if (LT(1) == IToken.tELLIPSIS) {
final int endOffset = consume(IToken.tELLIPSIS).getEndOffset();
if (clause instanceof ICPPASTPackExpandable) {
@ -4417,7 +4417,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected IASTStatement catchBlockCompoundStatement() throws BacktrackException, EndOfFileException {
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode()) {
int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement();
IToken last = skipOverCompoundStatement(true);
IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
setRange(cs, offset, last.getEndOffset());
return cs;
@ -4425,7 +4425,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (scanner.isOnTopContext())
return compoundStatement();
int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement();
IToken last = skipOverCompoundStatement(true);
IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
setRange(cs, offset, last.getEndOffset());
return cs;

View file

@ -9,6 +9,7 @@
* Markus Schorn - initial API and implementation
* IBM Corporation
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
@ -45,10 +46,12 @@ 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.IParserSettings;
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.ParserSettings;
import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
@ -400,6 +403,10 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
return null;
}
protected IParserSettings createParserSettings() {
return new ParserSettings();
}
/**
* @return array of linkage IDs that shall be parsed
*/
@ -950,7 +957,9 @@ 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());
ExtendedScannerInfo extendedScannerInfo = (ExtendedScannerInfo) scannerInfo;
extendedScannerInfo.setIncludeExportPatterns(getIncludeExportPatterns());
extendedScannerInfo.setParserSettings(createParserSettings());
}
return scannerInfo;
}

View file

@ -218,6 +218,38 @@ public class CCorePreferenceConstants {
*/
public static final String INCLUDE_END_EXPORTS_PATTERN = "includes.endExportsPattern"; //$NON-NLS-1$
/**
* A named preference that controls whether the parser should skip trivial expressions in initializer lists.
* <p>
* Value is of type <code>Boolean</code>.
*
* @since 5.6
*/
public static String SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS = "scalability.skipTrivialExpressions"; //$NON-NLS-1$
/**
* Default value for {@link #SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS}.
* @since 5.6
*/
public static final boolean DEFAULT_SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS = true;
/**
* The maximum number of trivial expressions that are parsed in initializer lists. This preference
* is considered only if <code>SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS</code> is set to true.
* <p>
* Value is of type <code>int</code>.
* </p>
*
* @since 5.6
*/
public static final String SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS = "scalability.maximumTrivialExpressions"; //$NON-NLS-1$
/**
* Default value for {@link #SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS}.
* @since 5.6
*/
public static final int DEFAULT_SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS = 1000;
/**
* Returns the node in the preference in the given context.
* @param key The preference key.

View file

@ -67,5 +67,9 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
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);
// Scalability defaults.
defaultPreferences.putBoolean(CCorePreferenceConstants.SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS, CCorePreferenceConstants.DEFAULT_SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS);
defaultPreferences.putInt(CCorePreferenceConstants.SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS, CCorePreferenceConstants.DEFAULT_SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS);
}
}

View file

@ -4481,4 +4481,25 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
public void testHistoryWithDuplicatesWithDifferentNames() throws Exception {
assertRefactoringSuccess();
}
//main.cpp
//int main() {
// /*$*/int array[] = { 1, 2, 3 };
// int i = array[0];/*$$*/
// return i;
//}
//====================
//int extracted() {
// int array[] = { 1, 2, 3 };
// int i = array[0];
// return i;
//}
//
//int main() {
// int i = extracted();
// return i;
//}
public void testExtractArrayInitializer_Bug412380() throws Exception {
assertRefactoringSuccess();
}
}

View file

@ -552,6 +552,9 @@ public final class PreferencesMessages extends NLS {
public static String ScalabilityPreferencePage_note;
public static String ScalabilityPreferencePage_preferenceOnlyForNewEditors;
public static String ScalabilityPreferencePage_contentAssist_autoActivation;
public static String ScalabilityPreferencePage_parserSettings_group_label;
public static String ScalabilityPreferencePage_skipTrivialExpressions_label;
public static String ScalabilityPreferencePage_maximumTrivialExpressions_label;
private PreferencesMessages() {
// Do not instantiate

View file

@ -14,6 +14,7 @@
# Kirk Beitz (Nokia)
# James Blackburn (Broadcom Corp.)
# Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
# Thomas Corbat (IFS)
###############################################################################
CEditorPreferencePage_link=C/C++ Editor Preferences. General preferences may be set via <a href="org.eclipse.ui.preferencePages.GeneralTextEditor">Text Editors</a>.
@ -617,4 +618,6 @@ ScalabilityPreferencePage_contentAssist_label= Disable parsing-based content ass
ScalabilityPreferencePage_contentAssist_autoActivation= Disable content assist auto-activation
ScalabilityPreferencePage_note=Note:
ScalabilityPreferencePage_preferenceOnlyForNewEditors=Some options do not affect open editors
ScalabilityPreferencePage_parserSettings_group_label= Parser settings
ScalabilityPreferencePage_skipTrivialExpressions_label= Skip trivial expressions in initializer lists
ScalabilityPreferencePage_maximumTrivialExpressions_label= Maximum number of trivial expressions in initializer lists to parse:

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
* Copyright (c) 2000, 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 Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
@ -18,6 +19,7 @@ import java.util.Map;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
@ -26,6 +28,7 @@ import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
@ -38,8 +41,8 @@ import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import com.ibm.icu.text.MessageFormat;
import org.eclipse.cdt.core.CCorePreferenceConstants;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
@ -63,6 +66,12 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
private Button fContentAssistAutoActivation;
private BooleanFieldEditor fSkipTrivialExpressions;
private IntegerFieldEditor fMaximumTrivialExpressions;
private Composite fParserSettingsComposite;
private final Map<Object, String> fCheckBoxes= new HashMap<Object, String>();
/**
@ -107,6 +116,10 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
listener.widgetSelected(null);
}
fLinesToTrigger.setStringValue(Integer.toString(prefs.getInt(PreferenceConstants.SCALABILITY_NUMBER_OF_LINES)));
fSkipTrivialExpressions.load();
fMaximumTrivialExpressions.load();
updateEnable();
}
/*
@ -146,6 +159,10 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
new Separator().doFillIntoGrid(composite, nColumns);
createParserSettings(composite);
new Separator().doFillIntoGrid(composite, nColumns);
String noteTitle= PreferencesMessages.ScalabilityPreferencePage_note;
String noteMessage= PreferencesMessages.ScalabilityPreferencePage_preferenceOnlyForNewEditors;
Composite noteControl= createNoteComposite(JFaceResources.getDialogFont(), composite, noteTitle, noteMessage);
@ -182,26 +199,8 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
createCheckButton(group, PreferencesMessages.ScalabilityPreferencePage_detection_label,PreferenceConstants.SCALABILITY_ALERT);
Composite comp= new Composite(group, SWT.NONE);
fLinesToTrigger = new IntegerFieldEditor( PreferenceConstants.SCALABILITY_NUMBER_OF_LINES, PreferencesMessages.ScalabilityPreferencePage_trigger_lines_label, comp);
GridData data = (GridData)fLinesToTrigger.getTextControl( comp ).getLayoutData();
data.horizontalAlignment = GridData.BEGINNING;
data.widthHint = convertWidthInCharsToPixels( 11 );
fLinesToTrigger.setPage( this );
fLinesToTrigger.setValidateStrategy( StringFieldEditor.VALIDATE_ON_KEY_STROKE );
fLinesToTrigger.setValidRange( 1, Integer.MAX_VALUE );
String minValue = Integer.toString( 1 );
String maxValue = Integer.toString( Integer.MAX_VALUE );
fLinesToTrigger.setErrorMessage( MessageFormat.format(PreferencesMessages.ScalabilityPreferencePage_error, new Object[] {minValue, maxValue}) );
fLinesToTrigger.load();
fLinesToTrigger.setPropertyChangeListener( new IPropertyChangeListener() {
@Override
public void propertyChange( PropertyChangeEvent event ) {
if ( event.getProperty().equals( FieldEditor.IS_VALID ) )
setValid( fLinesToTrigger.isValid() );
}
} );
fLinesToTrigger = createIntegerField(comp, PreferenceConstants.SCALABILITY_NUMBER_OF_LINES,
PreferencesMessages.ScalabilityPreferencePage_trigger_lines_label, 1, Integer.MAX_VALUE);
}
/**
@ -228,6 +227,55 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
createDependency(fEnableAll, PreferenceConstants.SCALABILITY_ENABLE_ALL, fContentAssistAutoActivation, false);
}
private void createParserSettings(Composite parent) {
final Composite parserSettingsGroup = createGroupComposite(parent, 1,
PreferencesMessages.ScalabilityPreferencePage_parserSettings_group_label);
final Composite skipTrivialComposite = new Composite(parserSettingsGroup, SWT.NONE);
fSkipTrivialExpressions = new BooleanFieldEditor(CCorePreferenceConstants.SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS,
PreferencesMessages.ScalabilityPreferencePage_skipTrivialExpressions_label, skipTrivialComposite);
fSkipTrivialExpressions.setPreferenceStore(CUIPlugin.getDefault().getCorePreferenceStore());
fParserSettingsComposite = new Composite(parserSettingsGroup, SWT.NONE);
fMaximumTrivialExpressions = createIntegerField(fParserSettingsComposite,
CCorePreferenceConstants.SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS,
PreferencesMessages.ScalabilityPreferencePage_maximumTrivialExpressions_label, 0, Integer.MAX_VALUE);
fMaximumTrivialExpressions.setPreferenceStore(CUIPlugin.getDefault().getCorePreferenceStore());
fSkipTrivialExpressions.setPropertyChangeListener(new IPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
updateEnable();
}
});
}
private void updateEnable() {
fMaximumTrivialExpressions.setEnabled(fSkipTrivialExpressions.getBooleanValue(), fParserSettingsComposite);
}
private IntegerFieldEditor createIntegerField(Composite parent, String name, String labelText, int rangeMinimum, int rangeMaximum) {
final IntegerFieldEditor integerField = new IntegerFieldEditor(name, labelText, parent);
GridData data = (GridData) integerField.getTextControl(parent).getLayoutData();
data.horizontalAlignment = GridData.BEGINNING;
data.widthHint = convertWidthInCharsToPixels(11);
integerField.setPage(this);
integerField.setValidateStrategy(StringFieldEditor.VALIDATE_ON_KEY_STROKE);
integerField.setValidRange(rangeMinimum, rangeMaximum);
integerField.setErrorMessage(NLS.bind(PreferencesMessages.ScalabilityPreferencePage_error,
new Object[] { rangeMinimum, rangeMaximum }));
integerField.load();
integerField.setPropertyChangeListener(new IPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(FieldEditor.IS_VALID))
setValid(integerField.isValid());
}
});
return integerField;
}
private static void indent(Control control, GridData masterLayoutData) {
GridData gridData= new GridData();
gridData.horizontalIndent= masterLayoutData.horizontalIndent + 20;
@ -281,6 +329,8 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
prefs.setValue(key, b.getSelection());
}
prefs.setValue(PreferenceConstants.SCALABILITY_NUMBER_OF_LINES, fLinesToTrigger.getIntValue());
fSkipTrivialExpressions.store();
fMaximumTrivialExpressions.store();
return super.performOk();
}
@ -305,5 +355,8 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe
listener.widgetSelected(null);
}
fLinesToTrigger.setStringValue(Integer.toString(prefs.getDefaultInt(PreferenceConstants.SCALABILITY_NUMBER_OF_LINES)));
fSkipTrivialExpressions.loadDefault();
fMaximumTrivialExpressions.loadDefault();
updateEnable();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2012 Google, Inc and others.
* Copyright (c) 2010, 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
@ -7,6 +7,7 @@
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring;
@ -41,7 +42,6 @@ import org.eclipse.cdt.internal.ui.editor.ASTProvider;
public class CRefactoringContext extends RefactoringContext {
private static final int PARSE_MODE = ITranslationUnit.AST_SKIP_ALL_HEADERS
| ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT
| ITranslationUnit.AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS
| ITranslationUnit.AST_PARSE_INACTIVE_CODE;
private final Map<ITranslationUnit, IASTTranslationUnit> fASTCache;
@ -85,6 +85,11 @@ public class CRefactoringContext extends RefactoringContext {
} else {
ast = ASTProvider.getASTProvider().acquireSharedAST(tu, fIndex,
ASTProvider.WAIT_ACTIVE_ONLY, pm);
if (ast != null && ast.hasNodesOmitted()) {
// Don't use an incomplete AST.
ASTProvider.getASTProvider().releaseSharedAST(ast);
ast = null;
}
if (ast == null) {
if (pm != null && pm.isCanceled())
throw new OperationCanceledException();