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)
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
}