c.s.tools.ide.analysis.modernize/src/com/sun/tools/ide/analysis/modernize/impl/ModernizeAnalyzerImpl.java
author Ilia Gromov <ilia@netbeans.org>
Thu, 15 Jun 2017 13:26:38 +0300
branchrelease82
changeset 18425 4b288c339c55
parent 18415 35b6125ef00c
child 18426 76cdf4401581
permissions -rw-r--r--
[clang-tidy] merge analyser errors (only DEV compatible)
(transplanted from 853976f2c6166dbb19b482e2247ec824b7183371)
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright (c) 2017 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  * 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.
    37  *
    38  * Contributor(s): Ilia Gromov
    39  */
    40 package com.sun.tools.ide.analysis.modernize.impl;
    41 
    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;
    45 import java.io.File;
    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;
    71 
    72 public class ModernizeAnalyzerImpl extends AbstractAnalyzer {
    73 
    74     private static final String PREFIX = "tidy-"; //NOI18N
    75 
    76     private ModernizeErrorProvider currentErrorProvider;
    77 
    78     private ModernizeAnalyzerImpl(Context ctx) {
    79         super(ctx);
    80     }
    81 
    82     @Override
    83     public ModernizeErrorProvider getErrorProvider(Preferences preferences) {
    84         return ModernizeErrorProvider.getInstance();
    85     }
    86 
    87     @Override
    88     protected boolean isCompileUnitBased() {
    89         return true;
    90     }
    91 
    92     @Override
    93     protected Collection<ErrorDescription> done() {
    94         if (currentErrorProvider != null) {
    95             Collection<ErrorDescription> results = currentErrorProvider.done();
    96             currentErrorProvider = null;
    97             return results;
    98         }
    99         return Collections.<ErrorDescription>emptyList();
   100     }
   101 
   102     @Override
   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();
   107         }
   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);
   113         return res;
   114     }
   115 
   116     protected static class ModernizeResponse extends AbstractResponse {
   117 
   118         public ModernizeResponse(FileObject sr, ArrayList<ErrorDescription> res, AtomicBoolean cancel) {
   119             super(sr, res, cancel);
   120         }
   121 
   122         @Override
   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");
   138                     } else {
   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;
   145                             try {
   146                                 attributeValue = XMLUtil.toAttributeValue(replacement.replacementText);
   147                             } catch (CharConversionException ex) {
   148                             }
   149                             sb.append(attributeValue).append("\n"); //NOI18N
   150                         }
   151                     }
   152                     sb.append(mei.getMessage());
   153                     sb.append("</pre>"); //NOI18N
   154 
   155                     LazyFixList list = new LazyFixListImpl();
   156 
   157                     return ErrorDescriptionFactory.createErrorDescription(PREFIX + mei.getId(), Severity.valueOf(mei.getSeverity().toString().toUpperCase()),
   158                             messages[0], sb.toString(), list, fo, errorInfo.getStartOffset(), errorInfo.getStartOffset());
   159                 }
   160             }
   161             return null;
   162         }
   163     }
   164 
   165     @ServiceProvider(service = AnalyzerFactory.class)
   166     public static final class AnalyzerFactoryImpl extends AnalyzerFactory {
   167 
   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
   172         }
   173 
   174         @Override
   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()));
   180             }
   181             String[] fatals = BundleUtilities.getFatalErrors();
   182             for (String id : fatals) { //NOI18N
   183                 if (!id.isEmpty()) {
   184                     result.add(WarningDescription.create(PREFIX + id, BundleUtilities.getDescription(id), ModernizeErrorProvider.NAME, provider.getDisplayName()));
   185                 }
   186             }
   187             return result;
   188         }
   189 
   190         @Override
   191         public CustomizerProvider<Void, AbstractHintsPanel> getCustomizerProvider() {
   192             return new CustomizerProvider<Void, AbstractHintsPanel>() {
   193 
   194                 @Override
   195                 public Void initialize() {
   196                     return null;
   197                 }
   198 
   199                 @Override
   200                 public AbstractHintsPanel createComponent(CustomizerContext<Void, AbstractHintsPanel> context) {
   201                     return AbstractAnalyzer.createComponent(ModernizeErrorProvider.getInstance());
   202                 }
   203             };
   204         }
   205 
   206         @Override
   207         public Collection<? extends MissingPlugin> requiredPlugins(Context context) {
   208 //            ExecutionEnvironment env = detectEnvironment(context);
   209 //            if (env == null) {
   210 //                env = ExecutionEnvironmentFactory.getLocal();
   211 //            }
   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
   217                 }
   218             }
   219             return Collections.emptyList();
   220         }
   221 
   222         @Override
   223         public Analyzer createAnalyzer(Context context) {
   224             return new ModernizeAnalyzerImpl(context);
   225         }
   226     }
   227 }