ilia@18415
|
1 |
/*
|
ilia@18415
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
ilia@18415
|
3 |
*
|
ilia@18415
|
4 |
* Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
|
ilia@18415
|
5 |
*
|
ilia@18415
|
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
|
ilia@18415
|
7 |
* Other names may be trademarks of their respective owners.
|
ilia@18415
|
8 |
*
|
ilia@18415
|
9 |
* The contents of this file are subject to the terms of either the GNU
|
ilia@18415
|
10 |
* General Public License Version 2 only ("GPL") or the Common
|
ilia@18415
|
11 |
* Development and Distribution License("CDDL") (collectively, the
|
ilia@18415
|
12 |
* "License"). You may not use this file except in compliance with the
|
ilia@18415
|
13 |
* License. You can obtain a copy of the License at
|
ilia@18415
|
14 |
* http://www.netbeans.org/cddl-gplv2.html
|
ilia@18415
|
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
ilia@18415
|
16 |
* specific language governing permissions and limitations under the
|
ilia@18415
|
17 |
* License. When distributing the software, include this License Header
|
ilia@18415
|
18 |
* Notice in each file and include the License file at
|
ilia@18415
|
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
|
ilia@18415
|
20 |
* particular file as subject to the "Classpath" exception as provided
|
ilia@18415
|
21 |
* by Oracle in the GPL Version 2 section of the License file that
|
ilia@18415
|
22 |
* accompanied this code. If applicable, add the following below the
|
ilia@18415
|
23 |
* License Header, with the fields enclosed by brackets [] replaced by
|
ilia@18415
|
24 |
* your own identifying information:
|
ilia@18415
|
25 |
* "Portions Copyrighted [year] [name of copyright owner]"
|
ilia@18415
|
26 |
*
|
ilia@18415
|
27 |
* If you wish your version of this file to be governed by only the CDDL
|
ilia@18415
|
28 |
* or only the GPL Version 2, indicate your decision by adding
|
ilia@18415
|
29 |
* "[Contributor] elects to include this software in this distribution
|
ilia@18415
|
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
ilia@18415
|
31 |
* single choice of license, a recipient has the option to distribute
|
ilia@18415
|
32 |
* your version of this file under either the CDDL, the GPL Version 2 or
|
ilia@18415
|
33 |
* to extend the choice of license to its licensees as provided above.
|
ilia@18415
|
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
ilia@18415
|
35 |
* Version 2 license, then the option applies only if the new code is
|
ilia@18415
|
36 |
* made subject to such option by the copyright holder.
|
ilia@18415
|
37 |
*
|
ilia@18415
|
38 |
* Contributor(s): Ilia Gromov
|
ilia@18415
|
39 |
*/
|
ilia@18415
|
40 |
package com.sun.tools.ide.analysis.modernize.impl;
|
ilia@18415
|
41 |
|
ilia@18415
|
42 |
import com.sun.tools.ide.analysis.modernize.options.ClangAnalyzerOptions;
|
ilia@18415
|
43 |
import com.sun.tools.ide.analysis.modernize.resources.BundleUtilities;
|
ilia@18415
|
44 |
import java.io.CharConversionException;
|
ilia@18415
|
45 |
import java.io.File;
|
ilia@18415
|
46 |
import java.util.ArrayList;
|
ilia@18415
|
47 |
import java.util.Arrays;
|
ilia@18415
|
48 |
import java.util.Collection;
|
ilia@18415
|
49 |
import java.util.Collections;
|
ilia@18415
|
50 |
import java.util.List;
|
ilia@18415
|
51 |
import java.util.concurrent.atomic.AtomicBoolean;
|
ilia@18415
|
52 |
import java.util.prefs.Preferences;
|
ilia@18415
|
53 |
import org.netbeans.modules.analysis.spi.Analyzer;
|
ilia@18415
|
54 |
import org.netbeans.modules.cnd.analysis.api.AbstractAnalyzer;
|
ilia@18415
|
55 |
import org.netbeans.modules.cnd.analysis.api.AbstractHintsPanel;
|
ilia@18415
|
56 |
import org.netbeans.modules.cnd.api.model.CsmFile;
|
ilia@18415
|
57 |
import org.netbeans.modules.cnd.api.model.syntaxerr.CodeAudit;
|
ilia@18415
|
58 |
import org.netbeans.modules.cnd.api.model.syntaxerr.CsmErrorInfo;
|
ilia@18415
|
59 |
import org.netbeans.modules.cnd.api.model.syntaxerr.CsmErrorProvider;
|
ilia@18415
|
60 |
import org.netbeans.modules.cnd.modelutil.CsmUtilities;
|
ilia@18415
|
61 |
import org.netbeans.modules.cnd.utils.CndPathUtilities;
|
ilia@18415
|
62 |
import org.netbeans.spi.editor.hints.ErrorDescription;
|
ilia@18415
|
63 |
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
|
ilia@18415
|
64 |
import org.netbeans.spi.editor.hints.LazyFixList;
|
ilia@18415
|
65 |
import org.netbeans.spi.editor.hints.Severity;
|
ilia@18415
|
66 |
import org.openide.filesystems.FileObject;
|
ilia@18415
|
67 |
import org.openide.util.ImageUtilities;
|
ilia@18415
|
68 |
import org.openide.util.NbBundle;
|
ilia@18415
|
69 |
import org.openide.util.lookup.ServiceProvider;
|
ilia@18415
|
70 |
import org.openide.xml.XMLUtil;
|
ilia@18415
|
71 |
|
ilia@18415
|
72 |
public class ModernizeAnalyzerImpl extends AbstractAnalyzer {
|
ilia@18415
|
73 |
|
ilia@18415
|
74 |
private static final String PREFIX = "tidy-"; //NOI18N
|
ilia@18415
|
75 |
|
ilia@18417
|
76 |
private ModernizeErrorProvider currentErrorProvider;
|
ilia@18417
|
77 |
|
ilia@18415
|
78 |
private ModernizeAnalyzerImpl(Context ctx) {
|
ilia@18415
|
79 |
super(ctx);
|
ilia@18415
|
80 |
}
|
ilia@18415
|
81 |
|
ilia@18415
|
82 |
@Override
|
ilia@18415
|
83 |
public ModernizeErrorProvider getErrorProvider(Preferences preferences) {
|
ilia@18415
|
84 |
return ModernizeErrorProvider.getInstance();
|
ilia@18415
|
85 |
}
|
ilia@18415
|
86 |
|
ilia@18417
|
87 |
@Override
|
ilia@18415
|
88 |
protected boolean isCompileUnitBased() {
|
ilia@18415
|
89 |
return true;
|
ilia@18415
|
90 |
}
|
ilia@18415
|
91 |
|
ilia@18415
|
92 |
@Override
|
ilia@18417
|
93 |
protected Collection<ErrorDescription> done() {
|
ilia@18417
|
94 |
if (currentErrorProvider != null) {
|
ilia@18417
|
95 |
Collection<ErrorDescription> results = currentErrorProvider.done();
|
ilia@18417
|
96 |
currentErrorProvider = null;
|
ilia@18417
|
97 |
return results;
|
ilia@18417
|
98 |
}
|
ilia@18417
|
99 |
return Collections.<ErrorDescription>emptyList();
|
ilia@18417
|
100 |
}
|
ilia@18417
|
101 |
|
ilia@18417
|
102 |
@Override
|
ilia@18415
|
103 |
protected Collection<? extends ErrorDescription> doRunImpl(final FileObject sr, final Context ctx, final CsmErrorProvider provider, final AtomicBoolean cancel) {
|
ilia@18415
|
104 |
final CsmFile csmFile = CsmUtilities.getCsmFile(sr, false, false);
|
ilia@18415
|
105 |
if (csmFile == null) {
|
ilia@18415
|
106 |
return Collections.<ErrorDescription>emptyList();
|
ilia@18415
|
107 |
}
|
ilia@18415
|
108 |
CsmErrorProvider.Request request = new RequestImpl(csmFile, ctx, cancel);
|
ilia@18417
|
109 |
final ArrayList<ErrorDescription> res = new ArrayList<>();
|
ilia@18417
|
110 |
CsmErrorProvider.Response response = new ModernizeResponse(sr, res, cancel);
|
ilia@18417
|
111 |
this.currentErrorProvider = (ModernizeErrorProvider) provider;
|
ilia@18415
|
112 |
provider.getErrors(request, response);
|
ilia@18415
|
113 |
return res;
|
ilia@18415
|
114 |
}
|
ilia@18415
|
115 |
|
ilia@18417
|
116 |
protected static class ModernizeResponse extends AbstractResponse {
|
ilia@18415
|
117 |
|
ilia@18417
|
118 |
public ModernizeResponse(FileObject sr, ArrayList<ErrorDescription> res, AtomicBoolean cancel) {
|
ilia@18415
|
119 |
super(sr, res, cancel);
|
ilia@18415
|
120 |
}
|
ilia@18415
|
121 |
|
ilia@18415
|
122 |
@Override
|
ilia@18417
|
123 |
public ErrorDescription addErrorImpl(CsmErrorInfo errorInfo, FileObject fo) {
|
ilia@18415
|
124 |
String messages[] = errorInfo.getMessage().split("\n"); //NOI18N
|
ilia@18415
|
125 |
if (messages.length > 0) {
|
ilia@18415
|
126 |
StringBuilder sb = new StringBuilder();
|
ilia@18415
|
127 |
if (errorInfo instanceof ModernizeErrorInfo) {
|
ilia@18415
|
128 |
ModernizeErrorInfo mei = (ModernizeErrorInfo) errorInfo;
|
ilia@18415
|
129 |
sb.append("<pre>"); //NOI18N
|
ilia@18415
|
130 |
sb.append("["); //NOI18N
|
ilia@18415
|
131 |
sb.append(mei.getId());
|
ilia@18415
|
132 |
sb.append("]"); //NOI18N
|
ilia@18415
|
133 |
sb.append("\n"); //NOI18N
|
ilia@18415
|
134 |
List<YamlParser.Replacement> replacements = mei.getDiagnostics().getReplacements();
|
ilia@18415
|
135 |
if (replacements.isEmpty()) {
|
ilia@18415
|
136 |
sb.append(CndPathUtilities.getRelativePath(mei.getProject().getProjectRoot(), mei.getDiagnostics().getMessageFilePath())).append(" "); //NOI18N
|
ilia@18415
|
137 |
sb.append(mei.getDiagnostics().getMessageFileOffset()).append("\n");
|
ilia@18415
|
138 |
} else {
|
ilia@18415
|
139 |
for (YamlParser.Replacement replacement : replacements) {
|
ilia@18415
|
140 |
sb.append("\n"); //NOI18N
|
ilia@18415
|
141 |
sb.append("Replacement: "); //NOI18N
|
ilia@18415
|
142 |
sb.append(CndPathUtilities.getRelativePath(mei.getProject().getProjectRoot(), replacement.filePath)).append(" "); //NOI18N
|
ilia@18415
|
143 |
sb.append(replacement.offset).append("-").append(replacement.offset + replacement.length).append("\n"); //NOI18N
|
ilia@18415
|
144 |
String attributeValue = replacement.replacementText;
|
ilia@18415
|
145 |
try {
|
ilia@18415
|
146 |
attributeValue = XMLUtil.toAttributeValue(replacement.replacementText);
|
ilia@18415
|
147 |
} catch (CharConversionException ex) {
|
ilia@18415
|
148 |
}
|
ilia@18415
|
149 |
sb.append(attributeValue).append("\n"); //NOI18N
|
ilia@18415
|
150 |
}
|
ilia@18415
|
151 |
}
|
ilia@18415
|
152 |
sb.append(mei.getMessage());
|
ilia@18415
|
153 |
sb.append("</pre>"); //NOI18N
|
ilia@18415
|
154 |
|
ilia@18415
|
155 |
LazyFixList list = new LazyFixListImpl();
|
ilia@18415
|
156 |
|
ilia@18415
|
157 |
return ErrorDescriptionFactory.createErrorDescription(PREFIX + mei.getId(), Severity.valueOf(mei.getSeverity().toString().toUpperCase()),
|
ilia@18415
|
158 |
messages[0], sb.toString(), list, fo, errorInfo.getStartOffset(), errorInfo.getStartOffset());
|
ilia@18415
|
159 |
}
|
ilia@18415
|
160 |
}
|
ilia@18415
|
161 |
return null;
|
ilia@18415
|
162 |
}
|
ilia@18415
|
163 |
}
|
ilia@18415
|
164 |
|
ilia@18415
|
165 |
@ServiceProvider(service = AnalyzerFactory.class)
|
ilia@18415
|
166 |
public static final class AnalyzerFactoryImpl extends AnalyzerFactory {
|
ilia@18415
|
167 |
|
ilia@18415
|
168 |
public AnalyzerFactoryImpl() {
|
ilia@18415
|
169 |
super(ModernizeErrorProvider.NAME,
|
ilia@18415
|
170 |
NbBundle.getMessage(ModernizeErrorProvider.class, "Modernize_NAME"), //NOI18N
|
ilia@18415
|
171 |
ImageUtilities.loadImage("com/sun/tools/ide/analysis/modernize/impl/bugs.png")); //NOI18N
|
ilia@18415
|
172 |
}
|
ilia@18415
|
173 |
|
ilia@18415
|
174 |
@Override
|
ilia@18415
|
175 |
public Iterable<? extends WarningDescription> getWarnings() {
|
ilia@18417
|
176 |
List<WarningDescription> result = new ArrayList<>();
|
ilia@18415
|
177 |
final ModernizeErrorProvider provider = ModernizeErrorProvider.getInstance();
|
ilia@18415
|
178 |
for (CodeAudit audit : provider.getAudits()) {
|
ilia@18415
|
179 |
result.add(WarningDescription.create(PREFIX + audit.getID(), audit.getName(), ModernizeErrorProvider.NAME, provider.getDisplayName()));
|
ilia@18415
|
180 |
}
|
ilia@18415
|
181 |
String[] fatals = BundleUtilities.getFatalErrors();
|
ilia@18415
|
182 |
for (String id : fatals) { //NOI18N
|
ilia@18415
|
183 |
if (!id.isEmpty()) {
|
ilia@18415
|
184 |
result.add(WarningDescription.create(PREFIX + id, BundleUtilities.getDescription(id), ModernizeErrorProvider.NAME, provider.getDisplayName()));
|
ilia@18415
|
185 |
}
|
ilia@18415
|
186 |
}
|
ilia@18415
|
187 |
return result;
|
ilia@18415
|
188 |
}
|
ilia@18415
|
189 |
|
ilia@18415
|
190 |
@Override
|
ilia@18415
|
191 |
public CustomizerProvider<Void, AbstractHintsPanel> getCustomizerProvider() {
|
ilia@18415
|
192 |
return new CustomizerProvider<Void, AbstractHintsPanel>() {
|
ilia@18415
|
193 |
|
ilia@18415
|
194 |
@Override
|
ilia@18415
|
195 |
public Void initialize() {
|
ilia@18415
|
196 |
return null;
|
ilia@18415
|
197 |
}
|
ilia@18415
|
198 |
|
ilia@18415
|
199 |
@Override
|
ilia@18415
|
200 |
public AbstractHintsPanel createComponent(CustomizerContext<Void, AbstractHintsPanel> context) {
|
ilia@18415
|
201 |
return AbstractAnalyzer.createComponent(ModernizeErrorProvider.getInstance());
|
ilia@18415
|
202 |
}
|
ilia@18415
|
203 |
};
|
ilia@18415
|
204 |
}
|
ilia@18415
|
205 |
|
ilia@18415
|
206 |
@Override
|
ilia@18415
|
207 |
public Collection<? extends MissingPlugin> requiredPlugins(Context context) {
|
ilia@18415
|
208 |
// ExecutionEnvironment env = detectEnvironment(context);
|
ilia@18415
|
209 |
// if (env == null) {
|
ilia@18415
|
210 |
// env = ExecutionEnvironmentFactory.getLocal();
|
ilia@18415
|
211 |
// }
|
ilia@18415
|
212 |
String installedTool = ClangAnalyzerOptions.getClangAnalyzerPath();
|
ilia@18415
|
213 |
if (installedTool == null || !new File(installedTool).exists()) {
|
ilia@18415
|
214 |
String codeBase = ClangAnalyzerOptions.getMissingModuleName();
|
ilia@18415
|
215 |
if (codeBase != null) {
|
ilia@18415
|
216 |
return Arrays.asList(new MissingPlugin(codeBase, NbBundle.getMessage(ModernizeAnalyzerImpl.class, "Modernize_NAME"))); //NOI18N
|
ilia@18415
|
217 |
}
|
ilia@18415
|
218 |
}
|
ilia@18415
|
219 |
return Collections.emptyList();
|
ilia@18415
|
220 |
}
|
ilia@18415
|
221 |
|
ilia@18415
|
222 |
@Override
|
ilia@18415
|
223 |
public Analyzer createAnalyzer(Context context) {
|
ilia@18415
|
224 |
return new ModernizeAnalyzerImpl(context);
|
ilia@18415
|
225 |
}
|
ilia@18415
|
226 |
}
|
ilia@18415
|
227 |
}
|