diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java index 7a1ce49f73b..7b0c5b1145b 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java @@ -15,14 +15,10 @@ import org.eclipse.cdt.codan.core.cxx.Activator; import org.eclipse.cdt.codan.core.model.AbstractChecker; import org.eclipse.cdt.codan.core.model.IProblemLocation; import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -44,24 +40,19 @@ public abstract class AbstractIndexAstChecker extends AbstractChecker implements protected IFile getFile() { return file; } + protected IProject getProject() { - return file==null?null:file.getProject(); + return file == null ? null : file.getProject(); } void processFile(IFile file) throws CoreException, InterruptedException { - // create translation unit and access index - ICElement model = CoreModel.getDefault().create(file); - if (!(model instanceof ITranslationUnit)) - return; // not a C/C++ file - ITranslationUnit tu = (ITranslationUnit) model; - IIndex index = CCorePlugin.getIndexManager().getIndex(tu.getCProject()); + IASTTranslationUnit ast = CxxModelsCache.getInstance().getAst(file); + if (ast == null) + return; // lock the index for read access + IIndex index = CxxModelsCache.getInstance().getIndex(file); index.acquireReadLock(); try { - // create index based ast - IASTTranslationUnit ast = tu.getAST(index, - ITranslationUnit.AST_SKIP_INDEXED_HEADERS); - if (ast==null) return;// // traverse the ast using the visitor pattern. this.file = file; processAst(ast); @@ -87,21 +78,21 @@ public abstract class AbstractIndexAstChecker extends AbstractChecker implements } @SuppressWarnings("restriction") - public void reportProblem(String id, IASTNode astNode, Object... args) { + public void reportProblem(String id, IASTNode astNode, Object... args) { IASTFileLocation astLocation = astNode.getFileLocation(); IPath location = new Path(astLocation.getFileName()); - IFile astFile = ResourceLookup.selectFileForLocation(location, getProject()); + IFile astFile = ResourceLookup.selectFileForLocation(location, + getProject()); if (astFile == null) { astFile = file; } if (astFile == null) { - Activator.log("Cannot resolve location: "+location); //$NON-NLS-1$ + Activator.log("Cannot resolve location: " + location); //$NON-NLS-1$ return; } IProblemLocation loc; int line = astLocation.getStartingLineNumber(); - if (line == astLocation - .getEndingLineNumber()) + if (line == astLocation.getEndingLineNumber()) loc = getRuntime().getProblemLocationFactory() .createProblemLocation( astFile, @@ -110,8 +101,7 @@ public abstract class AbstractIndexAstChecker extends AbstractChecker implements + astLocation.getNodeLength(), line); else loc = getRuntime().getProblemLocationFactory() - .createProblemLocation(astFile, - line); + .createProblemLocation(astFile, line); getProblemReporter().reportProblem(id, loc, args); } @@ -128,11 +118,12 @@ public abstract class AbstractIndexAstChecker extends AbstractChecker implements * (java.lang.Object) */ @SuppressWarnings("restriction") - public void processModel(Object model) { + public synchronized void processModel(Object model) { if (model instanceof IASTTranslationUnit) { IASTTranslationUnit ast = (IASTTranslationUnit) model; IPath location = new Path(ast.getFilePath()); - IFile astFile = ResourceLookup.selectFileForLocation(location, getProject()); + IFile astFile = ResourceLookup.selectFileForLocation(location, + getProject()); file = astFile; processAst(ast); } diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java new file mode 100644 index 00000000000..9ab45f7435a --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/CxxModelsCache.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2009 Alena Laskavaia + * 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: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.cxx.model; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; + +/** + * Cache data models for resource so checkers can share it + */ +public class CxxModelsCache { + private IFile file; + private IASTTranslationUnit ast; + private ITranslationUnit tu; + private IIndex index; + + private static CxxModelsCache instance = new CxxModelsCache(); + + public static CxxModelsCache getInstance() { + return instance; + } + + public synchronized IASTTranslationUnit getAst(IFile file) + throws CoreException, InterruptedException { + if (file.equals(this.file)) { + return ast; + } + + // create translation unit and access index + ICElement celement = CoreModel.getDefault().create(file); + if (!(celement instanceof ITranslationUnit)) + return null; // not a C/C++ file + this.file = file; + System.err.println("Making ast for "+file); + tu = (ITranslationUnit) celement; + index = CCorePlugin.getIndexManager().getIndex(tu.getCProject()); + // lock the index for read access + index.acquireReadLock(); + try { + // create index based ast + ast = tu.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS); + if (ast == null) + return null;// + return ast; + } finally { + index.releaseReadLock(); + } + } + + public synchronized IIndex getIndex(IFile file) + throws CoreException, InterruptedException { + if (file.equals(this.file)) { + return index; + } + getAst(file); // to init variables + return index; + } +} diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java index 7506bc4567c..1a94cedd8a6 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java @@ -115,6 +115,8 @@ public class CodanBuilder extends IncrementalProjectBuilder implements CheckersRegisry chegistry = CheckersRegisry.getInstance(); for (IChecker checker : chegistry) { try { + if (monitor.isCanceled()) + return; if (chegistry.isCheckerEnabled(checker, resource) && checker.enabledInContext(resource)) { checker.processResource(resource);