1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "clangsupportivetranslationunitinitializer.h"
27 
28 #include "clangjobs.h"
29 #include "clangtranslationunits.h"
30 
31 #include <utils/qtcassert.h>
32 
33 namespace ClangBackEnd {
34 
SupportiveTranslationUnitInitializer(const Document & document,Jobs & jobs)35 SupportiveTranslationUnitInitializer::SupportiveTranslationUnitInitializer(
36         const Document &document,
37         Jobs &jobs)
38     : m_document(document)
39     , m_jobs(jobs)
40 {
41 }
42 
setIsDocumentClosedChecker(const IsDocumentClosedChecker & isDocumentClosedChecker)43 void SupportiveTranslationUnitInitializer::setIsDocumentClosedChecker(
44         const IsDocumentClosedChecker &isDocumentClosedChecker)
45 {
46     m_isDocumentClosedChecker = isDocumentClosedChecker;
47 }
48 
state() const49 SupportiveTranslationUnitInitializer::State SupportiveTranslationUnitInitializer::state() const
50 {
51     return m_state;
52 }
53 
startInitializing()54 void SupportiveTranslationUnitInitializer::startInitializing()
55 {
56     if (!checkStateAndDocument(State::NotInitialized))
57         return;
58 
59     m_document.translationUnits().createAndAppend();
60 
61     m_jobs.setJobFinishedCallback([this](const Jobs::RunningJob &runningJob, IAsyncJob *) {
62         checkIfParseJobFinished(runningJob);
63         return false;
64     });
65     addJob(JobRequest::Type::ParseSupportiveTranslationUnit);
66     m_jobs.process();
67 
68     m_state = State::WaitingForParseJob;
69 }
70 
abort()71 void SupportiveTranslationUnitInitializer::abort()
72 {
73     if (m_document.translationUnits().size() > 1)
74         m_jobs.setJobFinishedCallback(Jobs::JobFinishedCallback());
75     m_state = State::Aborted;
76 }
77 
checkIfParseJobFinished(const Jobs::RunningJob & job)78 void SupportiveTranslationUnitInitializer::checkIfParseJobFinished(const Jobs::RunningJob &job)
79 {
80     if (!checkStateAndDocument(State::WaitingForParseJob))
81         return;
82 
83     if (job.jobRequest.type == JobRequest::Type::ParseSupportiveTranslationUnit) {
84         if (m_document.translationUnits().areAllTranslationUnitsParsed()) {
85             m_jobs.setJobFinishedCallback(nullptr);
86             m_state = State::Initialized;
87         } else {
88             // The supportive translation unit was parsed, but the document
89             // revision changed in the meanwhile, so try again.
90             addJob(JobRequest::Type::ParseSupportiveTranslationUnit);
91         }
92     }
93 }
94 
checkStateAndDocument(State currentExpectedState)95 bool SupportiveTranslationUnitInitializer::checkStateAndDocument(State currentExpectedState)
96 {
97     if (m_state != currentExpectedState) {
98         m_state = State::Aborted;
99         return false;
100     }
101 
102     QTC_CHECK(m_isDocumentClosedChecker);
103     if (m_isDocumentClosedChecker(m_document.filePath())) {
104         m_state = State::Aborted;
105         return false;
106     }
107 
108     return true;
109 }
110 
addJob(JobRequest::Type jobRequestType)111 void SupportiveTranslationUnitInitializer::addJob(JobRequest::Type jobRequestType)
112 {
113     const JobRequest jobRequest = m_jobs.createJobRequest(
114                 m_document, jobRequestType, PreferredTranslationUnit::LastUninitialized);
115 
116     m_jobs.add(jobRequest);
117 }
118 
setState(const State & state)119 void SupportiveTranslationUnitInitializer::setState(const State &state)
120 {
121     m_state = state;
122 }
123 
124 } // namespace ClangBackEnd
125