Commits

Jan Lahoda committed 58e6fd7

bitbucket-20: adding conditions for enclosing class/package.

  • Participants
  • Parent commits 9eef98c

Comments (0)

Files changed (4)

file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java

 
 package org.netbeans.modules.jackpot30.file.conditionapi;
 
+import com.sun.source.tree.CompilationUnitTree;
 import com.sun.source.tree.Tree.Kind;
 import com.sun.source.util.TreePath;
 import java.util.ArrayList;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import org.netbeans.api.annotations.common.CheckForNull;
 import org.netbeans.api.annotations.common.NonNull;
 import org.netbeans.api.java.queries.SourceLevelQuery;
+import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.jackpot30.file.APIAccessor;
 import org.netbeans.modules.jackpot30.spi.Hacks;
 import org.netbeans.modules.java.hints.jackpot.spi.HintContext;
         APIAccessor.IMPL = new APIAccessorImpl();
     }
 
+    /**Returns canonical names of classes that enclose the {@link Variable}.
+     * If the given {@link Variable} represents a class, its canonical name is also listed.
+     * The names are given from the innermost class to the outermost class.
+     *
+     * @return the canonical names of the enclosing classes
+     */
+    public @NonNull Iterable<? extends String> enclosingClasses(Variable forVariable) {
+        List<String> result = new ArrayList<String>();
+        TreePath path = getSingleVariable(forVariable);
+
+        while (path != null) {
+            TreePath current = path;
+
+            path = path.getParentPath();
+            
+            if (!TreeUtilities.CLASS_TREE_KINDS.contains(current.getLeaf().getKind())) continue;
+
+            Element e = ctx.getInfo().getTrees().getElement(current);
+
+            if (e == null) continue;
+
+            if (e.getKind().isClass() || e.getKind().isInterface()) {
+                result.add(((TypeElement) e).getQualifiedName().toString());
+            }
+        }
+
+        return result;
+    }
+
+    /**Returns name of package in which the current file is located. Default package
+     * is represented by an empty string.
+     *
+     * @return the name of the enclosing package
+     */
+    public @NonNull String enclosingPackage() {
+        CompilationUnitTree cut = ctx.getInfo().getCompilationUnit();
+
+        return cut.getPackageName() != null ? cut.getPackageName().toString() : "";
+    }
+
     static final class APIAccessorImpl extends APIAccessor {
 
         @Override

file/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilities.java

 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.Set;
+import java.util.regex.Pattern;
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.Modifier;
     public boolean containsAny(Variable var, String... patterns) {
         return matcher.containsAny(var, patterns);
     }
+
+    /**Tests whether the current occurrences is enclosed (directly or indirectly)
+     * by any of the specified classes.
+     *
+     * @param className canonical class names of possibly enclosing classes
+     * @return true if and only if the current occurrence is directly or indirectly
+     *              enclosed by any of the given classes.
+     */
+    public boolean inClass(String... className) {
+        Pattern p = constructRegexp(className);
+        Variable current = context.variableForName("$_");
+
+        assert current != null;
+
+        for (String canonicalName : context.enclosingClasses(current)) {
+            if (p.matcher(canonicalName).matches()) return true;
+        }
+
+        return false;
+    }
+
+    /**Tests whether the current occurrences is in any of the given packages.
+     *
+     * @param packageName names of possibly enclosing packages
+     * @return true if and only if the current occurrence is inside any of the
+     *              given packages
+     */
+    public boolean inPackage(String... packageName) {
+        Pattern p = constructRegexp(packageName);
+
+        return p.matcher(context.enclosingPackage()).matches();
+    }
+
+    private static Pattern constructRegexp(String[] pattern) {
+        StringBuilder regexp = new StringBuilder();
+        boolean first = true;
+        for (String p : pattern) {
+            if (first) regexp.append("|");
+
+            regexp.append("(");
+            regexp.append(Pattern.quote(p));
+            regexp.append(")");
+            first = false;
+        }
+        Pattern p = Pattern.compile(regexp.toString());
+        return p;
+    }
 }

file/test/unit/src/org/netbeans/modules/jackpot30/file/conditionapi/ContextTest.java

