Introducing an annotation processor that can run the hints (by default, only custom rules are run).
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/cmdline/ap/build.xml Sat Aug 15 13:14:20 2015 +0200
1.3 @@ -0,0 +1,33 @@
1.4 +<?xml version="1.0" encoding="UTF-8"?>
1.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
1.6 +<!-- for some information on what you could do (e.g. targets to override). -->
1.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
1.8 +<project name="org.netbeans.modules.jackpot30.ap" default="netbeans" basedir=".">
1.9 + <description>Builds, tests, and runs the project org.netbeans.modules.jackpot30.ap.</description>
1.10 + <import file="nbproject/build-impl.xml"/>
1.11 + <property name="bootclasspath.prepend" value="" />
1.12 + <import file="${suite.dir}/../findbugs-import.xml"/>
1.13 +
1.14 + <target name="-check-lib-exists" depends="files-init">
1.15 + <condition property="jackpot.lib.exists" value="true">
1.16 + <available file="${build.dir}/jackpot-ap-lib.jar" />
1.17 + </condition>
1.18 + </target>
1.19 + <target name="build-init" depends="harness.build-init,-check-lib-exists" unless="jackpot.lib.exists">
1.20 + <mkdir dir="${build.dir}/" />
1.21 + <ant dir="../lib" target="test" inheritall="false" inheritrefs="false">
1.22 + <property name="test.config.standalone.includes" value="org/netbeans/modules/jackpot30/cmdline/lib/CreateAPLibJar.class"/>
1.23 + <property name="test.config" value="standalone"/>
1.24 + <property name="test-unit-sys-prop.outputDir" location="${build.dir}/" />
1.25 + </ant>
1.26 + </target>
1.27 + <target name="build-ap-jar" depends="compile">
1.28 + <delete dir="${build.dir}/temp-unpack" failonerror="false"/>
1.29 + <mkdir dir="${build.dir}/temp-unpack" />
1.30 + <unjar src="${build.dir}/jackpot-ap-lib.jar" dest="${build.dir}/temp-unpack" />
1.31 + <copy todir="${build.dir}/temp-unpack">
1.32 + <fileset dir="${build.classes.dir}"/>
1.33 + </copy>
1.34 + <jar destfile="${build.dir}/jackpot-ap.jar" basedir="${build.dir}/temp-unpack" />
1.35 + </target>
1.36 +</project>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/cmdline/ap/manifest.mf Sat Aug 15 13:14:20 2015 +0200
2.3 @@ -0,0 +1,6 @@
2.4 +Manifest-Version: 1.0
2.5 +AutoUpdate-Show-In-Client: true
2.6 +OpenIDE-Module: org.netbeans.modules.jackpot30.ap
2.7 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jackpot30/ap/Bundle.properties
2.8 +OpenIDE-Module-Specification-Version: 1.0
2.9 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/cmdline/ap/nbproject/build-impl.xml Sat Aug 15 13:14:20 2015 +0200
3.3 @@ -0,0 +1,45 @@
3.4 +<?xml version="1.0" encoding="UTF-8"?>
3.5 +<!--
3.6 +*** GENERATED FROM project.xml - DO NOT EDIT ***
3.7 +*** EDIT ../build.xml INSTEAD ***
3.8 +-->
3.9 +<project name="org.netbeans.modules.jackpot30.ap-impl" basedir="..">
3.10 + <fail message="Please build using Ant 1.7.1 or higher.">
3.11 + <condition>
3.12 + <not>
3.13 + <antversion atleast="1.7.1"/>
3.14 + </not>
3.15 + </condition>
3.16 + </fail>
3.17 + <property file="nbproject/private/suite-private.properties"/>
3.18 + <property file="nbproject/suite.properties"/>
3.19 + <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
3.20 + <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
3.21 + <property file="${suite.dir}/nbproject/platform.properties"/>
3.22 + <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
3.23 + <attribute name="name"/>
3.24 + <attribute name="value"/>
3.25 + <sequential>
3.26 + <property name="@{name}" value="${@{value}}"/>
3.27 + </sequential>
3.28 + </macrodef>
3.29 + <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
3.30 + <attribute name="property"/>
3.31 + <attribute name="value"/>
3.32 + <sequential>
3.33 + <property name="@{property}" value="@{value}"/>
3.34 + </sequential>
3.35 + </macrodef>
3.36 + <property file="${user.properties.file}"/>
3.37 + <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
3.38 + <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
3.39 + <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
3.40 + <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
3.41 + <condition>
3.42 + <not>
3.43 + <contains string="${cluster.path.evaluated}" substring="platform"/>
3.44 + </not>
3.45 + </condition>
3.46 + </fail>
3.47 + <import file="${harness.dir}/build.xml"/>
3.48 +</project>
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/cmdline/ap/nbproject/genfiles.properties Sat Aug 15 13:14:20 2015 +0200
4.3 @@ -0,0 +1,8 @@
4.4 +build.xml.data.CRC32=abf35b3d
4.5 +build.xml.script.CRC32=434ef419
4.6 +build.xml.stylesheet.CRC32=a56c6a5b@2.70
4.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
4.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
4.9 +nbproject/build-impl.xml.data.CRC32=abf35b3d
4.10 +nbproject/build-impl.xml.script.CRC32=dd901283
4.11 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/cmdline/ap/nbproject/project.properties Sat Aug 15 13:14:20 2015 +0200
5.3 @@ -0,0 +1,3 @@
5.4 +javac.source=1.7
5.5 +javac.compilerargs=-Xlint -Xlint:-serial
5.6 +cp.extra=build/jackpot-ap-lib.jar:${tools.jar}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/cmdline/ap/nbproject/project.xml Sat Aug 15 13:14:20 2015 +0200
6.3 @@ -0,0 +1,30 @@
6.4 +<?xml version="1.0" encoding="UTF-8"?>
6.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
6.6 + <type>org.netbeans.modules.apisupport.project</type>
6.7 + <configuration>
6.8 + <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
6.9 + <code-name-base>org.netbeans.modules.jackpot30.ap</code-name-base>
6.10 + <suite-component/>
6.11 + <module-dependencies/>
6.12 + <test-dependencies>
6.13 + <test-type>
6.14 + <name>unit</name>
6.15 + <test-dependency>
6.16 + <code-name-base>org.netbeans.libs.junit4</code-name-base>
6.17 + <compile-dependency/>
6.18 + </test-dependency>
6.19 + <test-dependency>
6.20 + <code-name-base>org.netbeans.modules.jackpot30.test.borrowed</code-name-base>
6.21 + <compile-dependency/>
6.22 + </test-dependency>
6.23 + <test-dependency>
6.24 + <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
6.25 + <recursive/>
6.26 + <compile-dependency/>
6.27 + </test-dependency>
6.28 + </test-type>
6.29 + </test-dependencies>
6.30 + <public-packages/>
6.31 + </data>
6.32 + </configuration>
6.33 +</project>
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/cmdline/ap/nbproject/suite.properties Sat Aug 15 13:14:20 2015 +0200
7.3 @@ -0,0 +1,1 @@
7.4 +suite.dir=${basedir}/..
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/cmdline/ap/src/META-INF/services/javax.annotation.processing.Processor Sat Aug 15 13:14:20 2015 +0200
8.3 @@ -0,0 +1,1 @@
8.4 +org.netbeans.modules.jackpot30.ap.ProcessorImpl
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/cmdline/ap/src/org/netbeans/modules/jackpot30/ap/Bundle.properties Sat Aug 15 13:14:20 2015 +0200
9.3 @@ -0,0 +1,1 @@
9.4 +OpenIDE-Module-Name=Jackpot 3.0 Annotation Processing
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/cmdline/ap/src/org/netbeans/modules/jackpot30/ap/ProcessorImpl.java Sat Aug 15 13:14:20 2015 +0200
10.3 @@ -0,0 +1,402 @@
10.4 +/*
10.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
10.6 + *
10.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
10.8 + *
10.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
10.10 + * Other names may be trademarks of their respective owners.
10.11 + *
10.12 + * The contents of this file are subject to the terms of either the GNU
10.13 + * General Public License Version 2 only ("GPL") or the Common
10.14 + * Development and Distribution License("CDDL") (collectively, the
10.15 + * "License"). You may not use this file except in compliance with the
10.16 + * License. You can obtain a copy of the License at
10.17 + * http://www.netbeans.org/cddl-gplv2.html
10.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
10.19 + * specific language governing permissions and limitations under the
10.20 + * License. When distributing the software, include this License Header
10.21 + * Notice in each file and include the License file at
10.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
10.23 + * particular file as subject to the "Classpath" exception as provided
10.24 + * by Oracle in the GPL Version 2 section of the License file that
10.25 + * accompanied this code. If applicable, add the following below the
10.26 + * License Header, with the fields enclosed by brackets [] replaced by
10.27 + * your own identifying information:
10.28 + * "Portions Copyrighted [year] [name of copyright owner]"
10.29 + *
10.30 + * If you wish your version of this file to be governed by only the CDDL
10.31 + * or only the GPL Version 2, indicate your decision by adding
10.32 + * "[Contributor] elects to include this software in this distribution
10.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
10.34 + * single choice of license, a recipient has the option to distribute
10.35 + * your version of this file under either the CDDL, the GPL Version 2 or
10.36 + * to extend the choice of license to its licensees as provided above.
10.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
10.38 + * Version 2 license, then the option applies only if the new code is
10.39 + * made subject to such option by the copyright holder.
10.40 + *
10.41 + * Contributor(s):
10.42 + *
10.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
10.44 + */
10.45 +package org.netbeans.modules.jackpot30.ap;
10.46 +
10.47 +import com.sun.source.tree.CompilationUnitTree;
10.48 +import com.sun.source.tree.Tree;
10.49 +import com.sun.source.util.SourcePositions;
10.50 +import com.sun.source.util.TreePath;
10.51 +import com.sun.source.util.TreePathScanner;
10.52 +import com.sun.source.util.Trees;
10.53 +import java.io.File;
10.54 +import java.io.IOException;
10.55 +import java.lang.reflect.Field;
10.56 +import java.lang.reflect.InvocationTargetException;
10.57 +import java.lang.reflect.Method;
10.58 +import java.net.MalformedURLException;
10.59 +import java.net.URL;
10.60 +import java.util.ArrayList;
10.61 +import java.util.Arrays;
10.62 +import java.util.Collection;
10.63 +import java.util.HashMap;
10.64 +import java.util.List;
10.65 +import java.util.Map;
10.66 +import java.util.Map.Entry;
10.67 +import java.util.Set;
10.68 +import java.util.concurrent.atomic.AtomicBoolean;
10.69 +import java.util.logging.Level;
10.70 +import java.util.logging.Logger;
10.71 +import java.util.prefs.AbstractPreferences;
10.72 +import java.util.prefs.BackingStoreException;
10.73 +import java.util.prefs.Preferences;
10.74 +import javax.annotation.processing.AbstractProcessor;
10.75 +import javax.annotation.processing.RoundEnvironment;
10.76 +import javax.annotation.processing.SupportedAnnotationTypes;
10.77 +import javax.annotation.processing.SupportedOptions;
10.78 +import javax.lang.model.SourceVersion;
10.79 +import javax.lang.model.element.Element;
10.80 +import javax.lang.model.element.ElementKind;
10.81 +import javax.lang.model.element.TypeElement;
10.82 +import javax.tools.Diagnostic.Kind;
10.83 +import javax.tools.JavaFileManager;
10.84 +import javax.tools.StandardJavaFileManager;
10.85 +import javax.tools.StandardLocation;
10.86 +import org.netbeans.api.java.classpath.ClassPath;
10.87 +import org.netbeans.api.java.source.ClasspathInfo;
10.88 +import org.netbeans.api.java.source.CompilationController;
10.89 +import org.netbeans.api.java.source.JavaSource;
10.90 +import org.netbeans.api.java.source.Task;
10.91 +import org.netbeans.modules.editor.tools.storage.api.ToolPreferences;
10.92 +import org.netbeans.modules.jackpot30.cmdline.lib.Utils;
10.93 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
10.94 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
10.95 +import org.netbeans.modules.java.hints.spiimpl.RulesManager;
10.96 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
10.97 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
10.98 +import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
10.99 +import org.netbeans.spi.editor.hints.ErrorDescription;
10.100 +import org.netbeans.spi.editor.hints.Severity;
10.101 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
10.102 +import org.openide.filesystems.FileObject;
10.103 +import org.openide.filesystems.FileUtil;
10.104 +import org.openide.filesystems.URLMapper;
10.105 +import org.openide.util.Lookup;
10.106 +
10.107 +/**
10.108 + *
10.109 + * @author lahvac
10.110 + */
10.111 +@SupportedAnnotationTypes("*")
10.112 +@SupportedOptions("hintsConfiguration")
10.113 +public class ProcessorImpl extends AbstractProcessor {
10.114 +
10.115 + public static final String CONFIGURATION_OPTION = "hintsConfiguration";
10.116 + private final Map<URL, String> sources = new HashMap<>();
10.117 +
10.118 + @Override
10.119 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
10.120 + final Trees trees = Trees.instance(processingEnv);
10.121 +
10.122 + if (!roundEnv.processingOver()) {
10.123 + for (Element root : roundEnv.getRootElements()) {
10.124 + TypeElement outtermost = outtermostType(root);
10.125 + TreePath path = trees.getPath(outtermost);
10.126 +
10.127 + if (path == null) {
10.128 + //TODO: log
10.129 + continue;
10.130 + }
10.131 +
10.132 + try {
10.133 + sources.put(path.getCompilationUnit().getSourceFile().toUri().toURL(), outtermost.getQualifiedName().toString());
10.134 + } catch (MalformedURLException ex) {
10.135 + processingEnv.getMessager().printMessage(Kind.ERROR, "Unexpected exception: " + ex.getMessage());
10.136 + Logger.getLogger(ProcessorImpl.class.getName()).log(Level.SEVERE, null, ex);
10.137 + }
10.138 + }
10.139 + } else {
10.140 + try {
10.141 + Field contextField = processingEnv.getClass().getDeclaredField("context");
10.142 + contextField.setAccessible(true);
10.143 + Object context = contextField.get(processingEnv);
10.144 + Method get = context.getClass().getDeclaredMethod("get", Class.class);
10.145 + JavaFileManager fileManager = (JavaFileManager) get.invoke(context, JavaFileManager.class);
10.146 +
10.147 + if (!(fileManager instanceof StandardJavaFileManager)) {
10.148 + processingEnv.getMessager().printMessage(Kind.ERROR, "The file manager is not a StandardJavaFileManager, cannot run Jackpot 3.0.");
10.149 + return false;
10.150 + }
10.151 +
10.152 + setupCache();
10.153 +
10.154 + StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
10.155 +
10.156 + ClassPath bootCP = toClassPath(sfm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
10.157 + ClassPath compileCP = toClassPath(sfm.getLocation(StandardLocation.CLASS_PATH));
10.158 + Iterable<? extends File> sourcePathLocation = sfm.getLocation(StandardLocation.SOURCE_PATH);
10.159 + ClassPath sourceCP = sourcePathLocation != null ? toClassPath(sourcePathLocation) : inferSourcePath();
10.160 +
10.161 + final Map<FileObject, String> sourceFiles = new HashMap<>();
10.162 +
10.163 + for (Entry<URL, String> e : sources.entrySet()) {
10.164 + FileObject fo = URLMapper.findFileObject(e.getKey());
10.165 + if (fo == null) {
10.166 + //XXX:
10.167 + return false;
10.168 + }
10.169 + sourceFiles.put(fo, e.getValue());
10.170 + }
10.171 +
10.172 + final Map<HintMetadata, ? extends Collection<? extends HintDescription>> allHints = RulesManager.getInstance().readHints(null, Arrays.asList(bootCP, compileCP, sourceCP), new AtomicBoolean());
10.173 + List<HintDescription> hints = new ArrayList<>();
10.174 + for (Collection<? extends HintDescription> v : allHints.values()) {
10.175 + hints.addAll(v);
10.176 + }
10.177 + final Map<String, String> id2DisplayName = Utils.computeId2DisplayName(hints);
10.178 + final Map<HintMetadata, ? extends Collection<? extends HintDescription>> hardcodedHints = RulesManager.getInstance().readHints(null, null, new AtomicBoolean());
10.179 + final HintsSettings settings;
10.180 + String configurationFileLoc = processingEnv.getOptions().get(CONFIGURATION_OPTION);
10.181 + File configurationFile = configurationFileLoc != null ? new File(configurationFileLoc) : null;
10.182 +
10.183 + if (configurationFile == null || !configurationFile.canRead()) {
10.184 + settings = new HintsSettings() {
10.185 +
10.186 + @Override
10.187 + public boolean isEnabled(HintMetadata hm) {
10.188 + return !hardcodedHints.containsKey(hm) ? hm.enabled : false;
10.189 + }
10.190 +
10.191 + @Override
10.192 + public void setEnabled(HintMetadata hm, boolean bln) {
10.193 + throw new UnsupportedOperationException();
10.194 + }
10.195 +
10.196 + @Override
10.197 + public Preferences getHintPreferences(HintMetadata hm) {
10.198 + return new DummyPreferences(null, "");
10.199 + }
10.200 +
10.201 + @Override
10.202 + public Severity getSeverity(HintMetadata hm) {
10.203 + return hm.severity;
10.204 + }
10.205 +
10.206 + @Override
10.207 + public void setSeverity(HintMetadata hm, Severity svrt) {
10.208 + throw new UnsupportedOperationException();
10.209 + }
10.210 + };
10.211 + } else {
10.212 + settings = HintsSettings.createPreferencesBasedHintsSettings(ToolPreferences.from(configurationFile.toURI()).getPreferences("hints", "text/x-java"), true, null);
10.213 + }
10.214 +
10.215 + ClasspathInfo cpInfo = ClasspathInfo.create(bootCP, compileCP, sourceCP);
10.216 +
10.217 + JavaSource.create(cpInfo, sourceFiles.keySet()).runUserActionTask(new Task<CompilationController>() {
10.218 +
10.219 + @Override
10.220 + public void run(CompilationController parameter) throws Exception {
10.221 + if (parameter.toPhase(JavaSource.Phase.RESOLVED).compareTo(JavaSource.Phase.RESOLVED) < 0) {
10.222 + return;
10.223 + }
10.224 +
10.225 + List<ErrorDescription> eds = new HintsInvoker(settings, /*XXX*/new AtomicBoolean()).computeHints(parameter);
10.226 +
10.227 + if (eds != null) {
10.228 + for (ErrorDescription ed : eds) {
10.229 + String outtermost = sourceFiles.get(ed.getFile());
10.230 + TypeElement type = processingEnv.getElementUtils().getTypeElement(outtermost); //XXX: package-info!!!
10.231 + TreePath typePath = trees.getPath(type);
10.232 + TreePath posPath = pathFor(typePath.getCompilationUnit(), trees.getSourcePositions(), ed.getRange().getBegin().getOffset());
10.233 + String category = Utils.categoryName(ed.getId(), id2DisplayName);
10.234 + Kind diagKind;
10.235 + switch (ed.getSeverity()) {
10.236 + case ERROR: diagKind = Kind.ERROR; break;
10.237 + case VERIFIER:
10.238 + case WARNING: diagKind = Kind.WARNING; break;
10.239 + case HINT:
10.240 + default: diagKind = Kind.NOTE; break;
10.241 + }
10.242 + trees.printMessage(diagKind, category + ed.getDescription(), posPath.getLeaf(), posPath.getCompilationUnit());
10.243 + }
10.244 + }
10.245 + }
10.246 + }, true);
10.247 + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | IOException ex) {
10.248 + processingEnv.getMessager().printMessage(Kind.ERROR, "Unexpected exception: " + ex.getMessage());
10.249 + Logger.getLogger(ProcessorImpl.class.getName()).log(Level.SEVERE, null, ex);
10.250 + }
10.251 + }
10.252 +
10.253 + return false;
10.254 + }
10.255 +
10.256 + private static ClassPath toClassPath(Iterable<? extends File> files) throws MalformedURLException {
10.257 + Collection<URL> roots = new ArrayList<>();
10.258 +
10.259 + if (files != null) {
10.260 + for (File f : files) {
10.261 + roots.add(FileUtil.urlForArchiveOrDir(FileUtil.normalizeFile(f)));
10.262 + }
10.263 + }
10.264 +
10.265 + return ClassPathSupport.createClassPath(roots.toArray(new URL[0]));
10.266 + }
10.267 +
10.268 + private void setupCache() throws IOException {
10.269 + File tmp = File.createTempFile("jackpot30", null);
10.270 +
10.271 + tmp.delete();
10.272 + tmp.mkdirs();
10.273 + tmp.deleteOnExit();
10.274 +
10.275 + tmp = FileUtil.normalizeFile(tmp);
10.276 + FileUtil.refreshFor(tmp.getParentFile());
10.277 +
10.278 + org.openide.filesystems.FileObject tmpFO = FileUtil.toFileObject(tmp);
10.279 +
10.280 + if (tmpFO != null) {
10.281 + CacheFolder.setCacheFolder(tmpFO);
10.282 + }
10.283 + }
10.284 +
10.285 + private TypeElement outtermostType(Element el) {
10.286 + while (el.getEnclosingElement().getKind() != ElementKind.PACKAGE) { //XXX: package-info!
10.287 + el = el.getEnclosingElement();
10.288 + }
10.289 + return (TypeElement) el;
10.290 + }
10.291 +
10.292 + private TreePath pathFor(final CompilationUnitTree cut, final SourcePositions sp, final long pos) {
10.293 + class Result extends RuntimeException {
10.294 + final TreePath result;
10.295 + public Result(TreePath result) {
10.296 + this.result = result;
10.297 + }
10.298 + }
10.299 + try {
10.300 + new TreePathScanner<Void, Void>() {
10.301 + @Override
10.302 + public Void scan(Tree tree, Void p) {
10.303 + long s = sp.getStartPosition(cut, tree);
10.304 + long e = sp.getEndPosition(cut, tree);
10.305 + if (s <= pos && pos <= e) {
10.306 + super.scan(tree, p);
10.307 + throw new Result(getCurrentPath());
10.308 + }
10.309 + return null;
10.310 + }
10.311 + }.scan(cut, null);
10.312 + } catch (Result r) {
10.313 + return r.result;
10.314 + }
10.315 + return null;
10.316 + }
10.317 +
10.318 + private ClassPath inferSourcePath() {
10.319 + if (sources.isEmpty())
10.320 + return ClassPath.EMPTY;
10.321 + Entry<URL, String> e = sources.entrySet().iterator().next();
10.322 + FileObject sourceRoot = URLMapper.findFileObject(e.getKey());
10.323 + if (sourceRoot == null) {
10.324 + //unexpected
10.325 + return ClassPath.EMPTY;
10.326 + }
10.327 + for (String part : e.getValue().split("\\.")) {
10.328 + sourceRoot = sourceRoot.getParent();
10.329 + }
10.330 + return ClassPathSupport.createClassPath(sourceRoot);
10.331 + }
10.332 +
10.333 + @Override
10.334 + public SourceVersion getSupportedSourceVersion() {
10.335 + return SourceVersion.latest();
10.336 + }
10.337 +
10.338 + static {
10.339 + ClassLoader origContext = Thread.currentThread().getContextClassLoader();
10.340 + try {
10.341 + Thread.currentThread().setContextClassLoader(ProcessorImpl.class.getClassLoader());
10.342 + Lookup.getDefault();
10.343 + } finally {
10.344 + Thread.currentThread().setContextClassLoader(origContext);
10.345 + }
10.346 + }
10.347 +
10.348 + private static final class DummyPreferences extends AbstractPreferences {
10.349 +
10.350 + private final Map<String, String> values = new HashMap<>();
10.351 + private final Map<String, DummyPreferences> subNodes = new HashMap<>();
10.352 +
10.353 + public DummyPreferences(AbstractPreferences parent, String name) {
10.354 + super(parent, name);
10.355 + }
10.356 +
10.357 + @Override
10.358 + protected void putSpi(String key, String value) {
10.359 + values.put(key, value);
10.360 + }
10.361 +
10.362 + @Override
10.363 + protected String getSpi(String key) {
10.364 + return values.get(key);
10.365 + }
10.366 +
10.367 + @Override
10.368 + protected void removeSpi(String key) {
10.369 + values.remove(key);
10.370 + }
10.371 +
10.372 + @Override
10.373 + protected void removeNodeSpi() throws BackingStoreException {
10.374 + ((DummyPreferences) parent()).subNodes.remove(name());
10.375 + }
10.376 +
10.377 + @Override
10.378 + protected String[] keysSpi() throws BackingStoreException {
10.379 + return values.keySet().toArray(new String[0]);
10.380 + }
10.381 +
10.382 + @Override
10.383 + protected String[] childrenNamesSpi() throws BackingStoreException {
10.384 + return subNodes.keySet().toArray(new String[0]);
10.385 + }
10.386 +
10.387 + @Override
10.388 + protected AbstractPreferences childSpi(String name) {
10.389 + DummyPreferences n = subNodes.get(name);
10.390 + if (n == null) {
10.391 + subNodes.put(name, n = new DummyPreferences(this, name));
10.392 + }
10.393 + return n;
10.394 + }
10.395 +
10.396 + @Override
10.397 + protected void syncSpi() throws BackingStoreException {
10.398 + }
10.399 +
10.400 + @Override
10.401 + protected void flushSpi() throws BackingStoreException {
10.402 + }
10.403 +
10.404 + }
10.405 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/cmdline/ap/test/unit/src/org/netbeans/modules/jackpot30/ap/ProcessorImplTest.java Sat Aug 15 13:14:20 2015 +0200
11.3 @@ -0,0 +1,244 @@
11.4 +/*
11.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
11.6 + *
11.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
11.8 + *
11.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
11.10 + * Other names may be trademarks of their respective owners.
11.11 + *
11.12 + * The contents of this file are subject to the terms of either the GNU
11.13 + * General Public License Version 2 only ("GPL") or the Common
11.14 + * Development and Distribution License("CDDL") (collectively, the
11.15 + * "License"). You may not use this file except in compliance with the
11.16 + * License. You can obtain a copy of the License at
11.17 + * http://www.netbeans.org/cddl-gplv2.html
11.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
11.19 + * specific language governing permissions and limitations under the
11.20 + * License. When distributing the software, include this License Header
11.21 + * Notice in each file and include the License file at
11.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
11.23 + * particular file as subject to the "Classpath" exception as provided
11.24 + * by Oracle in the GPL Version 2 section of the License file that
11.25 + * accompanied this code. If applicable, add the following below the
11.26 + * License Header, with the fields enclosed by brackets [] replaced by
11.27 + * your own identifying information:
11.28 + * "Portions Copyrighted [year] [name of copyright owner]"
11.29 + *
11.30 + * If you wish your version of this file to be governed by only the CDDL
11.31 + * or only the GPL Version 2, indicate your decision by adding
11.32 + * "[Contributor] elects to include this software in this distribution
11.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
11.34 + * single choice of license, a recipient has the option to distribute
11.35 + * your version of this file under either the CDDL, the GPL Version 2 or
11.36 + * to extend the choice of license to its licensees as provided above.
11.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
11.38 + * Version 2 license, then the option applies only if the new code is
11.39 + * made subject to such option by the copyright holder.
11.40 + *
11.41 + * Contributor(s):
11.42 + *
11.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
11.44 + */
11.45 +package org.netbeans.modules.jackpot30.ap;
11.46 +
11.47 +import com.sun.tools.javac.Main;
11.48 +import java.io.ByteArrayOutputStream;
11.49 +import java.io.File;
11.50 +import java.io.PrintStream;
11.51 +import java.util.ArrayList;
11.52 +import java.util.Arrays;
11.53 +import java.util.Collections;
11.54 +import java.util.LinkedList;
11.55 +import java.util.List;
11.56 +import java.util.regex.Matcher;
11.57 +import java.util.regex.Pattern;
11.58 +import static junit.framework.TestCase.assertEquals;
11.59 +import static junit.framework.TestCase.assertTrue;
11.60 +import org.netbeans.api.java.source.TestUtilities;
11.61 +import org.netbeans.junit.NbTestCase;
11.62 +
11.63 +/**
11.64 + *
11.65 + * @author lahvac
11.66 + */
11.67 +public class ProcessorImplTest extends NbTestCase {
11.68 +
11.69 + public ProcessorImplTest(String name) {
11.70 + super(name);
11.71 + }
11.72 +
11.73 + public void testHardcoded1() throws Exception {
11.74 + doRunCompiler("",
11.75 + "",
11.76 + "src/test/Test.java",
11.77 + "package test;\n" +
11.78 + "public class Test {\n" +
11.79 + " private void test(java.util.Collection c) {\n" +
11.80 + " boolean b1 = c.size() == 0;\n" +
11.81 + "\tboolean b2 = c.size() == 0;\n" +
11.82 + " }\n" +
11.83 + "}\n",
11.84 + null,
11.85 + "-source",
11.86 + "7",
11.87 + "-Xlint:-options");
11.88 + }
11.89 +
11.90 + public void testHardcodedWithConfiguration() throws Exception {
11.91 + doRunCompiler("",
11.92 + "${workdir}/src/test/Test.java:4: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
11.93 + " boolean b1 = c.size() == 0;\n" +
11.94 + " ^\n" +
11.95 + "${workdir}/src/test/Test.java:5: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
11.96 + "\tboolean b2 = c.size() == 0;\n" +
11.97 + "\t ^\n" +
11.98 + "2 warnings\n",
11.99 + "src/test/Test.java",
11.100 + "package test;\n" +
11.101 + "public class Test {\n" +
11.102 + " private void test(java.util.Collection c) {\n" +
11.103 + " boolean b1 = c.size() == 0;\n" +
11.104 + "\tboolean b2 = c.size() == 0;\n" +
11.105 + " }\n" +
11.106 + "}\n",
11.107 + "cfg_hints.xml",
11.108 + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
11.109 + "<!DOCTYPE configuration PUBLIC \"-//NetBeans//DTD Tool Configuration 1.0//EN\" \"http://www.netbeans.org/dtds/ToolConfiguration-1_0.dtd\">\n" +
11.110 + "<configuration>\n" +
11.111 + " <tool kind=\"hints\" type=\"text/x-java\">\n" +
11.112 + " </tool>\n" +
11.113 + "</configuration>\n",
11.114 + null,
11.115 + "-source",
11.116 + "7",
11.117 + "-Xlint:-options",
11.118 + "-A" + ProcessorImpl.CONFIGURATION_OPTION + "=" + new File(getWorkDir(), "cfg_hints.xml").getAbsolutePath());
11.119 + }
11.120 +
11.121 + public void testCustomWithSourcePath() throws Exception {
11.122 + doRunCompiler("",
11.123 + "${workdir}/src/test/Test.java:4: warning: [test] test\n" +
11.124 + " boolean b1 = c.size() == 0;\n" +
11.125 + " ^\n" +
11.126 + "${workdir}/src/test/Test.java:5: warning: [test] test\n" +
11.127 + "\tboolean b2 = c.size() == 0;\n" +
11.128 + "\t ^\n" +
11.129 + "2 warnings\n",
11.130 + "src/test/Test.java",
11.131 + "package test;\n" +
11.132 + "public class Test {\n" +
11.133 + " private void test(java.util.Collection c) {\n" +
11.134 + " boolean b1 = c.size() == 0;\n" +
11.135 + "\tboolean b2 = c.size() == 0;\n" +
11.136 + " }\n" +
11.137 + "}\n",
11.138 + "src/META-INF/upgrade/test.hint",
11.139 + "$coll.size() == 0 :: $coll instanceof java.util.Collection;;\n",
11.140 + null,
11.141 + "-source",
11.142 + "7",
11.143 + "-Xlint:-options",
11.144 + "-sourcepath",
11.145 + new File(getWorkDir(), "src").getAbsolutePath());
11.146 + }
11.147 +
11.148 + public void testCustomWithOutSourcePath() throws Exception {
11.149 + doRunCompiler("",
11.150 + "${workdir}/src/test/Test.java:4: warning: [test] test\n" +
11.151 + " boolean b1 = c.size() == 0;\n" +
11.152 + " ^\n" +
11.153 + "${workdir}/src/test/Test.java:5: warning: [test] test\n" +
11.154 + "\tboolean b2 = c.size() == 0;\n" +
11.155 + "\t ^\n" +
11.156 + "2 warnings\n",
11.157 + "src/test/Test.java",
11.158 + "package test;\n" +
11.159 + "public class Test {\n" +
11.160 + " private void test(java.util.Collection c) {\n" +
11.161 + " boolean b1 = c.size() == 0;\n" +
11.162 + "\tboolean b2 = c.size() == 0;\n" +
11.163 + " }\n" +
11.164 + "}\n",
11.165 + "src/META-INF/upgrade/test.hint",
11.166 + "$coll.size() == 0 :: $coll instanceof java.util.Collection;;\n",
11.167 + null,
11.168 + "-source",
11.169 + "7",
11.170 + "-Xlint:-options");
11.171 + }
11.172 +
11.173 + private void doRunCompiler(String stdOut, String stdErr, String... fileContentAndExtraOptions) throws Exception {
11.174 + List<String> fileAndContent = new LinkedList<String>();
11.175 + List<String> extraOptions = new LinkedList<String>();
11.176 + List<String> fileContentAndExtraOptionsList = Arrays.asList(fileContentAndExtraOptions);
11.177 + int nullPos = fileContentAndExtraOptionsList.indexOf(null);
11.178 +
11.179 + if (nullPos == (-1)) {
11.180 + fileAndContent = fileContentAndExtraOptionsList;
11.181 + extraOptions = Collections.emptyList();
11.182 + } else {
11.183 + fileAndContent = fileContentAndExtraOptionsList.subList(0, nullPos);
11.184 + extraOptions = fileContentAndExtraOptionsList.subList(nullPos + 1, fileContentAndExtraOptionsList.size());
11.185 + }
11.186 +
11.187 + assertTrue(fileAndContent.size() % 2 == 0);
11.188 +
11.189 + clearWorkDir();
11.190 +
11.191 + List<String> params = new ArrayList<>();
11.192 +
11.193 + for (int cntr = 0; cntr < fileAndContent.size(); cntr += 2) {
11.194 + File target = new File(getWorkDir(), fileAndContent.get(cntr));
11.195 +
11.196 + target.getParentFile().mkdirs();
11.197 +
11.198 + TestUtilities.copyStringToFile(target, fileAndContent.get(cntr + 1));
11.199 +
11.200 + if (target.getName().endsWith(".java"))
11.201 + params.add(target.getAbsolutePath());
11.202 + }
11.203 +
11.204 + params.addAll(extraOptions);
11.205 +
11.206 + File wd = getWorkDir();
11.207 + String[] output = new String[2];
11.208 + reallyRunCompiler(wd, output, params.toArray(new String[0]));
11.209 +
11.210 + if (stdOut != null) {
11.211 + assertEquals(stdOut, output[0].replaceAll(Pattern.quote(wd.getAbsolutePath()), Matcher.quoteReplacement("${workdir}")));
11.212 + }
11.213 +
11.214 + if (stdErr != null) {
11.215 + assertEquals(stdErr, output[1].replaceAll(Pattern.quote(wd.getAbsolutePath()), Matcher.quoteReplacement("${workdir}")));
11.216 + }
11.217 + }
11.218 +
11.219 + protected void reallyRunCompiler(File workDir, String[] output, String... params) throws Exception {
11.220 + String oldUserDir = System.getProperty("user.dir");
11.221 +
11.222 + System.setProperty("user.dir", workDir.getAbsolutePath());
11.223 +
11.224 + PrintStream oldOut = System.out;
11.225 + ByteArrayOutputStream outData = new ByteArrayOutputStream();
11.226 + System.setOut(new PrintStream(outData, true, "UTF-8"));
11.227 +
11.228 + PrintStream oldErr = System.err;
11.229 + ByteArrayOutputStream errData = new ByteArrayOutputStream();
11.230 + System.setErr(new PrintStream(errData, true, "UTF-8"));
11.231 +
11.232 + try {
11.233 + assertEquals(0, Main.compile(params));
11.234 + } finally {
11.235 + System.setProperty("user.dir", oldUserDir);
11.236 + System.out.close();
11.237 + output[0] = new String(outData.toByteArray(), "UTF-8");
11.238 + System.setOut(oldOut);
11.239 + System.err.close();
11.240 + output[1] = new String(errData.toByteArray(), "UTF-8");
11.241 + System.setErr(oldErr);
11.242 +
11.243 + System.err.println("stdout: " + output[0]);
11.244 + System.err.println("stderr: " + output[1]);
11.245 + }
11.246 + }
11.247 +}
12.1 --- a/cmdline/build.sh Sat Aug 15 08:14:07 2015 +0200
12.2 +++ b/cmdline/build.sh Sat Aug 15 13:14:20 2015 +0200
12.3 @@ -1,5 +1,5 @@
12.4 #!/bin/bash -x
12.5 -ant "$@" clean && ant "$@" build && ant "$@" test && (cd compiler; ant "$@" create-standalone-compiler && build/test/scripted/run ) && (cd tool; ant "$@" create-standalone-tool && build/test/scripted/run ) && (cd lib; ant "$@" create-cmdline-lib ) || exit 1
12.6 +ant "$@" clean && ant "$@" build && ant "$@" test && (cd compiler; ant "$@" create-standalone-compiler && build/test/scripted/run ) && (cd tool; ant "$@" create-standalone-tool && build/test/scripted/run ) && (cd lib; ant "$@" create-cmdline-lib ) && (cd ap; ant "$@" build-ap-jar ) || exit 1
12.7 mvn $MAVEN_EXTRA_ARGS install:install-file -Dfile=tool/build/jackpot/jackpot.jar -DgroupId=org.netbeans.modules.jackpot30 -DartifactId=tool -Dversion=7.3-SNAPSHOT -Dpackaging=jar -DgeneratePom=true
12.8 (cd maven; mvn $MAVEN_EXTRA_ARGS install -DskipTests; mvn $MAVEN_EXTRA_ARGS -Dmaven.executable=`which mvn` test)
12.9 MAVEN_REPO=`pwd`/build/.m2
13.1 --- a/cmdline/lib/nbproject/project.properties Sat Aug 15 08:14:07 2015 +0200
13.2 +++ b/cmdline/lib/nbproject/project.properties Sat Aug 15 13:14:20 2015 +0200
13.3 @@ -1,5 +1,5 @@
13.4 is.autoload=true
13.5 -javac.source=1.6
13.6 +javac.source=1.7
13.7 javac.compilerargs=-Xlint -Xlint:-serial
13.8 requires.nb.javac=true
13.9 spec.version.base=1.16.0
14.1 --- a/cmdline/lib/nbproject/project.xml Sat Aug 15 08:14:07 2015 +0200
14.2 +++ b/cmdline/lib/nbproject/project.xml Sat Aug 15 13:14:20 2015 +0200
14.3 @@ -68,6 +68,14 @@
14.4 </run-dependency>
14.5 </dependency>
14.6 <dependency>
14.7 + <code-name-base>org.netbeans.modules.editor.tools.storage</code-name-base>
14.8 + <build-prerequisite/>
14.9 + <compile-dependency/>
14.10 + <run-dependency>
14.11 + <specification-version>1.6</specification-version>
14.12 + </run-dependency>
14.13 + </dependency>
14.14 + <dependency>
14.15 <code-name-base>org.netbeans.modules.jackpot30.remoting.api</code-name-base>
14.16 <build-prerequisite/>
14.17 <compile-dependency/>
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/cmdline/lib/src/org/netbeans/modules/jackpot30/cmdline/lib/Utils.java Sat Aug 15 13:14:20 2015 +0200
15.3 @@ -0,0 +1,94 @@
15.4 +/*
15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
15.6 + *
15.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
15.8 + *
15.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
15.10 + * Other names may be trademarks of their respective owners.
15.11 + *
15.12 + * The contents of this file are subject to the terms of either the GNU
15.13 + * General Public License Version 2 only ("GPL") or the Common
15.14 + * Development and Distribution License("CDDL") (collectively, the
15.15 + * "License"). You may not use this file except in compliance with the
15.16 + * License. You can obtain a copy of the License at
15.17 + * http://www.netbeans.org/cddl-gplv2.html
15.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15.19 + * specific language governing permissions and limitations under the
15.20 + * License. When distributing the software, include this License Header
15.21 + * Notice in each file and include the License file at
15.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
15.23 + * particular file as subject to the "Classpath" exception as provided
15.24 + * by Oracle in the GPL Version 2 section of the License file that
15.25 + * accompanied this code. If applicable, add the following below the
15.26 + * License Header, with the fields enclosed by brackets [] replaced by
15.27 + * your own identifying information:
15.28 + * "Portions Copyrighted [year] [name of copyright owner]"
15.29 + *
15.30 + * If you wish your version of this file to be governed by only the CDDL
15.31 + * or only the GPL Version 2, indicate your decision by adding
15.32 + * "[Contributor] elects to include this software in this distribution
15.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
15.34 + * single choice of license, a recipient has the option to distribute
15.35 + * your version of this file under either the CDDL, the GPL Version 2 or
15.36 + * to extend the choice of license to its licensees as provided above.
15.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
15.38 + * Version 2 license, then the option applies only if the new code is
15.39 + * made subject to such option by the copyright holder.
15.40 + *
15.41 + * Contributor(s):
15.42 + *
15.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
15.44 + */
15.45 +package org.netbeans.modules.jackpot30.cmdline.lib;
15.46 +
15.47 +import java.util.HashMap;
15.48 +import java.util.Map;
15.49 +import java.util.Map.Entry;
15.50 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
15.51 +
15.52 +/**
15.53 + *
15.54 + * @author lahvac
15.55 + */
15.56 +public class Utils {
15.57 +
15.58 + public static Map<String, String> computeId2DisplayName(Iterable<? extends HintDescription> descs) {
15.59 + final Map<String, String> id2DisplayName = new HashMap<>();
15.60 +
15.61 + for (HintDescription hd : descs) {
15.62 + if (hd.getMetadata() != null) {
15.63 + id2DisplayName.put(hd.getMetadata().id, hd.getMetadata().displayName);
15.64 + }
15.65 + }
15.66 +
15.67 + return id2DisplayName;
15.68 + }
15.69 +
15.70 + public static String categoryName(String id, Map<String, String> id2DisplayName) {
15.71 + if (id != null && id.startsWith("text/x-java:")) {
15.72 + id = id.substring("text/x-java:".length());
15.73 + }
15.74 +
15.75 + String idDisplayName = id2DisplayName.get(id);
15.76 +
15.77 + if (idDisplayName == null) {
15.78 + idDisplayName = "unknown";
15.79 + }
15.80 +
15.81 + for (Entry<String, String> remap : toIdRemap.entrySet()) {
15.82 + idDisplayName = idDisplayName.replace(remap.getKey(), remap.getValue());
15.83 + }
15.84 +
15.85 + idDisplayName = idDisplayName.replaceAll("[^A-Za-z0-9]", "_").replaceAll("_+", "_");
15.86 +
15.87 + idDisplayName = "[" + idDisplayName + "] ";
15.88 +
15.89 + return idDisplayName;
15.90 + }
15.91 +
15.92 + private static final Map<String, String> toIdRemap = new HashMap<String, String>() {{
15.93 + put("==", "equals");
15.94 + put("!=", "not_equals");
15.95 + }};
15.96 +
15.97 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/cmdline/lib/test/unit/src/org/netbeans/modules/jackpot30/cmdline/lib/CreateAPLibJar.java Sat Aug 15 13:14:20 2015 +0200
16.3 @@ -0,0 +1,62 @@
16.4 +/*
16.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
16.6 + *
16.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
16.8 + *
16.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
16.10 + * Other names may be trademarks of their respective owners.
16.11 + *
16.12 + * The contents of this file are subject to the terms of either the GNU
16.13 + * General Public License Version 2 only ("GPL") or the Common
16.14 + * Development and Distribution License("CDDL") (collectively, the
16.15 + * "License"). You may not use this file except in compliance with the
16.16 + * License. You can obtain a copy of the License at
16.17 + * http://www.netbeans.org/cddl-gplv2.html
16.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16.19 + * specific language governing permissions and limitations under the
16.20 + * License. When distributing the software, include this License Header
16.21 + * Notice in each file and include the License file at
16.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
16.23 + * particular file as subject to the "Classpath" exception as provided
16.24 + * by Oracle in the GPL Version 2 section of the License file that
16.25 + * accompanied this code. If applicable, add the following below the
16.26 + * License Header, with the fields enclosed by brackets [] replaced by
16.27 + * your own identifying information:
16.28 + * "Portions Copyrighted [year] [name of copyright owner]"
16.29 + *
16.30 + * If you wish your version of this file to be governed by only the CDDL
16.31 + * or only the GPL Version 2, indicate your decision by adding
16.32 + * "[Contributor] elects to include this software in this distribution
16.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
16.34 + * single choice of license, a recipient has the option to distribute
16.35 + * your version of this file under either the CDDL, the GPL Version 2 or
16.36 + * to extend the choice of license to its licensees as provided above.
16.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
16.38 + * Version 2 license, then the option applies only if the new code is
16.39 + * made subject to such option by the copyright holder.
16.40 + *
16.41 + * Contributor(s):
16.42 + *
16.43 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
16.44 + */
16.45 +
16.46 +package org.netbeans.modules.jackpot30.cmdline.lib;
16.47 +
16.48 +import org.netbeans.modules.editor.tools.storage.api.ToolPreferences;
16.49 +
16.50 +/**
16.51 + *
16.52 + * @author lahvac
16.53 + */
16.54 +public class CreateAPLibJar extends CreateStandaloneLibJarNoEscape {
16.55 +
16.56 + public CreateAPLibJar(String name) {
16.57 + super(name, "jackpot-ap-lib");
16.58 + }
16.59 +
16.60 + @Override
16.61 + protected Info computeInfo() {
16.62 + return super.computeInfo().addAdditionalRoots(ToolPreferences.class.getName()).setEscapeJavaxLang();
16.63 + }
16.64 +
16.65 +}
17.1 --- a/cmdline/lib/test/unit/src/org/netbeans/modules/jackpot30/cmdline/lib/CreateStandaloneJar.java Sat Aug 15 08:14:07 2015 +0200
17.2 +++ b/cmdline/lib/test/unit/src/org/netbeans/modules/jackpot30/cmdline/lib/CreateStandaloneJar.java Sat Aug 15 13:14:20 2015 +0200
17.3 @@ -63,7 +63,9 @@
17.4 import java.util.Map;
17.5 import java.util.Map.Entry;
17.6 import java.util.Set;
17.7 +import java.util.TreeMap;
17.8 import java.util.jar.JarOutputStream;
17.9 +import java.util.jar.Manifest;
17.10 import java.util.regex.Pattern;
17.11 import java.util.zip.ZipEntry;
17.12 import org.apache.lucene.analysis.tokenattributes.OffsetAttributeImpl;
17.13 @@ -141,7 +143,7 @@
17.14 protected abstract Info computeInfo();
17.15
17.16 public void createCompiler(File targetCompilerFile, File targetHintsFile) throws Exception {
17.17 - JarOutputStream out = new JarOutputStream(new FileOutputStream(targetCompilerFile));
17.18 + Map<String, byte[]> out = new TreeMap<>();
17.19 List<String> toProcess = new LinkedList<String>(INCLUDE);
17.20
17.21 for (FSWrapper.ClassWrapper cw : FSWrapper.listClasses()) {
17.22 @@ -212,21 +214,23 @@
17.23 toProcess.add(classFromCP.getInternalName().replace('/', '.'));
17.24 }
17.25
17.26 - out.putNextEntry(new ZipEntry(escapeJavaxLang(info, fileName)));
17.27 - out.write(escapeJavaxLang(info, bytes));
17.28 + out.put(escapeJavaxLang(info, fileName), escapeJavaxLang(info, bytes));
17.29
17.30 if (COPY_REGISTRATION.contains(fqn) || info.copyMetaInfRegistration.contains(fqn)) {
17.31 String serviceName = "META-INF/services/" + fqn;
17.32 Enumeration<URL> resources = this.getClass().getClassLoader().getResources(serviceName);
17.33
17.34 if (resources.hasMoreElements()) {
17.35 - out.putNextEntry(new ZipEntry(escapeJavaxLang(info, serviceName)));
17.36 + try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
17.37 + while (resources.hasMoreElements()) {
17.38 + URL res = resources.nextElement();
17.39
17.40 - while (resources.hasMoreElements()) {
17.41 - URL res = resources.nextElement();
17.42 + buffer.write(readFile(res));
17.43 + }
17.44
17.45 - out.write(readFile(res));
17.46 + out.put(escapeJavaxLang(info, serviceName), buffer.toByteArray());
17.47 }
17.48 +
17.49 }
17.50 }
17.51
17.52 @@ -275,8 +279,10 @@
17.53 }
17.54 }
17.55
17.56 - out.putNextEntry(new ZipEntry(escapeJavaxLang(info, "META-INF/generated-layer.xml")));
17.57 - XMLUtil.write(main, out, "UTF-8");
17.58 + ByteArrayOutputStream bytes = new ByteArrayOutputStream();
17.59 + XMLUtil.write(main, bytes, "UTF-8");
17.60 + bytes.close();
17.61 + out.put(escapeJavaxLang(info, "META-INF/generated-layer.xml"), escapeJavaxLang(info, bytes.toByteArray()));
17.62
17.63 List<MetaInfRegistration> registrations = new ArrayList<MetaInfRegistration>();
17.64
17.65 @@ -310,7 +316,21 @@
17.66 addMETA_INFRegistration(out, info, e.getValue());
17.67 }
17.68
17.69 - out.close();
17.70 + try (JarOutputStream outStream = new JarOutputStream(new FileOutputStream(targetCompilerFile))) {
17.71 + Set<String> seenDirs = new HashSet<>();
17.72 + for (Entry<String, byte[]> e : out.entrySet()) {
17.73 + String[] parts = e.getKey().split("/");
17.74 + StringBuilder dir = new StringBuilder();
17.75 + for (int i = 0; i < parts.length - 1; i++) {
17.76 + dir.append(parts[i]);
17.77 + dir.append("/");
17.78 + if (seenDirs.add(dir.toString()))
17.79 + outStream.putNextEntry(new ZipEntry(dir.toString()));
17.80 + }
17.81 + outStream.putNextEntry(new ZipEntry(e.getKey()));
17.82 + outStream.write(e.getValue());
17.83 + }
17.84 + }
17.85
17.86 Writer hints = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetHintsFile), "UTF-8"));
17.87
17.88 @@ -379,7 +399,7 @@
17.89
17.90 }
17.91
17.92 - private void copyResources(JarOutputStream out, Info info, Set<String> res) throws IOException {
17.93 + private void copyResources(Map<String, byte[]> out, Info info, Set<String> res) throws IOException {
17.94 for (String resource : res) {
17.95 URL url = this.getClass().getClassLoader().getResource(resource);
17.96
17.97 @@ -387,8 +407,7 @@
17.98 continue;
17.99 }
17.100
17.101 - out.putNextEntry(new ZipEntry(escapeJavaxLang(info, resource)));
17.102 - out.write(readFile(url));
17.103 + out.put(escapeJavaxLang(info, resource), readFile(url));
17.104 }
17.105 }
17.106
17.107 @@ -410,25 +429,35 @@
17.108 return data.toByteArray();
17.109 }
17.110
17.111 - private static void addMETA_INFRegistration(JarOutputStream out, Info info, Iterable<MetaInfRegistration> registrations) throws IOException {
17.112 + private static void addMETA_INFRegistration(Map<String, byte[]> out, Info info, Iterable<MetaInfRegistration> registrations) throws IOException {
17.113 String apiClassName = registrations.iterator().next().apiClassName;
17.114 - out.putNextEntry(new ZipEntry(escapeJavaxLang(info, "META-INF/services/" + apiClassName)));
17.115
17.116 - for (MetaInfRegistration r : registrations) {
17.117 - assert apiClassName.equals(r.apiClassName);
17.118 - out.write(r.implClassName.getBytes("UTF-8"));
17.119 - out.write("\n".getBytes("UTF-8"));
17.120 - if (r.pos != null) {
17.121 - out.write(("#position=" + r.pos.toString() + "\n").getBytes("UTF-8"));
17.122 + try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
17.123 + for (MetaInfRegistration r : registrations) {
17.124 + assert apiClassName.equals(r.apiClassName);
17.125 + buffer.write(r.implClassName.getBytes("UTF-8"));
17.126 + buffer.write("\n".getBytes("UTF-8"));
17.127 + if (r.pos != null) {
17.128 + buffer.write(("#position=" + r.pos.toString() + "\n").getBytes("UTF-8"));
17.129 + }
17.130 }
17.131 +
17.132 + out.put(escapeJavaxLang(info, "META-INF/services/" + apiClassName), buffer.toByteArray());
17.133 }
17.134 }
17.135
17.136 private static final Map<String, String> replaceWhat2With = new LinkedHashMap<String, String>();
17.137
17.138 static {
17.139 + replaceWhat2With.put("javax/annotation/processing/", "jpt30/annotation/processing/");
17.140 replaceWhat2With.put("javax/lang/", "jpt30/lang/");
17.141 replaceWhat2With.put("javax/tools/", "jpt30/tools/");
17.142 + replaceWhat2With.put("com/sun/tools/", "jpt/sun/tools/");
17.143 + replaceWhat2With.put("com/sun/source/", "jpt/sun/source/");
17.144 +
17.145 + for (String originalKey : new HashSet<>(replaceWhat2With.keySet())) {
17.146 + replaceWhat2With.put(originalKey.replace('/', '.'), replaceWhat2With.get(originalKey).replace('/', '.'));
17.147 + }
17.148 }
17.149
17.150
17.151 @@ -509,6 +538,7 @@
17.152 CompilerSettingsImpl.class.getName(),
17.153 NbMutexEventProvider.class.getName(),
17.154 DefaultMutexImplementation.class.getName(),
17.155 + Utils.class.getName(),
17.156 IndexerControl.class.getName()
17.157 ));
17.158
18.1 --- a/cmdline/nbproject/project.properties Sat Aug 15 08:14:07 2015 +0200
18.2 +++ b/cmdline/nbproject/project.properties Sat Aug 15 13:14:20 2015 +0200
18.3 @@ -1,7 +1,9 @@
18.4 modules=\
18.5 ${project.org.netbeans.modules.jackpot30.cmdline.lib}:\
18.6 ${project.org.netbeans.modules.jackpot30.compiler}:\
18.7 - ${project.org.netbeans.modules.jackpot30.cmdline}
18.8 + ${project.org.netbeans.modules.jackpot30.cmdline}:\
18.9 + ${project.org.netbeans.modules.jackpot30.ap}
18.10 +project.org.netbeans.modules.jackpot30.ap=ap
18.11 project.org.netbeans.modules.jackpot30.cmdline=tool
18.12 project.org.netbeans.modules.jackpot30.cmdline.lib=lib
18.13 project.org.netbeans.modules.jackpot30.compiler=compiler
19.1 --- a/cmdline/tool/nbproject/genfiles.properties Sat Aug 15 08:14:07 2015 +0200
19.2 +++ b/cmdline/tool/nbproject/genfiles.properties Sat Aug 15 13:14:20 2015 +0200
19.3 @@ -3,6 +3,6 @@
19.4 build.xml.stylesheet.CRC32=a56c6a5b@1.44
19.5 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
19.6 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
19.7 -nbproject/build-impl.xml.data.CRC32=28a6110c
19.8 +nbproject/build-impl.xml.data.CRC32=c79833a9
19.9 nbproject/build-impl.xml.script.CRC32=08f1fb11
19.10 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
20.1 --- a/cmdline/tool/nbproject/project.xml Sat Aug 15 08:14:07 2015 +0200
20.2 +++ b/cmdline/tool/nbproject/project.xml Sat Aug 15 13:14:20 2015 +0200
20.3 @@ -74,6 +74,14 @@
20.4 </run-dependency>
20.5 </dependency>
20.6 <dependency>
20.7 + <code-name-base>org.netbeans.modules.jackpot30.cmdline.lib</code-name-base>
20.8 + <build-prerequisite/>
20.9 + <compile-dependency/>
20.10 + <run-dependency>
20.11 + <implementation-version/>
20.12 + </run-dependency>
20.13 + </dependency>
20.14 + <dependency>
20.15 <code-name-base>org.netbeans.modules.jackpot30.indexing</code-name-base>
20.16 <build-prerequisite/>
20.17 <compile-dependency/>
21.1 --- a/cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java Sat Aug 15 08:14:07 2015 +0200
21.2 +++ b/cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java Sat Aug 15 13:14:20 2015 +0200
21.3 @@ -84,6 +84,7 @@
21.4 import org.netbeans.api.java.source.ModificationResult;
21.5 import org.netbeans.api.project.ui.*;
21.6 import org.netbeans.core.startup.MainLookup;
21.7 +import org.netbeans.modules.jackpot30.cmdline.lib.Utils;
21.8 import org.netbeans.modules.jackpot30.ui.settings.XMLHintPreferences;
21.9 import org.netbeans.modules.java.hints.jackpot.spi.PatternConvertor;
21.10 import org.netbeans.modules.java.hints.providers.spi.HintDescription;
21.11 @@ -465,14 +466,7 @@
21.12 }
21.13
21.14 private static void findOccurrences(Iterable<? extends HintDescription> descs, Folder[] sourceRoot, ProgressHandleWrapper progress, HintsSettings settings, File out) throws IOException {
21.15 - final Map<String, String> id2DisplayName = new HashMap<String, String>();
21.16 -
21.17 - for (HintDescription hd : descs) {
21.18 - if (hd.getMetadata() != null) {
21.19 - id2DisplayName.put(hd.getMetadata().id, hd.getMetadata().displayName);
21.20 - }
21.21 - }
21.22 -
21.23 + final Map<String, String> id2DisplayName = Utils.computeId2DisplayName(descs);
21.24 ProgressHandleWrapper w = progress.startNextPartWithEmbedding(1, 1);
21.25 BatchResult occurrences = BatchSearch.findOccurrences(descs, Scopes.specifiedFoldersScope(sourceRoot), w, settings);
21.26
21.27 @@ -508,36 +502,12 @@
21.28
21.29 b.append('^');
21.30
21.31 - String id = error.getId();
21.32 -
21.33 - if (id != null && id.startsWith("text/x-java:")) {
21.34 - id = id.substring("text/x-java:".length());
21.35 - }
21.36 -
21.37 - String idDisplayName = id2DisplayName.get(id);
21.38 -
21.39 - if (idDisplayName == null) {
21.40 - idDisplayName = "unknown";
21.41 - }
21.42 -
21.43 - for (Entry<String, String> remap : toIdRemap.entrySet()) {
21.44 - idDisplayName = idDisplayName.replace(remap.getKey(), remap.getValue());
21.45 - }
21.46 -
21.47 - idDisplayName = idDisplayName.replaceAll("[^A-Za-z0-9]", "_").replaceAll("_+", "_");
21.48 -
21.49 - idDisplayName = "[" + idDisplayName + "] ";
21.50 -
21.51 + String idDisplayName = Utils.categoryName(error.getId(), id2DisplayName);
21.52 System.out.println(FileUtil.getFileDisplayName(error.getFile()) + ":" + (lineNumber + 1) + ": warning: " + idDisplayName + error.getDescription());
21.53 System.out.println(line);
21.54 System.out.println(b);
21.55 }
21.56
21.57 - private static final Map<String, String> toIdRemap = new HashMap<String, String>() {{
21.58 - put("==", "equals");
21.59 - put("!=", "not_equals");
21.60 - }};
21.61 -
21.62 private static void apply(Iterable<? extends HintDescription> descs, Folder[] sourceRoot, ProgressHandleWrapper progress, HintsSettings settings, File out) throws IOException {
21.63 ProgressHandleWrapper w = progress.startNextPartWithEmbedding(1, 1);
21.64 BatchResult occurrences = BatchSearch.findOccurrences(descs, Scopes.specifiedFoldersScope(sourceRoot), w, settings);