From b40866ce3206c386e443d4cc45430503aaf1ae60 Mon Sep 17 00:00:00 2001 From: Thomas Corbat Date: Tue, 9 Jul 2013 16:40:36 +0200 Subject: [PATCH] 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 IP-Clean: Thomas Corbat Tested-by: Thomas Corbat --- .../parser/tests/ast2/AST2TemplateTests.java | 2 +- .../core/parser/tests/ast2/AST2TestBase.java | 13 +- .../cdt/core/parser/tests/ast2/AST2Tests.java | 123 +++++++++++++----- .../LanguageSettingsScannerInfoProvider.java | 24 +++- .../cdt/core/dom/ast/IASTTranslationUnit.java | 15 ++- .../cdt/core/dom/ast/gnu/c/GCCLanguage.java | 14 ++ .../cdt/core/dom/ast/gnu/cpp/GPPLanguage.java | 14 ++ .../dom/parser/AbstractCLikeLanguage.java | 57 ++++++-- .../cdt/core/parser/ExtendedScannerInfo.java | 21 ++- .../cdt/core/parser/IParserSettings.java | 25 ++++ .../cdt/core/parser/ParserSettings.java | 34 +++++ .../internal/core/dom/parser/ASTQueries.java | 11 +- .../core/dom/parser/ASTTranslationUnit.java | 16 ++- .../parser/AbstractGNUSourceCodeParser.java | 29 +++-- .../core/dom/parser/c/GNUCSourceParser.java | 27 ++-- .../dom/parser/cpp/GNUCPPSourceParser.java | 16 +-- .../core/pdom/AbstractIndexerTask.java | 11 +- .../cdt/core/CCorePreferenceConstants.java | 32 +++++ .../core/CCorePreferenceInitializer.java | 4 + .../ExtractFunctionRefactoringTest.java | 21 +++ .../ui/preferences/PreferencesMessages.java | 3 + .../PreferencesMessages.properties | 5 +- .../ScalabilityPreferencePage.java | 109 ++++++++++++---- .../ui/refactoring/CRefactoringContext.java | 11 +- 24 files changed, 505 insertions(+), 132 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParserSettings.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserSettings.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index b7a861c27c9..b695e39f01b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -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); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index 9d88bb2a088..9e3ef8a38bb 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -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); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index f4358768c91..4eaa0621f54 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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; @@ -5847,23 +5850,16 @@ public class AST2Tests extends AST2TestBase { // }; public void testScalabilityOfLargeTrivialInitializer_253690() throws Exception { - sValidateCopy= false; - final int AMOUNT= 250000; + 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); - long diff= memoryUsed()-mem; - // allow a copy of the buffer + less than 2 bytes per initializer - final int expected = code.length()*2 + AMOUNT + AMOUNT/2; + long mem = memoryUsed(); + IASTTranslationUnit tu = parse(code, lang, false, true, 0); + long diff = memoryUsed() - mem; + // 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()); } @@ -5880,28 +5876,75 @@ public class AST2Tests extends AST2TestBase { // } // }; public void testLargeTrivialAggregateInitializer_253690() throws Exception { - sValidateCopy= false; - final int AMOUNT= 250000; + 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); - long diff= memoryUsed()-mem; - // allow a copy of the buffer + not even 1 byte per initializer - final int expected = code.length()*2 + AMOUNT + AMOUNT/2; + long mem = memoryUsed(); + IASTTranslationUnit tu = parse(code, lang, false, true, 0); + long diff = memoryUsed() - mem; + // 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); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java index 9e34a363860..13d41d28c30 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index 30652baa00c..67cfa3dd477 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java index 11012eca605..1b5b57e2a01 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java index da1d20f1800..8db04ebf060 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java index afdee032fb2..14000e094e7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/AbstractCLikeLanguage.java @@ -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; + ParserMode mode = createParserMode(forCompletion, options); + return createParser(scanner, mode, log, index); + } + + /** + * 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) { - mode= ParserMode.COMPLETION_PARSE; + return ParserMode.COMPLETION_PARSE; } else if ((options & OPTION_SKIP_FUNCTION_BODIES) != 0) { - mode= ParserMode.STRUCTURAL_PARSE; + return ParserMode.STRUCTURAL_PARSE; } else { - mode= ParserMode.COMPLETE_PARSE; + return ParserMode.COMPLETE_PARSE; } - - 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); - } - } - return parser; } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ExtendedScannerInfo.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ExtendedScannerInfo.java index d6872ced177..5c903c0fffe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ExtendedScannerInfo.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ExtendedScannerInfo.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParserSettings.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParserSettings.java new file mode 100644 index 00000000000..e7dcdbb0dcf --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParserSettings.java @@ -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(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserSettings.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserSettings.java new file mode 100644 index 00000000000..aa041d3d51f --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserSettings.java @@ -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; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java index 7c3736634e1..55b707a3154 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java @@ -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(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java index 2c092ccc2bd..e3e6fe5b925 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTranslationUnit.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 3c1450d3883..4804742a88c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index d74fefd9ea1..83c43052647 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -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 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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 71d7c47e712..843ce659c20 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java index 9150a63b971..d509b6b16e1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java index 88b72cd45e1..861537e43aa 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java @@ -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. + *

+ * Value is of type Boolean. + * + * @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 SCALABILITY_SKIP_TRIVIAL_EXPRESSIONS is set to true. + *

+ * Value is of type int. + *

+ * + * @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. diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java index 9720c7e9be0..587bc70d905 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java @@ -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); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java index 76a7edcea93..4fb1c6935d9 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractfunction/ExtractFunctionRefactoringTest.java @@ -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(); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java index 76e81c64de2..2b7fc5d6c4b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java @@ -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 diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties index 7df1f6e73a5..5fbc879261f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties @@ -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 Text Editors. @@ -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: diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ScalabilityPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ScalabilityPreferencePage.java index 64477f479b0..7bef09509b6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ScalabilityPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ScalabilityPreferencePage.java @@ -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; @@ -62,9 +65,15 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe private Button fContentAssist; private Button fContentAssistAutoActivation; - + + private BooleanFieldEditor fSkipTrivialExpressions; + + private IntegerFieldEditor fMaximumTrivialExpressions; + + private Composite fParserSettingsComposite; + private final Map fCheckBoxes= new HashMap(); - + /** * List of master/slave listeners when there's a dependency. * @@ -99,7 +108,7 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe String key= fCheckBoxes.get(b); b.setSelection(prefs.getBoolean(key)); } - + // Update slaves iter= fMasterSlaveListeners.iterator(); while (iter.hasNext()) { @@ -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(); } /* @@ -144,6 +157,10 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe createScalabilityModeSettings(composite); + new Separator().doFillIntoGrid(composite, nColumns); + + createParserSettings(composite); + new Separator().doFillIntoGrid(composite, nColumns); String noteTitle= PreferencesMessages.ScalabilityPreferencePage_note; @@ -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); } /** @@ -227,7 +226,56 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe createDependency(fContentAssist, PreferenceConstants.SCALABILITY_PARSER_BASED_CONTENT_ASSIST, fContentAssistAutoActivation, true); 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(); } @@ -297,7 +347,7 @@ public class ScalabilityPreferencePage extends PreferencePage implements IWorkbe String key= fCheckBoxes.get(b); b.setSelection(prefs.getDefaultBoolean(key)); } - + // Update slaves iter= fMasterSlaveListeners.iterator(); while (iter.hasNext()) { @@ -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(); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoringContext.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoringContext.java index c1626864fa4..2d2636d0e07 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoringContext.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoringContext.java @@ -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 fASTCache; @@ -85,8 +85,13 @@ 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()) + if (pm != null && pm.isCanceled()) throw new OperationCanceledException(); ast= tu.getAST(fIndex, PARSE_MODE); fASTCache.put(tu, ast);