c.s.tools.ide.analysis.modernize/src/com/sun/tools/ide/analysis/modernize/impl/ModernizeAnalyzerImpl.java
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
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]"
27 * If you wish your version of this file to be governed by only the CDDL
28 * or only the GPL Version 2, indicate your decision by adding
29 * "[Contributor] elects to include this software in this distribution
30 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31 * single choice of license, a recipient has the option to distribute
32 * your version of this file under either the CDDL, the GPL Version 2 or
33 * to extend the choice of license to its licensees as provided above.
34 * However, if you add GPL Version 2 code and therefore, elected the GPL
35 * Version 2 license, then the option applies only if the new code is
36 * made subject to such option by the copyright holder.
38 * Contributor(s): Ilia Gromov
40 package com.sun.tools.ide.analysis.modernize.impl;
42 import com.sun.tools.ide.analysis.modernize.options.ClangAnalyzerOptions;
43 import com.sun.tools.ide.analysis.modernize.resources.BundleUtilities;
44 import java.io.CharConversionException;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Collection;
49 import java.util.Collections;
50 import java.util.List;
51 import java.util.concurrent.atomic.AtomicBoolean;
52 import java.util.prefs.Preferences;
53 import org.netbeans.modules.analysis.spi.Analyzer;
54 import org.netbeans.modules.cnd.analysis.api.AbstractAnalyzer;
55 import org.netbeans.modules.cnd.analysis.api.AbstractHintsPanel;
56 import org.netbeans.modules.cnd.api.model.CsmFile;
57 import org.netbeans.modules.cnd.api.model.syntaxerr.CodeAudit;
58 import org.netbeans.modules.cnd.api.model.syntaxerr.CsmErrorInfo;
59 import org.netbeans.modules.cnd.api.model.syntaxerr.CsmErrorProvider;
60 import org.netbeans.modules.cnd.modelutil.CsmUtilities;
61 import org.netbeans.modules.cnd.utils.CndPathUtilities;
62 import org.netbeans.spi.editor.hints.ErrorDescription;
63 import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
64 import org.netbeans.spi.editor.hints.LazyFixList;
65 import org.netbeans.spi.editor.hints.Severity;
66 import org.openide.filesystems.FileObject;
67 import org.openide.util.ImageUtilities;
68 import org.openide.util.NbBundle;
69 import org.openide.util.lookup.ServiceProvider;
70 import org.openide.xml.XMLUtil;
72 public class ModernizeAnalyzerImpl extends AbstractAnalyzer {
74 private static final String PREFIX = "tidy-"; //NOI18N
76 private ModernizeErrorProvider currentErrorProvider;
78 private ModernizeAnalyzerImpl(Context ctx) {
83 public ModernizeErrorProvider getErrorProvider(Preferences preferences) {
84 return ModernizeErrorProvider.getInstance();
88 protected boolean isCompileUnitBased() {
93 protected Collection<ErrorDescription> done() {
94 if (currentErrorProvider != null) {
95 Collection<ErrorDescription> results = currentErrorProvider.done();
96 currentErrorProvider = null;
99 return Collections.<ErrorDescription>emptyList();
103 protected Collection<? extends ErrorDescription> doRunImpl(final FileObject sr, final Context ctx, final CsmErrorProvider provider, final AtomicBoolean cancel) {
104 final CsmFile csmFile = CsmUtilities.getCsmFile(sr, false, false);
105 if (csmFile == null) {
106 return Collections.<ErrorDescription>emptyList();
108 CsmErrorProvider.Request request = new RequestImpl(csmFile, ctx, cancel);
109 final ArrayList<ErrorDescription> res = new ArrayList<>();
110 CsmErrorProvider.Response response = new ModernizeResponse(sr, res, cancel);
111 this.currentErrorProvider = (ModernizeErrorProvider) provider;
112 provider.getErrors(request, response);
116 protected static class ModernizeResponse extends AbstractResponse {
118 public ModernizeResponse(FileObject sr, ArrayList<ErrorDescription> res, AtomicBoolean cancel) {
119 super(sr, res, cancel);
123 public ErrorDescription addErrorImpl(CsmErrorInfo errorInfo, FileObject fo) {
124 String messages[] = errorInfo.getMessage().split("\n"); //NOI18N
125 if (messages.length > 0) {
126 StringBuilder sb = new StringBuilder();
127 if (errorInfo instanceof ModernizeErrorInfo) {
128 ModernizeErrorInfo mei = (ModernizeErrorInfo) errorInfo;
129 sb.append("<pre>"); //NOI18N
130 sb.append("["); //NOI18N
131 sb.append(mei.getId());
132 sb.append("]"); //NOI18N
133 sb.append("\n"); //NOI18N
134 List<YamlParser.Replacement> replacements = mei.getDiagnostics().getReplacements();
135 if (replacements.isEmpty()) {
136 sb.append(CndPathUtilities.getRelativePath(mei.getProject().getProjectRoot(), mei.getDiagnostics().getMessageFilePath())).append(" "); //NOI18N
137 sb.append(mei.getDiagnostics().getMessageFileOffset()).append("\n");
139 for (YamlParser.Replacement replacement : replacements) {
140 sb.append("\n"); //NOI18N
141 sb.append("Replacement: "); //NOI18N
142 sb.append(CndPathUtilities.getRelativePath(mei.getProject().getProjectRoot(), replacement.filePath)).append(" "); //NOI18N
143 sb.append(replacement.offset).append("-").append(replacement.offset + replacement.length).append("\n"); //NOI18N
144 String attributeValue = replacement.replacementText;
146 attributeValue = XMLUtil.toAttributeValue(replacement.replacementText);
147 } catch (CharConversionException ex) {
149 sb.append(attributeValue).append("\n"); //NOI18N
152 sb.append(mei.getMessage());
153 sb.append("</pre>"); //NOI18N
155 LazyFixList list = new LazyFixListImpl();
157 return ErrorDescriptionFactory.createErrorDescription(PREFIX + mei.getId(), Severity.valueOf(mei.getSeverity().toString().toUpperCase()),
158 messages[0], sb.toString(), list, fo, errorInfo.getStartOffset(), errorInfo.getStartOffset());
165 @ServiceProvider(service = AnalyzerFactory.class)
166 public static final class AnalyzerFactoryImpl extends AnalyzerFactory {
168 public AnalyzerFactoryImpl() {
169 super(ModernizeErrorProvider.NAME,
170 NbBundle.getMessage(ModernizeErrorProvider.class, "Modernize_NAME"), //NOI18N
171 ImageUtilities.loadImage("com/sun/tools/ide/analysis/modernize/impl/bugs.png")); //NOI18N
175 public Iterable<? extends WarningDescription> getWarnings() {
176 List<WarningDescription> result = new ArrayList<>();
177 final ModernizeErrorProvider provider = ModernizeErrorProvider.getInstance();
178 for (CodeAudit audit : provider.getAudits()) {
179 result.add(WarningDescription.create(PREFIX + audit.getID(), audit.getName(), ModernizeErrorProvider.NAME, provider.getDisplayName()));
181 String[] fatals = BundleUtilities.getFatalErrors();
182 for (String id : fatals) { //NOI18N
184 result.add(WarningDescription.create(PREFIX + id, BundleUtilities.getDescription(id), ModernizeErrorProvider.NAME, provider.getDisplayName()));
191 public CustomizerProvider<Void, AbstractHintsPanel> getCustomizerProvider() {
192 return new CustomizerProvider<Void, AbstractHintsPanel>() {
195 public Void initialize() {
200 public AbstractHintsPanel createComponent(CustomizerContext<Void, AbstractHintsPanel> context) {
201 return AbstractAnalyzer.createComponent(ModernizeErrorProvider.getInstance());
207 public Collection<? extends MissingPlugin> requiredPlugins(Context context) {
208 // ExecutionEnvironment env = detectEnvironment(context);
209 // if (env == null) {
210 // env = ExecutionEnvironmentFactory.getLocal();
212 String installedTool = ClangAnalyzerOptions.getClangAnalyzerPath();
213 if (installedTool == null || !new File(installedTool).exists()) {
214 String codeBase = ClangAnalyzerOptions.getMissingModuleName();
215 if (codeBase != null) {
216 return Arrays.asList(new MissingPlugin(codeBase, NbBundle.getMessage(ModernizeAnalyzerImpl.class, "Modernize_NAME"))); //NOI18N
219 return Collections.emptyList();
223 public Analyzer createAnalyzer(Context context) {
224 return new ModernizeAnalyzerImpl(context);