PageRenderTime 198ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/netbeans-7.3/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/csm/core/ProjectBase.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1075 lines | 901 code | 86 blank | 88 comment | 202 complexity | a9e093800a58cfa4025e9321228aaa5b MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.cnd.modelimpl.csm.core;
  45. import java.io.File;
  46. import java.io.IOException;
  47. import java.io.PrintStream;
  48. import java.io.PrintWriter;
  49. import java.util.ArrayList;
  50. import java.util.Arrays;
  51. import java.util.Collection;
  52. import java.util.Collections;
  53. import java.util.HashMap;
  54. import java.util.HashSet;
  55. import java.util.Iterator;
  56. import java.util.LinkedList;
  57. import java.util.List;
  58. import java.util.Map;
  59. import java.util.Set;
  60. import java.util.StringTokenizer;
  61. import java.util.TreeMap;
  62. import java.util.WeakHashMap;
  63. import java.util.concurrent.ConcurrentHashMap;
  64. import java.util.concurrent.atomic.AtomicBoolean;
  65. import java.util.concurrent.locks.ReadWriteLock;
  66. import java.util.concurrent.locks.ReentrantReadWriteLock;
  67. import java.util.logging.Level;
  68. import org.netbeans.modules.cnd.antlr.collections.AST;
  69. import org.netbeans.modules.cnd.api.model.CsmClass;
  70. import org.netbeans.modules.cnd.api.model.CsmClassifier;
  71. import org.netbeans.modules.cnd.api.model.CsmDeclaration;
  72. import org.netbeans.modules.cnd.api.model.CsmFile;
  73. import org.netbeans.modules.cnd.api.model.CsmFriend;
  74. import org.netbeans.modules.cnd.api.model.CsmInheritance;
  75. import org.netbeans.modules.cnd.api.model.CsmModelAccessor;
  76. import org.netbeans.modules.cnd.api.model.CsmModelState;
  77. import org.netbeans.modules.cnd.api.model.CsmNamespace;
  78. import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration;
  79. import org.netbeans.modules.cnd.api.model.CsmProject;
  80. import org.netbeans.modules.cnd.api.model.CsmUID;
  81. import org.netbeans.modules.cnd.api.model.services.CsmSelect.NameAcceptor;
  82. import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities;
  83. import org.netbeans.modules.cnd.api.model.util.CsmTracer;
  84. import org.netbeans.modules.cnd.api.model.util.UIDs;
  85. import org.netbeans.modules.cnd.api.project.NativeFileItem;
  86. import org.netbeans.modules.cnd.api.project.NativeFileItem.Language;
  87. import org.netbeans.modules.cnd.api.project.NativeProject;
  88. import org.netbeans.modules.cnd.api.project.NativeProjectItemsAdapter;
  89. import org.netbeans.modules.cnd.api.project.NativeProjectItemsListener;
  90. import org.netbeans.modules.cnd.apt.structure.APTFile;
  91. import org.netbeans.modules.cnd.apt.support.APTDriver;
  92. import org.netbeans.modules.cnd.apt.support.APTFileCacheEntry;
  93. import org.netbeans.modules.cnd.apt.support.APTFileCacheManager;
  94. import org.netbeans.modules.cnd.apt.support.APTFileSearch;
  95. import org.netbeans.modules.cnd.apt.support.APTHandlersSupport;
  96. import org.netbeans.modules.cnd.apt.support.APTIncludeHandler;
  97. import org.netbeans.modules.cnd.apt.support.APTIncludePathStorage;
  98. import org.netbeans.modules.cnd.apt.support.APTMacroMap;
  99. import org.netbeans.modules.cnd.apt.support.APTPreprocHandler;
  100. import org.netbeans.modules.cnd.apt.support.APTPreprocHandler.State;
  101. import org.netbeans.modules.cnd.apt.support.APTSystemStorage;
  102. import org.netbeans.modules.cnd.apt.support.APTWalker;
  103. import org.netbeans.modules.cnd.apt.support.IncludeDirEntry;
  104. import org.netbeans.modules.cnd.apt.support.PostIncludeData;
  105. import org.netbeans.modules.cnd.apt.support.StartEntry;
  106. import org.netbeans.modules.cnd.apt.utils.APTSerializeUtils;
  107. import org.netbeans.modules.cnd.apt.utils.APTUtils;
  108. import org.netbeans.modules.cnd.debug.CndTraceFlags;
  109. import org.netbeans.modules.cnd.debug.DebugUtils;
  110. import org.netbeans.modules.cnd.indexing.api.CndTextIndex;
  111. import org.netbeans.modules.cnd.modelimpl.cache.impl.WeakContainer;
  112. import org.netbeans.modules.cnd.modelimpl.content.project.ClassifierContainer;
  113. import org.netbeans.modules.cnd.modelimpl.content.project.DeclarationContainerProject;
  114. import org.netbeans.modules.cnd.modelimpl.content.project.FileContainer;
  115. import org.netbeans.modules.cnd.modelimpl.content.project.FileContainer.FileEntry;
  116. import org.netbeans.modules.cnd.modelimpl.content.project.GraphContainer;
  117. import org.netbeans.modules.cnd.modelimpl.content.project.IncludedFileContainer;
  118. import org.netbeans.modules.cnd.modelimpl.content.project.IncludedFileContainer.Storage;
  119. import org.netbeans.modules.cnd.modelimpl.content.project.ProjectComponent;
  120. import org.netbeans.modules.cnd.modelimpl.csm.ClassEnumBase;
  121. import org.netbeans.modules.cnd.modelimpl.csm.ForwardClass;
  122. import org.netbeans.modules.cnd.modelimpl.csm.FunctionImplEx;
  123. import org.netbeans.modules.cnd.modelimpl.csm.NamespaceImpl;
  124. import org.netbeans.modules.cnd.modelimpl.debug.Diagnostic;
  125. import org.netbeans.modules.cnd.modelimpl.debug.DiagnosticExceptoins;
  126. import org.netbeans.modules.cnd.modelimpl.debug.Terminator;
  127. import org.netbeans.modules.cnd.modelimpl.debug.TraceFlags;
  128. import org.netbeans.modules.cnd.modelimpl.impl.services.FileInfoQueryImpl;
  129. import org.netbeans.modules.cnd.modelimpl.parser.apt.APTParseFileWalker;
  130. import org.netbeans.modules.cnd.modelimpl.parser.apt.APTRestorePreprocStateWalker;
  131. import org.netbeans.modules.cnd.modelimpl.platform.ModelSupport;
  132. import org.netbeans.modules.cnd.modelimpl.repository.ClassifierContainerKey;
  133. import org.netbeans.modules.cnd.modelimpl.repository.FileContainerKey;
  134. import org.netbeans.modules.cnd.modelimpl.repository.GraphContainerKey;
  135. import org.netbeans.modules.cnd.modelimpl.repository.KeyUtilities;
  136. import org.netbeans.modules.cnd.modelimpl.repository.PersistentUtils;
  137. import org.netbeans.modules.cnd.modelimpl.repository.ProjectDeclarationContainerKey;
  138. import org.netbeans.modules.cnd.modelimpl.repository.RepositoryUtils;
  139. import org.netbeans.modules.cnd.modelimpl.textcache.ProjectNameCache;
  140. import org.netbeans.modules.cnd.modelimpl.textcache.QualifiedNameCache;
  141. import org.netbeans.modules.cnd.modelimpl.trace.TraceUtils;
  142. import org.netbeans.modules.cnd.modelimpl.uid.LazyCsmCollection;
  143. import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
  144. import org.netbeans.modules.cnd.modelimpl.uid.UIDManager;
  145. import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
  146. import org.netbeans.modules.cnd.modelimpl.uid.UIDUtilities;
  147. import org.netbeans.modules.cnd.repository.api.RepositoryAccessor;
  148. import org.netbeans.modules.cnd.repository.spi.Key;
  149. import org.netbeans.modules.cnd.repository.spi.Persistent;
  150. import org.netbeans.modules.cnd.repository.spi.RepositoryDataInput;
  151. import org.netbeans.modules.cnd.repository.spi.RepositoryDataOutput;
  152. import org.netbeans.modules.cnd.repository.support.SelfPersistent;
  153. import org.netbeans.modules.cnd.spi.utils.CndFileSystemProvider;
  154. import org.netbeans.modules.cnd.utils.CndPathUtilitities;
  155. import org.netbeans.modules.cnd.utils.CndUtils;
  156. import org.netbeans.modules.cnd.utils.FSPath;
  157. import org.netbeans.modules.cnd.repository.api.CacheLocation;
  158. import org.netbeans.modules.cnd.utils.cache.CndFileUtils;
  159. import org.netbeans.spi.project.CacheDirectoryProvider;
  160. import org.openide.filesystems.FileObject;
  161. import org.openide.filesystems.FileSystem;
  162. import org.openide.filesystems.FileUtil;
  163. import org.openide.util.Cancellable;
  164. import org.openide.util.CharSequences;
  165. import org.openide.util.Lookup.Provider;
  166. import org.openide.util.NbBundle;
  167. import org.openide.util.Parameters;
  168. /**
  169. * Base class for CsmProject implementation
  170. * @author Dmitry Ivanov
  171. * @author Vladimir Kvashin
  172. */
  173. public abstract class ProjectBase implements CsmProject, Persistent, SelfPersistent, CsmIdentifiable,
  174. CndFileSystemProvider.CndFileSystemProblemListener {
  175. protected ProjectBase(ModelImpl model, FileSystem fs, NativeProject platformProject, String name) {
  176. this(model, fs, (Object) platformProject, name, createProjectKey(fs, platformProject));
  177. }
  178. protected ProjectBase(ModelImpl model, FileSystem fs, CharSequence platformProject, String name, CacheLocation cacheLocation) {
  179. this(model, fs, (Object) platformProject, name, createProjectKey(fs, platformProject, cacheLocation));
  180. }
  181. /** Creates a new instance of CsmProjectImpl */
  182. private ProjectBase(ModelImpl model, FileSystem fs, Object platformProject, String name, Key key) {
  183. namespaces = new ConcurrentHashMap<CharSequence, CsmUID<CsmNamespace>>();
  184. this.uniqueName = getUniqueName(fs, platformProject);
  185. RepositoryUtils.openUnit(key);
  186. unitId = key.getUnitId();
  187. cacheLocation = RepositoryAccessor.getTranslator().getCacheLocation(unitId);
  188. setStatus(Status.Initial);
  189. this.name = ProjectNameCache.getManager().getString(name);
  190. this.fileSystem = fs;
  191. init(model, platformProject);
  192. sysAPTData = APTSystemStorage.getInstance();
  193. userPathStorage = new APTIncludePathStorage();
  194. declarationsSorageKey = new ProjectDeclarationContainerKey(unitId);
  195. weakDeclarationContainer = new WeakContainer<DeclarationContainerProject>(this, declarationsSorageKey);
  196. classifierStorageKey = new ClassifierContainerKey(unitId);
  197. weakClassifierContainer = new WeakContainer<ClassifierContainer>(this, classifierStorageKey);
  198. fileContainerKey = new FileContainerKey(unitId);
  199. weakFileContainer = new WeakContainer<FileContainer>(this, fileContainerKey);
  200. graphStorageKey = new GraphContainerKey(unitId);
  201. weakGraphContainer = new WeakContainer<GraphContainer>(this, graphStorageKey);
  202. includedFileContainer = new IncludedFileContainer(this);
  203. initFields();
  204. }
  205. /*package*/final void initFields() {
  206. NamespaceImpl ns = NamespaceImpl.create(this, false);
  207. assert ns != null;
  208. this.globalNamespaceUID = UIDCsmConverter.namespaceToUID(ns);
  209. DeclarationContainerProject declarationContainer = new DeclarationContainerProject(this);
  210. CndUtils.assertTrue(declarationsSorageKey.equals(declarationContainer.getKey()));
  211. weakDeclarationContainer.clear();
  212. ClassifierContainer classifierContainer = new ClassifierContainer(this);
  213. CndUtils.assertTrue(classifierStorageKey.equals(classifierContainer.getKey()));
  214. weakClassifierContainer.clear();
  215. FileContainer fileContainer = new FileContainer(this);
  216. CndUtils.assertTrue(fileContainerKey.equals(fileContainer.getKey()));
  217. weakFileContainer.clear();
  218. GraphContainer graphContainer = new GraphContainer(this);
  219. CndUtils.assertTrue(graphStorageKey.equals(graphContainer.getKey()));
  220. weakGraphContainer.clear();
  221. includedFileContainer.clear();
  222. FAKE_GLOBAL_NAMESPACE = NamespaceImpl.create(this, true);
  223. }
  224. private void init(ModelImpl model, Object platformProject) {
  225. this.model = model;
  226. assert (platformProject instanceof NativeProject) || (platformProject instanceof CharSequence);
  227. this.platformProject = platformProject;
  228. // remember in repository
  229. RepositoryUtils.hang(this);
  230. // create global namespace
  231. if (TraceFlags.CLOSE_AFTER_PARSE) {
  232. Terminator.create(this);
  233. }
  234. }
  235. private boolean checkConsistency(boolean restoring) {
  236. long time = TraceFlags.TIMING ? System.currentTimeMillis() : 0;
  237. if (getFileContainer() == FileContainer.empty()) {
  238. return false;
  239. }
  240. if (getDeclarationsSorage() == DeclarationContainerProject.empty()) {
  241. return false;
  242. }
  243. if (getGraph() == GraphContainer.empty()) {
  244. return false;
  245. }
  246. if (getGlobalNamespace() == FAKE_GLOBAL_NAMESPACE) {
  247. return false;
  248. }
  249. if (TraceFlags.TIMING || CndUtils.isUnitTestMode()) {
  250. if (TraceFlags.TIMING) {
  251. System.err.printf("Consistency check took %d ms\n", System.currentTimeMillis() - time);
  252. }
  253. time = System.currentTimeMillis();
  254. checkFileContainerConsistency(restoring);
  255. if (TraceFlags.TIMING) {
  256. System.err.printf("File Container Consistency check took %d ms\n", System.currentTimeMillis() - time);
  257. }
  258. }
  259. return true;
  260. }
  261. private void checkFileContainerConsistency(boolean restoring) {
  262. if (this.isArtificial()) {
  263. return;
  264. }
  265. Set<FileImpl> allFileImpls = new HashSet<FileImpl>(this.getAllFileImpls());
  266. Storage storageForSelf = this.includedFileContainer.getStorageForProject(this);
  267. if (storageForSelf != null) {
  268. for (Map.Entry<CharSequence, FileEntry> entry : storageForSelf.getInternalMap().entrySet()) {
  269. FileImpl file = getFileContainer().getFile(entry.getKey(), true);
  270. if (file == null || !allFileImpls.contains(file)) {
  271. CndUtils.assertTrueInConsole(false, "no file enty for included file ", entry);
  272. }
  273. }
  274. }
  275. for (FileImpl fileImpl : allFileImpls) {
  276. checkFileEntryConsistency(fileImpl, restoring);
  277. }
  278. }
  279. private void checkFileEntryConsistency(FileImpl fileImpl, boolean restoring) {
  280. CharSequence fileKey = fileImpl.getAbsolutePath();
  281. FileImpl.State fileState = fileImpl.getState();
  282. FileEntry entry = getFileContainer().getEntry(fileKey);
  283. if (entry != null) {
  284. Object lock = entry.getLock();
  285. synchronized (lock) {
  286. List<PreprocessorStatePair> fcPairs = new ArrayList<PreprocessorStatePair>(entry.getStatePairs());
  287. if (fcPairs.isEmpty() && fileState != FileImpl.State.INITIAL) {
  288. CndUtils.assertTrueInConsole(false, "no states for own file ", fileImpl);
  289. }
  290. boolean hasParsing = false;
  291. Boolean hasValid = fcPairs.isEmpty() ? Boolean.TRUE : null;
  292. // check own File Container and remember what we have found for checking own includes files
  293. // from includedFileContainer later
  294. for (PreprocessorStatePair fcPair : fcPairs) {
  295. if (fileState == FileImpl.State.PARSED) {
  296. CndUtils.assertTrueInConsole(fcPair.state.isValid(), "FC Should not contain invalid ", fcPair);
  297. CndUtils.assertTrueInConsole(fcPair.pcState != FilePreprocessorConditionState.PARSING, "FC Should not contain PARSING ", fcPair);
  298. }
  299. if (fcPair.pcState == FilePreprocessorConditionState.PARSING) {
  300. hasParsing = true;
  301. }
  302. if (hasValid == null) {
  303. hasValid = fcPair.state.isValid();
  304. }
  305. CndUtils.assertTrueInConsole(hasValid == fcPair.state.isValid(), "FC Should not contain " + hasValid, fcPair);
  306. }
  307. CsmUID<CsmFile> testFileUID = entry.getTestFileUID();
  308. FileImpl testFileImpl = (FileImpl) UIDCsmConverter.UIDtoFile(testFileUID);
  309. if (!testFileImpl.equals(fileImpl)) {
  310. CndUtils.assertTrueInConsole(false, "different files: " + fileImpl, testFileImpl);
  311. }
  312. // check if input file was included by 'this' project
  313. FileEntry includedFileEntry = this.includedFileContainer.getIncludedFileEntry(lock, this, fileKey);
  314. if (includedFileEntry != null) {
  315. // it was included => check in which states it was included from 'this' project
  316. List<PreprocessorStatePair> inclPairs = new ArrayList<PreprocessorStatePair>(includedFileEntry.getStatePairs());
  317. if (inclPairs.isEmpty()) {
  318. CndUtils.assertTrueInConsole(false, "no included states for included file ", fileImpl);
  319. } else {
  320. for (PreprocessorStatePair inclPair : inclPairs) {
  321. if (fileState == FileImpl.State.PARSED) {
  322. CndUtils.assertTrueInConsole(inclPair.state.isValid(), "Should not contain invalid ", inclPair);
  323. CndUtils.assertTrueInConsole(inclPair.pcState != FilePreprocessorConditionState.PARSING, "Should not contain PARSING ", inclPair);
  324. }
  325. // check that any own include files are contributing in own FC container the same way
  326. List<PreprocessorStatePair> statesToKeep = new ArrayList<PreprocessorStatePair>(4);
  327. AtomicBoolean newStateFound = new AtomicBoolean();
  328. ComparisonResult resultPP;
  329. resultPP = fillStatesToKeepBasedOnPPState(inclPair.state, fcPairs, statesToKeep, newStateFound);
  330. if (inclPair.state.isValid()) {
  331. if (resultPP != ComparisonResult.KEEP_WITH_OTHERS) {
  332. CndUtils.assertTrueInConsole(false, "Should not contribute [" + restoring + "," + hasParsing + "] " + newStateFound + " " + resultPP + " pair into File Container (state based) " + inclPair + "vs.\n", fcPairs);
  333. }
  334. } else {
  335. CndUtils.assertTrueInConsole(resultPP == ComparisonResult.DISCARD && !hasValid, "Should not contribute invalid [" + restoring + "," + hasParsing + "] " + newStateFound + " " + resultPP + " pair into File Container (state based) " + inclPair + "vs.\n", fcPairs);
  336. }
  337. // check that any own include files are contributing has not worse PC state in own FC container
  338. ComparisonResult resultPC = fillStatesToKeepBasedOnPCState(inclPair.pcState, fcPairs, statesToKeep);
  339. if (resultPC != ComparisonResult.DISCARD) {
  340. CndUtils.assertTrueInConsole(inclPair.pcState == FilePreprocessorConditionState.PARSING && hasParsing, "Should not contribute [" + restoring + "," + hasParsing + "] " + newStateFound + " " + resultPC + " pair into File Container (PCState based) " + inclPair, fcPairs);
  341. }
  342. }
  343. }
  344. }
  345. }
  346. } else {
  347. CndUtils.assertTrueInConsole(false, "no entry for ", fileKey);
  348. }
  349. }
  350. private void setStatus(Status newStatus) {
  351. //System.err.printf("CHANGING STATUS %s -> %s for %s (%s)\n", status, newStatus, name, getClass().getName());
  352. status = newStatus;
  353. }
  354. protected static void cleanRepository(FileSystem fs, NativeProject platformProject, boolean articicial) {
  355. Key key = createProjectKey(fs, platformProject);
  356. RepositoryUtils.closeUnit(key, null, true);
  357. }
  358. protected static void cleanRepository(FileSystem fs, CharSequence platformProject, boolean articicial, CacheLocation cacheLocation) {
  359. Key key = createProjectKey(fs, platformProject, cacheLocation);
  360. RepositoryUtils.closeUnit(key, null, true);
  361. }
  362. private static Key createProjectKey(FileSystem fs, NativeProject platfProj) {
  363. return KeyUtilities.createProjectKey(getUniqueName(fs, platfProj), ProjectBase.getCacheLocation(platfProj));
  364. }
  365. private static Key createProjectKey(FileSystem fs, CharSequence platfProj, CacheLocation cacheLocation) {
  366. return KeyUtilities.createProjectKey(getUniqueName(fs, platfProj), cacheLocation);
  367. }
  368. protected static ProjectBase readInstance(ModelImpl model, FileSystem fs, NativeProject platformProject, String name) {
  369. return readInstance(model, createProjectKey(fs, platformProject), platformProject, name);
  370. }
  371. protected static ProjectBase readInstance(ModelImpl model, FileSystem fs, CharSequence platformProject, String name, CacheLocation cacheLocation) {
  372. ProjectBase instance = readInstance(model, createProjectKey(fs, platformProject, cacheLocation), platformProject, name);
  373. return instance;
  374. }
  375. private static ProjectBase readInstance(ModelImpl model, Key key, Object platformProject, String name) {
  376. long time = 0;
  377. if (TraceFlags.TIMING) {
  378. System.err.printf("Project %s: instantiating...\n", name);
  379. time = System.currentTimeMillis();
  380. }
  381. assert TraceFlags.PERSISTENT_REPOSITORY;
  382. RepositoryUtils.openUnit(key);
  383. Persistent o = RepositoryUtils.get(key);
  384. if (o != null) {
  385. assert o instanceof ProjectBase;
  386. ProjectBase impl = (ProjectBase) o;
  387. CharSequence aName = ProjectNameCache.getManager().getString(name);
  388. if (!impl.name.equals(aName)) {
  389. impl.setName(aName);
  390. }
  391. impl.init(model, platformProject);
  392. if (TraceFlags.TIMING) {
  393. time = System.currentTimeMillis() - time;
  394. System.err.printf("Project %s: loaded. %d ms\n", name, time);
  395. }
  396. UIDManager.instance().clearProjectCache(key);
  397. if (impl.checkConsistency(true)) {
  398. return impl;
  399. }
  400. }
  401. return null;
  402. }
  403. @Override
  404. public final CsmNamespace getGlobalNamespace() {
  405. return _getGlobalNamespace();
  406. }
  407. @Override
  408. public final CharSequence getName() {
  409. return name;
  410. }
  411. protected final void setName(CharSequence name) {
  412. this.name = name;
  413. }
  414. /**
  415. * Returns a string that uniquely identifies this project.
  416. * One should never rely on this name structure,
  417. * just use it as in unique identifier
  418. */
  419. public final CharSequence getUniqueName() {
  420. return uniqueName;
  421. }
  422. public static CharSequence getUniqueName(NativeProject platformProject) {
  423. return getUniqueName(platformProject.getFileSystem(), platformProject);
  424. }
  425. public final CacheLocation getCacheLocation() {
  426. return cacheLocation;
  427. }
  428. public static CacheLocation getCacheLocation(NativeProject project) {
  429. assert project != null;
  430. Provider lp = project.getProject();
  431. if (lp != null) {
  432. CacheDirectoryProvider loc = lp.getLookup().lookup(CacheDirectoryProvider.class);
  433. if (loc != null) {
  434. try {
  435. FileObject cacheDir = loc.getCacheDirectory();
  436. if (cacheDir != null) {
  437. File cacheDirFile = FileUtil.toFile(cacheDir);
  438. if (cacheDirFile != null) {
  439. return new CacheLocation(new File(cacheDirFile, "cnd/model")); //NOI18N
  440. }
  441. }
  442. } catch (IOException ex) {
  443. ex.printStackTrace(System.err);
  444. }
  445. }
  446. }
  447. return CacheLocation.DEFAULT;
  448. }
  449. @Override
  450. public String getDisplayName() {
  451. if (CndFileUtils.isLocalFileSystem(fileSystem)) {
  452. return name.toString();
  453. } else {
  454. return NbBundle.getMessage(getClass(), "ProjectDisplayName", name, fileSystem.getDisplayName());
  455. }
  456. }
  457. @Override
  458. public String getHtmlDisplayName() {
  459. if (CndFileUtils.isLocalFileSystem(fileSystem)) {
  460. return name.toString();
  461. } else {
  462. return NbBundle.getMessage(getClass(), "ProjectHtmlDisplayName", name, fileSystem.getDisplayName());
  463. }
  464. }
  465. public static CharSequence getUniqueName(FileSystem fs, Object platformProject) {
  466. Parameters.notNull("FileSystem", fs); //NOI18N
  467. String postfix = CndFileUtils.isLocalFileSystem(fs) ? "" : fs.getDisplayName();
  468. String result;
  469. if (platformProject instanceof NativeProject) {
  470. result = ((NativeProject) platformProject).getProjectRoot() + "/N/" + postfix; // NOI18N
  471. } else if (platformProject instanceof CharSequence) {
  472. result = ((CharSequence)platformProject).toString() + "/L/" + postfix; // NOI18N
  473. } else if (platformProject == null) {
  474. throw new IllegalArgumentException("Incorrect platform project: null"); // NOI18N
  475. } else {
  476. throw new IllegalArgumentException("Incorrect platform project class: " + platformProject.getClass()); // NOI18N
  477. }
  478. return ProjectNameCache.getManager().getString(result);
  479. }
  480. /** Gets an object, which represents correspondent IDE project */
  481. @Override
  482. public final Object getPlatformProject() {
  483. assert (platformProject == null) || (platformProject instanceof NativeProject) || (platformProject instanceof CharSequence);
  484. return platformProject;
  485. }
  486. /** Gets an object, which represents correspondent IDE project */
  487. protected final void setPlatformProject(CharSequence platformProject) {
  488. setPlatformProjectImpl(platformProject);
  489. }
  490. protected final void setPlatformProject(NativeProject platformProject) {
  491. setPlatformProjectImpl(platformProject);
  492. }
  493. private void setPlatformProjectImpl(Object platformProject) {
  494. assert (platformProject == null) || (platformProject instanceof NativeProject) || (platformProject instanceof CharSequence);
  495. CndUtils.assertTrue(this.platformProject == null);
  496. CndUtils.assertNotNull(platformProject, "Passing null project for ", this);
  497. this.platformProject = platformProject;
  498. checkUniqueNameConsistency();
  499. }
  500. private void checkUniqueNameConsistency() {
  501. if (CndUtils.isDebugMode()) {
  502. CharSequence expectedUniqueName = getUniqueName(fileSystem, platformProject);
  503. CharSequence defactoUniqueName = this.uniqueName;
  504. if (!defactoUniqueName.equals(expectedUniqueName)) {
  505. CndUtils.assertTrue(false,
  506. "Existing project unique name differ: " + defactoUniqueName + " - expected " + expectedUniqueName + //NOI18N
  507. " Cache location " + cacheLocation); //NOI18N
  508. }
  509. }
  510. }
  511. /** Finds namespace by its qualified name */
  512. public final CsmNamespace findNamespace(CharSequence qualifiedName, boolean findInLibraries) {
  513. CsmNamespace result = findNamespace(qualifiedName);
  514. if (result == null && findInLibraries) {
  515. for (Iterator<CsmProject> it = getLibraries().iterator(); it.hasNext();) {
  516. CsmProject lib = it.next();
  517. result = lib.findNamespace(qualifiedName);
  518. if (result != null) {
  519. break;
  520. }
  521. }
  522. }
  523. return result;
  524. }
  525. /** Finds namespace by its qualified name */
  526. @Override
  527. public final CsmNamespace findNamespace(CharSequence qualifiedName) {
  528. CsmNamespace nsp = _getNamespace(qualifiedName);
  529. return nsp;
  530. }
  531. private static String getNestedNamespaceQualifiedName(CharSequence name, NamespaceImpl parent, boolean createForEmptyNames) {
  532. StringBuilder sb = new StringBuilder(name);
  533. if (parent != null) {
  534. if (name.length() == 0 && createForEmptyNames) {
  535. sb.append(parent.getNameForUnnamedElement());
  536. }
  537. if (!parent.isGlobal()) {
  538. sb.insert(0, "::"); // NOI18N
  539. sb.insert(0, parent.getQualifiedName());
  540. }
  541. }
  542. return sb.toString();
  543. }
  544. public final NamespaceImpl findNamespaceCreateIfNeeded(NamespaceImpl parent, CharSequence name) {
  545. synchronized (namespaceLock) {
  546. String qualifiedName = ProjectBase.getNestedNamespaceQualifiedName(name, parent, true);
  547. NamespaceImpl nsp = _getNamespace(qualifiedName);
  548. if (nsp == null) {
  549. nsp = NamespaceImpl.create(this, parent, name.toString(), qualifiedName);
  550. }
  551. return nsp;
  552. }
  553. }
  554. public final void registerNamespace(NamespaceImpl namespace) {
  555. _registerNamespace(namespace);
  556. }
  557. public final void unregisterNamesace(NamespaceImpl namespace) {
  558. _unregisterNamespace(namespace);
  559. }
  560. public final CsmClassifier findClassifier(CharSequence qualifiedName, boolean findInLibraries) {
  561. CsmClassifier result = findClassifier(qualifiedName);
  562. if (result == null && findInLibraries) {
  563. for (Iterator<CsmProject> it = getLibraries().iterator(); it.hasNext();) {
  564. CsmProject lib = it.next();
  565. result = lib.findClassifier(qualifiedName);
  566. if (result != null) {
  567. break;
  568. }
  569. }
  570. }
  571. return result;
  572. }
  573. @Override
  574. public final CsmClassifier findClassifier(CharSequence qualifiedName) {
  575. CsmClassifier result = getClassifierSorage().getClassifier(qualifiedName);
  576. return result;
  577. }
  578. @Override
  579. public final Collection<CsmClassifier> findClassifiers(CharSequence qualifiedName) {
  580. CsmClassifier result = getClassifierSorage().getClassifier(qualifiedName);
  581. Collection<CsmClassifier> out = new ArrayList<CsmClassifier>();
  582. //Collection<CsmClassifier> out = new LazyCsmCollection<CsmClassifier, CsmClassifier>(new ArrayList<CsmUID<CsmClassifier>>(), TraceFlags.SAFE_UID_ACCESS);
  583. if (result != null) {
  584. if (CsmKindUtilities.isBuiltIn(result)) {
  585. return Collections.<CsmClassifier>singletonList(result);
  586. }
  587. CharSequence[] allClassifiersUniqueNames = Utils.getAllClassifiersUniqueNames(result.getUniqueName());
  588. Collection<CsmClassifier> fwds = new ArrayList<CsmClassifier>(1);
  589. for (CharSequence curUniqueName : allClassifiersUniqueNames) {
  590. Collection<? extends CsmDeclaration> decls = this.findDeclarations(curUniqueName);
  591. @SuppressWarnings("unchecked")
  592. Collection<CsmClassifier> classifiers = (Collection<CsmClassifier>) decls;
  593. for (CsmClassifier csmClassifier : classifiers) {
  594. if (ForwardClass.isForwardClass(csmClassifier)) {
  595. fwds.add(csmClassifier);
  596. } else {
  597. out.add(csmClassifier);
  598. }
  599. }
  600. }
  601. // All forwards move at the end
  602. out.addAll(fwds);
  603. }
  604. return out;
  605. }
  606. @Override
  607. public final Collection<CsmInheritance> findInheritances(CharSequence name) {
  608. return getClassifierSorage().getInheritances(name);
  609. }
  610. @Override
  611. public final CsmDeclaration findDeclaration(CharSequence uniqueName) {
  612. return getDeclarationsSorage().getDeclaration(uniqueName);
  613. }
  614. @Override
  615. public final Collection<CsmOffsetableDeclaration> findDeclarations(CharSequence uniqueName) {
  616. return getDeclarationsSorage().findDeclarations(uniqueName);
  617. }
  618. public final Collection<CsmOffsetableDeclaration> findDeclarationsByPrefix(String uniquNamePrefix) {
  619. // To improve performance use char(255) instead real Character.MAX_VALUE
  620. char maxChar = 255; //Character.MAX_VALUE;
  621. return getDeclarationsSorage().getDeclarationsRange(uniquNamePrefix, uniquNamePrefix + maxChar); // NOI18N
  622. }
  623. public final Collection<CsmFriend> findFriendDeclarations(CsmOffsetableDeclaration decl) {
  624. return getDeclarationsSorage().findFriends(decl);
  625. }
  626. public final boolean registerDeclaration(CsmOffsetableDeclaration decl) {
  627. if (!Utils.canRegisterDeclaration(decl)) {
  628. if (TraceFlags.TRACE_REGISTRATION) {
  629. traceRegistration("not registered decl " + decl + " UID " + UIDs.get(decl)); //NOI18N
  630. }
  631. return false;
  632. }
  633. if (CsmKindUtilities.isClass(decl) || CsmKindUtilities.isEnum(decl)) {
  634. ClassEnumBase<?> cls = (ClassEnumBase<?>) decl;
  635. CharSequence qname = cls.getQualifiedName();
  636. synchronized (classifierReplaceLock) {
  637. CsmClassifier old = getClassifierSorage().getClassifier(qname);
  638. if (old != null) {
  639. // don't register if the new one is weaker
  640. if (cls.shouldBeReplaced(old)) {
  641. if (TraceFlags.TRACE_REGISTRATION) {
  642. traceRegistration("not registered decl " + decl + " UID " + UIDs.get(decl)); //NOI18N
  643. }
  644. return false;
  645. }
  646. // remove the old one if the new one is stronger
  647. if ((old instanceof ClassEnumBase<?>) && ((ClassEnumBase<?>) old).shouldBeReplaced(cls)) {
  648. if (TraceFlags.TRACE_REGISTRATION) {
  649. System.err.println("disposing old decl " + old + " UID " + UIDs.get(decl)); //NOI18N
  650. }
  651. ((ClassEnumBase<?>) old).dispose();
  652. }
  653. }
  654. getDeclarationsSorage().putDeclaration(decl);
  655. getClassifierSorage().putClassifier((CsmClassifier) decl);
  656. }
  657. } else if (CsmKindUtilities.isTypedef(decl)) { // isClassifier(decl) or isTypedef(decl) ??
  658. getDeclarationsSorage().putDeclaration(decl);
  659. getClassifierSorage().putClassifier((CsmClassifier) decl);
  660. } else {
  661. // only classes, enums and typedefs are registered as classifiers;
  662. // even if you implement CsmClassifier, this doesn't mean you atomatically get there ;)
  663. getDeclarationsSorage().putDeclaration(decl);
  664. }
  665. if (TraceFlags.TRACE_REGISTRATION) {
  666. System.err.println("registered " + decl + " UID " + UIDs.get(decl)); //NOI18N
  667. }
  668. return true;
  669. }
  670. public final void unregisterDeclaration(CsmOffsetableDeclaration decl) {
  671. if (TraceFlags.TRACE_REGISTRATION) {
  672. traceRegistration("unregistered " + decl + " UID " + UIDs.get(decl)); //NOI18N
  673. }
  674. if (decl instanceof CsmClassifier) {
  675. getClassifierSorage().removeClassifier(decl);
  676. }
  677. getDeclarationsSorage().removeDeclaration(decl);
  678. }
  679. private static void traceRegistration(String text) {
  680. assert TraceFlags.TRACE_REGISTRATION : "TraceFlags.TRACE_REGISTRATION should be checked *before* call !"; //NOI18N
  681. System.err.printf("registration: %s\n", text);
  682. }
  683. @Override
  684. public final void waitParse() {
  685. boolean insideParser = ParserThreadManager.instance().isParserThread();
  686. if (insideParser) {
  687. new Throwable("project.waitParse should NEVER be called in parser thread !!!").printStackTrace(System.err); // NOI18N
  688. }
  689. if (insideParser) {
  690. return;
  691. }
  692. ensureFilesCreated();
  693. ensureChangedFilesEnqueued();
  694. model.waitModelTasks();
  695. waitParseImpl();
  696. }
  697. private void waitParseImpl() {
  698. synchronized (waitParseLock) {
  699. while (ParserQueue.instance().hasPendingProjectRelatedWork(this, null)) {
  700. try {
  701. //FIXUP - timeout is a workaround for #146436 hang on running unit tests
  702. waitParseLock.wait(10000);
  703. } catch (InterruptedException ex) {
  704. // do nothing
  705. }
  706. }
  707. }
  708. }
  709. protected void ensureChangedFilesEnqueued() {
  710. }
  711. /**
  712. * @param skipFile if null => check all files, otherwise skip checking
  713. * this file
  714. *
  715. */
  716. protected boolean hasChangedFiles(CsmFile skipFile) {
  717. return false;
  718. }
  719. protected boolean hasEditedFiles() {
  720. return false;
  721. }
  722. private Set<FileSystem> getIncludesFileSystems(NativeProject nativeProject) {
  723. Set<FileSystem> fileSystems = new HashSet<FileSystem>();
  724. for (FSPath fsPath : nativeProject.getSystemIncludePaths()) {
  725. fileSystems.add(fsPath.getFileSystem());
  726. }
  727. return fileSystems;
  728. }
  729. @Override
  730. public void problemOccurred(FSPath fsPath) {
  731. synchronized (fileSystemProblemsLock) {
  732. hasFileSystemProblems = true;
  733. }
  734. }
  735. @Override
  736. public void recovered(FileSystem fileSystem) {
  737. boolean prev;
  738. synchronized (fileSystemProblemsLock) {
  739. prev = hasFileSystemProblems;
  740. hasFileSystemProblems = false;
  741. }
  742. if (prev) {
  743. ModelImpl.instance().scheduleReparse(Collections.<CsmProject>singleton(this));
  744. }
  745. }
  746. public final void enableProjectListeners(boolean enable) {
  747. synchronized (projectListenerLock) {
  748. if (projectListener != null) {
  749. projectListener.enableListening(enable);
  750. }
  751. }
  752. }
  753. protected final void registerProjectListeners() {
  754. synchronized (projectListenerLock) {
  755. if (platformProject instanceof NativeProject) {
  756. if (projectListener == null) {
  757. projectListener = new NativeProjectListenerImpl(getModel(), (NativeProject) platformProject, this);
  758. }
  759. NativeProject nativeProject = (NativeProject) platformProject;
  760. nativeProject.addProjectItemsListener(projectListener);
  761. for (FileSystem fs : getIncludesFileSystems(nativeProject)) {
  762. CndFileSystemProvider.addFileSystemProblemListener(this, fs);
  763. }
  764. }
  765. }
  766. }
  767. protected final void unregisterProjectListeners() {
  768. synchronized (projectListenerLock) {
  769. if (projectListener != null) {
  770. if (platformProject instanceof NativeProject) {
  771. NativeProject nativeProject = (NativeProject) platformProject;
  772. nativeProject.removeProjectItemsListener(projectListener);
  773. for (FileSystem fs : getIncludesFileSystems(nativeProject)) {
  774. CndFileSystemProvider.removeFileSystemProblemListener(this, fs);
  775. }
  776. }
  777. projectListener = null;
  778. }
  779. }
  780. }
  781. /*package*/ final void scheduleReparse() {
  782. ensureFilesCreated();
  783. DeepReparsingUtils.reparseOnEdit(this.getAllFileImpls(), this, true);
  784. }
  785. private final Object fileCreateLock = new Object();
  786. protected void ensureFilesCreated() {
  787. if (status == Status.Ready) {
  788. return;
  789. }
  790. boolean notify = false;
  791. try {
  792. synchronized (fileCreateLock) {
  793. if (status == Status.Initial || status == Status.Restored) {
  794. try {
  795. setStatus((status == Status.Initial) ? Status.AddingFiles : Status.Validating);
  796. long time = 0;
  797. if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
  798. System.err.println("suspend queue");
  799. ParserQueue.instance().suspend();
  800. if (TraceFlags.TIMING) {
  801. time = System.currentTimeMillis();
  802. }
  803. }
  804. ParserQueue.instance().onStartAddingProjectFiles(this);
  805. notify = true;
  806. registerProjectListeners();
  807. NativeProject nativeProject = ModelSupport.getNativeProject(platformProject);
  808. if (nativeProject != null) {
  809. try {
  810. ParserQueue.instance().suspend();
  811. createProjectFilesIfNeed(nativeProject);
  812. } finally {
  813. ParserQueue.instance().resume();
  814. }
  815. }
  816. if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
  817. if (TraceFlags.TIMING) {
  818. time = System.currentTimeMillis() - time;
  819. System.err.println("getting files from project system + put in queue took " + time + "ms");
  820. }
  821. System.err.println("sleep for " + TraceFlags.SUSPEND_PARSE_TIME + "sec before resuming queue");
  822. sleep(TraceFlags.SUSPEND_PARSE_TIME * 1000);
  823. }
  824. } finally {
  825. if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
  826. System.err.println("woke up after sleep");
  827. ParserQueue.instance().resume();
  828. }
  829. setStatus(Status.Ready);
  830. }
  831. }
  832. }
  833. } finally {
  834. if (notify) {
  835. ParserQueue.instance().onEndAddingProjectFiles(this);
  836. }
  837. }
  838. }
  839. private void sleep(int millisec) {
  840. try {
  841. Thread.sleep(millisec);
  842. } catch (InterruptedException ex) {
  843. // do nothing
  844. }
  845. }
  846. private void createProjectFilesIfNeed(NativeProject nativeProject) {
  847. if (TraceFlags.TIMING) {
  848. System.err.printf("\n\nGetting files from project system for %s...\n", getName());
  849. }
  850. if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
  851. try {
  852. System.err.println("sleep for " + TraceFlags.SUSPEND_PARSE_TIME + "sec before getting files from project");
  853. Thread.sleep(TraceFlags.SUSPEND_PARSE_TIME * 1000);
  854. System.err.println("woke up after sleep");
  855. } catch (InterruptedException ex) {
  856. // do nothing
  857. }
  858. }
  859. long time = System.currentTimeMillis();
  860. final Set<NativeFileItem> removedFileItems = Collections.synchronizedSet(new HashSet<NativeFileItem>());
  861. final Set<NativeFileItem> readOnlyRemovedFilesSet = Collections.unmodifiableSet(removedFileItems);
  862. NativeProjectItemsListener projectItemListener = new NativeProjectItemsAdapter() {
  863. @Override
  864. public void filesRemoved(List<NativeFileItem> fileItems) {
  865. removedFileItems.addAll(fileItems);
  866. }
  867. @Override
  868. public void filesPropertiesChanged(List<NativeFileItem> fileItems) {
  869. for (NativeFileItem item : fileItems) {
  870. if (item.isExcluded()) {
  871. removedFileItems.add(item);
  872. }
  873. }
  874. }
  875. };
  876. nativeProject.addProjectItemsListener(projectItemListener);
  877. List<NativeFileItem> sources = new ArrayList<NativeFileItem>();
  878. List<NativeFileItem> headers = new ArrayList<NativeFileItem>();
  879. for (NativeFileItem item : nativeProject.getAllFiles()) {
  880. if (!item.isExcluded()) {
  881. switch (item.getLanguage()) {
  882. case C:
  883. case CPP:
  884. case FORTRAN:
  885. sources.add(item);
  886. break;
  887. case C_HEADER:
  888. headers.add(item);
  889. break;
  890. default:
  891. break;
  892. }
  893. } else {
  894. switch (item.getLanguage()) {
  895. case C:
  896. case CPP:
  897. case FORTRAN:
  898. removedFileItems.add(item);
  899. break;
  900. default:
  901. break;
  902. }
  903. }
  904. }
  905. if (TraceFlags.TIMING) {
  906. time = System.currentTimeMillis() - time;
  907. System.err.printf("Getting files from project system took %d ms for %s\n", time, getName());
  908. System.err.printf("FILES COUNT for %s:\nSource files:\t%d\nHeader files:\t%d\nTotal files:\t%d\n",
  909. getName(), sources.size(), headers.size(), sources.size() + headers.size());
  910. time = System.currentTimeMillis();
  911. }
  912. if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
  913. try {
  914. System.err.println("sleep for " + TraceFlags.SUSPEND_PARSE_TIME + "sec after getting files from project");
  915. Thread.sleep(TraceFlags.SUSPEND_PARSE_TIME * 1000);
  916. System.err.println("woke up after sleep");
  917. } catch (InterruptedException ex) {
  918. // do nothing
  919. }
  920. }
  921. if (TraceFlags.DUMP_PROJECT_ON_OPEN) {
  922. ModelSupport.dumpNativeProject(nativeProject);
  923. }
  924. try {
  925. disposeLock.readLock().lock();
  926. if (TraceFlags.TIMING) {
  927. time = System.currentTimeMillis() - time;
  928. System.err.printf("Waited on disposeLock: %d ms for %s\n", time, getName());
  929. time = System.currentTimeMillis();
  930. }
  931. if (isDisposing()) {
  932. if (TraceFlags.TRACE_MODEL_STATE) {
  933. System.err.printf("filling parser queue interrupted for %s\n", getName());
  934. }
  935. return;
  936. }
  937. ProjectSettingsValidator validator = null;
  938. if (status == Status.Validating) {
  939. validator = new ProjectSettingsValidator(this);
  940. validator.restoreSettings();
  941. }
  942. if (status == Status.Validating && RepositoryUtils.getRepositoryErrorCount(this) > 0){
  943. System.err.println("Clean index for project \""+getUniqueName()+"\" because index was corrupted (was "+RepositoryUtils.getRepositoryErrorCount(this)+" errors)."); // NOI18N
  944. validator = null;
  945. reopenUnit();
  946. }
  947. getProjectRoots().fixFolder(nativeProject.getProjectRoot());
  948. for (String root : nativeProject.getSourceRoots()) {
  949. getProjectRoots().fixFolder(root);
  950. }
  951. getProjectRoots().addSources(sources);
  952. getProjectRoots().addSources(headers);
  953. getProjectRoots().addSources(removedFileItems);
  954. checkConsistency(false);
  955. CreateFilesWorker worker = new CreateFilesWorker(this, readOnlyRemovedFilesSet, validator);
  956. worker.createProjectFilesIfNeed(sources, true);
  957. if (status != Status.Validating || RepositoryUtils.getRepositoryErrorCount(this) == 0){
  958. worker.createProjectFilesIfNeed(headers, false);
  959. }
  960. if (status == Status.Validating && RepositoryUtils.getRepositoryErrorCount(this) > 0){
  961. if (!TraceFlags.DEBUG_BROKEN_REPOSITORY) {
  962. System.err.println("Clean index for project \""+getUniqueName()+"\" because index was corrupted (was "+RepositoryUtils.getRepositoryErrorCount(this)+" errors)."); // NOI18N
  963. }
  964. reopenUnit();
  965. // reset worker to create files without validator
  966. validator = null;
  967. worker = new CreateFilesWorker(this, readOnlyRemovedFilesSet, null);
  968. worker.createProjectFilesIfNeed(sources, true);
  969. worker.createProjectFilesIfNeed(headers, false);
  970. }
  971. worker.checkLibraries();
  972. checkConsistency(validator != null);
  973. worker.finishProjectFilesCreation();
  974. checkConsistency(false);
  975. } finally {
  976. disposeLock.readLock().unlock();
  977. if (TraceFlags.TIMING) {
  978. time = System.currentTimeMillis() - time;
  979. System.err.printf("FILLING PARSER QUEUE took %d ms for %s\n", time, getName());
  980. }
  981. }
  982. nativeProject.removeProjectItemsListener(projectItemListener);
  983. // in fact if visitor used for parsing => visitor will parse all included files
  984. // recursively starting from current source file
  985. // so, when we visit headers, they should not be reparsed if already were parsed
  986. }
  987. private void reopenUnit() {
  988. setStatus(Status.Initial);
  989. ParserQueue.insta