+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.file.conditionapi;
+
+import com.sun.source.util.TreePath;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+import org.netbeans.modules.jackpot30.impl.TestBase;
+import org.netbeans.modules.java.hints.jackpot.spi.HintContext;
+
+/**
+ *
+ * @author lahvac
+ */
+public class ContextTest extends TestBase {
+
+    public ContextTest(String name) {
+        super(name);
+    }
+
+    public void testEnclosingClasses() throws Exception {
+        String code = "package test; public class Test { public static class X { private int i|i; } }";
+        int pos = code.indexOf("|");
+        
+        code = code.replaceAll(Pattern.quote("|"), "");
+
+        prepareTest("test/Test.java", code);
+
+        TreePath tp = info.getTreeUtilities().pathFor(pos);
+        Map<String, TreePath> variables = new HashMap<String, TreePath>();
+        variables.put("$1", tp);
+        variables.put("$2", tp.getParentPath());
+        variables.put("$3", tp.getParentPath().getParentPath());
+        Map<String, Collection<? extends TreePath>> multiVariables = Collections.<String, Collection<? extends TreePath>>emptyMap();
+        Map<String, String> variables2Names = Collections.emptyMap();
+        Context ctx = new Context(HintContext.create(info, null, null, variables, multiVariables, variables2Names));
+
+        assertEquals(Arrays.asList("test.Test.X", "test.Test"), ctx.enclosingClasses(new Variable("$1")));
+        assertEquals(Arrays.asList("test.Test.X", "test.Test"), ctx.enclosingClasses(new Variable("$2")));
+        assertEquals(Arrays.asList("test.Test"), ctx.enclosingClasses(new Variable("$3")));
+    }
+
+}

file/test/unit/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilitiesTest.java

+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * <p/>
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ * <p/>
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ * <p/>
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development and
+ * Distribution License("CDDL") (collectively, the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy of
+ * the License at http://www.netbeans.org/cddl-gplv2.html or
+ * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
+ * governing permissions and limitations under the License. When distributing
+ * the software, include this License Header Notice in each file and include
+ * the License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided by
+ * Oracle in the GPL Version 2 section of the License file that accompanied
+ * this code. If applicable, add the following below the License Header, with
+ * the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions Copyrighted [year] [name of copyright owner]"
+ * <p/>
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you do not indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to its
+ * licensees as provided above. However, if you add GPL Version 2 code and
+ * therefore, elected the GPL Version 2 license, then the option applies only
+ * if the new code is made subject to such option by the copyright holder.
+ * <p/>
+ * Contributor(s):
+ * <p/>
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.file.conditionapi;
+
+import com.sun.source.util.TreePath;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.regex.Pattern;
+import org.netbeans.modules.jackpot30.impl.TestBase;
+import org.netbeans.modules.java.hints.jackpot.spi.HintContext;
+
+/**
+ *
+ * @author lahvac
+ */
+public class DefaultRuleUtilitiesTest extends TestBase {
+
+    public DefaultRuleUtilitiesTest(String name) {
+        super(name);
+    }
+
+    public void testEnclosingClasses() throws Exception {
+        String code = "package test; public class Test { public static class X { private int i|i; } }";
+        int pos = code.indexOf("|");
+
+        code = code.replaceAll(Pattern.quote("|"), "");
+
+        prepareTest("test/Test.java", code);
+
+        TreePath tp = info.getTreeUtilities().pathFor(pos);
+        Map<String, TreePath> variables = Collections.<String, TreePath>emptyMap();
+        Map<String, Collection<? extends TreePath>> multiVariables = Collections.<String, Collection<? extends TreePath>>emptyMap();
+        Map<String, String> variables2Names = Collections.emptyMap();
+        Context ctx = new Context(HintContext.create(info, null, tp, variables, multiVariables, variables2Names));
+        DefaultRuleUtilities utils = new DefaultRuleUtilities(ctx, new Matcher(ctx));
+
+        assertTrue(utils.inClass("test.Test.X"));
+        assertTrue(utils.inClass("test.Test"));
+        assertFalse(utils.inClass("test.TestA"));
+    }
+}