bitbucket-20: adding conditions for enclosing class/package (transplanting from trunk). release701
authorJan Lahoda <jlahoda@netbeans.org>
Thu, 21 Jul 2011 22:51:52 +0200
branchrelease701
changeset 648cb630b7113bf
parent 632 fcb0069e23c5
bitbucket-20: adding conditions for enclosing class/package (transplanting from trunk).
file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java
file/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilities.java
file/test/unit/src/org/netbeans/modules/jackpot30/file/conditionapi/ContextTest.java
file/test/unit/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilitiesTest.java
     1.1 --- a/file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java	Sun Jul 10 21:50:05 2011 +0200
     1.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/conditionapi/Context.java	Thu Jul 21 22:51:52 2011 +0200
     1.3 @@ -39,6 +39,7 @@
     1.4  
     1.5  package org.netbeans.modules.jackpot30.file.conditionapi;
     1.6  
     1.7 +import com.sun.source.tree.CompilationUnitTree;
     1.8  import com.sun.source.tree.Tree.Kind;
     1.9  import com.sun.source.util.TreePath;
    1.10  import java.util.ArrayList;
    1.11 @@ -55,11 +56,13 @@
    1.12  import javax.lang.model.element.Element;
    1.13  import javax.lang.model.element.ElementKind;
    1.14  import javax.lang.model.element.Modifier;
    1.15 +import javax.lang.model.element.TypeElement;
    1.16  import javax.lang.model.type.TypeKind;
    1.17  import javax.lang.model.type.TypeMirror;
    1.18  import org.netbeans.api.annotations.common.CheckForNull;
    1.19  import org.netbeans.api.annotations.common.NonNull;
    1.20  import org.netbeans.api.java.queries.SourceLevelQuery;
    1.21 +import org.netbeans.api.java.source.TreeUtilities;
    1.22  import org.netbeans.modules.jackpot30.file.APIAccessor;
    1.23  import org.netbeans.modules.jackpot30.spi.Hacks;
    1.24  import org.netbeans.modules.jackpot30.spi.HintContext;
    1.25 @@ -250,6 +253,46 @@
    1.26          APIAccessor.IMPL = new APIAccessorImpl();
    1.27      }
    1.28  
    1.29 +    /**Returns canonical names of classes that enclose the {@link Variable}.
    1.30 +     * If the given {@link Variable} represents a class, its canonical name is also listed.
    1.31 +     * The names are given from the innermost class to the outermost class.
    1.32 +     *
    1.33 +     * @return the canonical names of the enclosing classes
    1.34 +     */
    1.35 +    public @NonNull Iterable<? extends String> enclosingClasses(Variable forVariable) {
    1.36 +        List<String> result = new ArrayList<String>();
    1.37 +        TreePath path = getSingleVariable(forVariable);
    1.38 +
    1.39 +        while (path != null) {
    1.40 +            TreePath current = path;
    1.41 +
    1.42 +            path = path.getParentPath();
    1.43 +            
    1.44 +            if (!TreeUtilities.CLASS_TREE_KINDS.contains(current.getLeaf().getKind())) continue;
    1.45 +
    1.46 +            Element e = ctx.getInfo().getTrees().getElement(current);
    1.47 +
    1.48 +            if (e == null) continue;
    1.49 +
    1.50 +            if (e.getKind().isClass() || e.getKind().isInterface()) {
    1.51 +                result.add(((TypeElement) e).getQualifiedName().toString());
    1.52 +            }
    1.53 +        }
    1.54 +
    1.55 +        return result;
    1.56 +    }
    1.57 +
    1.58 +    /**Returns name of package in which the current file is located. Default package
    1.59 +     * is represented by an empty string.
    1.60 +     *
    1.61 +     * @return the name of the enclosing package
    1.62 +     */
    1.63 +    public @NonNull String enclosingPackage() {
    1.64 +        CompilationUnitTree cut = ctx.getInfo().getCompilationUnit();
    1.65 +
    1.66 +        return cut.getPackageName() != null ? cut.getPackageName().toString() : "";
    1.67 +    }
    1.68 +
    1.69      static final class APIAccessorImpl extends APIAccessor {
    1.70  
    1.71          @Override
     2.1 --- a/file/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilities.java	Sun Jul 10 21:50:05 2011 +0200
     2.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilities.java	Thu Jul 21 22:51:52 2011 +0200
     2.3 @@ -42,6 +42,7 @@
     2.4  import java.util.Arrays;
     2.5  import java.util.EnumSet;
     2.6  import java.util.Set;
     2.7 +import java.util.regex.Pattern;
     2.8  import javax.lang.model.SourceVersion;
     2.9  import javax.lang.model.element.ElementKind;
    2.10  import javax.lang.model.element.Modifier;
    2.11 @@ -114,4 +115,51 @@
    2.12      public boolean containsAny(Variable var, String... patterns) {
    2.13          return matcher.containsAny(var, patterns);
    2.14      }
    2.15 +
    2.16 +    /**Tests whether the current occurrences is enclosed (directly or indirectly)
    2.17 +     * by any of the specified classes.
    2.18 +     *
    2.19 +     * @param className canonical class names of possibly enclosing classes
    2.20 +     * @return true if and only if the current occurrence is directly or indirectly
    2.21 +     *              enclosed by any of the given classes.
    2.22 +     */
    2.23 +    public boolean inClass(String... className) {
    2.24 +        Pattern p = constructRegexp(className);
    2.25 +        Variable current = context.variableForName("$_");
    2.26 +
    2.27 +        assert current != null;
    2.28 +
    2.29 +        for (String canonicalName : context.enclosingClasses(current)) {
    2.30 +            if (p.matcher(canonicalName).matches()) return true;
    2.31 +        }
    2.32 +
    2.33 +        return false;
    2.34 +    }
    2.35 +
    2.36 +    /**Tests whether the current occurrences is in any of the given packages.
    2.37 +     *
    2.38 +     * @param packageName names of possibly enclosing packages
    2.39 +     * @return true if and only if the current occurrence is inside any of the
    2.40 +     *              given packages
    2.41 +     */
    2.42 +    public boolean inPackage(String... packageName) {
    2.43 +        Pattern p = constructRegexp(packageName);
    2.44 +
    2.45 +        return p.matcher(context.enclosingPackage()).matches();
    2.46 +    }
    2.47 +
    2.48 +    private static Pattern constructRegexp(String[] pattern) {
    2.49 +        StringBuilder regexp = new StringBuilder();
    2.50 +        boolean first = true;
    2.51 +        for (String p : pattern) {
    2.52 +            if (first) regexp.append("|");
    2.53 +
    2.54 +            regexp.append("(");
    2.55 +            regexp.append(Pattern.quote(p));
    2.56 +            regexp.append(")");
    2.57 +            first = false;
    2.58 +        }
    2.59 +        Pattern p = Pattern.compile(regexp.toString());
    2.60 +        return p;
    2.61 +    }
    2.62  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/file/test/unit/src/org/netbeans/modules/jackpot30/file/conditionapi/ContextTest.java	Thu Jul 21 22:51:52 2011 +0200
     3.3 @@ -0,0 +1,84 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved.
     3.8 + *
     3.9 + * The contents of this file are subject to the terms of either the GNU
    3.10 + * General Public License Version 2 only ("GPL") or the Common
    3.11 + * Development and Distribution License("CDDL") (collectively, the
    3.12 + * "License"). You may not use this file except in compliance with the
    3.13 + * License. You can obtain a copy of the License at
    3.14 + * http://www.netbeans.org/cddl-gplv2.html
    3.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.16 + * specific language governing permissions and limitations under the
    3.17 + * License.  When distributing the software, include this License Header
    3.18 + * Notice in each file and include the License file at
    3.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    3.20 + * particular file as subject to the "Classpath" exception as provided
    3.21 + * by Sun in the GPL Version 2 section of the License file that
    3.22 + * accompanied this code. If applicable, add the following below the
    3.23 + * License Header, with the fields enclosed by brackets [] replaced by
    3.24 + * your own identifying information:
    3.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.26 + *
    3.27 + * If you wish your version of this file to be governed by only the CDDL
    3.28 + * or only the GPL Version 2, indicate your decision by adding
    3.29 + * "[Contributor] elects to include this software in this distribution
    3.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.31 + * single choice of license, a recipient has the option to distribute
    3.32 + * your version of this file under either the CDDL, the GPL Version 2 or
    3.33 + * to extend the choice of license to its licensees as provided above.
    3.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    3.35 + * Version 2 license, then the option applies only if the new code is
    3.36 + * made subject to such option by the copyright holder.
    3.37 + *
    3.38 + * Contributor(s):
    3.39 + *
    3.40 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
    3.41 + */
    3.42 +
    3.43 +package org.netbeans.modules.jackpot30.file.conditionapi;
    3.44 +
    3.45 +import com.sun.source.util.TreePath;
    3.46 +import java.util.Arrays;
    3.47 +import java.util.Collection;
    3.48 +import java.util.Collections;
    3.49 +import java.util.HashMap;
    3.50 +import java.util.Map;
    3.51 +import java.util.regex.Pattern;
    3.52 +import org.netbeans.modules.jackpot30.impl.TestBase;
    3.53 +import org.netbeans.modules.jackpot30.spi.HintContext;
    3.54 +
    3.55 +/**
    3.56 + *
    3.57 + * @author lahvac
    3.58 + */
    3.59 +public class ContextTest extends TestBase {
    3.60 +
    3.61 +    public ContextTest(String name) {
    3.62 +        super(name);
    3.63 +    }
    3.64 +
    3.65 +    public void testEnclosingClasses() throws Exception {
    3.66 +        String code = "package test; public class Test { public static class X { private int i|i; } }";
    3.67 +        int pos = code.indexOf("|");
    3.68 +        
    3.69 +        code = code.replaceAll(Pattern.quote("|"), "");
    3.70 +
    3.71 +        prepareTest("test/Test.java", code);
    3.72 +
    3.73 +        TreePath tp = info.getTreeUtilities().pathFor(pos);
    3.74 +        Map<String, TreePath> variables = new HashMap<String, TreePath>();
    3.75 +        variables.put("$1", tp);
    3.76 +        variables.put("$2", tp.getParentPath());
    3.77 +        variables.put("$3", tp.getParentPath().getParentPath());
    3.78 +        Map<String, Collection<? extends TreePath>> multiVariables = Collections.<String, Collection<? extends TreePath>>emptyMap();
    3.79 +        Map<String, String> variables2Names = Collections.emptyMap();
    3.80 +        Context ctx = new Context(HintContext.create(info, null, null, variables, multiVariables, variables2Names));
    3.81 +
    3.82 +        assertEquals(Arrays.asList("test.Test.X", "test.Test"), ctx.enclosingClasses(new Variable("$1")));
    3.83 +        assertEquals(Arrays.asList("test.Test.X", "test.Test"), ctx.enclosingClasses(new Variable("$2")));
    3.84 +        assertEquals(Arrays.asList("test.Test"), ctx.enclosingClasses(new Variable("$3")));
    3.85 +    }
    3.86 +
    3.87 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/file/test/unit/src/org/netbeans/modules/jackpot30/file/conditionapi/DefaultRuleUtilitiesTest.java	Thu Jul 21 22:51:52 2011 +0200
     4.3 @@ -0,0 +1,77 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + * <p/>
     4.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
     4.8 + * <p/>
     4.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    4.10 + * Other names may be trademarks of their respective owners.
    4.11 + * <p/>
    4.12 + * The contents of this file are subject to the terms of either the GNU
    4.13 + * General Public License Version 2 only ("GPL") or the Common Development and
    4.14 + * Distribution License("CDDL") (collectively, the "License"). You may not use
    4.15 + * this file except in compliance with the License. You can obtain a copy of
    4.16 + * the License at http://www.netbeans.org/cddl-gplv2.html or
    4.17 + * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
    4.18 + * governing permissions and limitations under the License. When distributing
    4.19 + * the software, include this License Header Notice in each file and include
    4.20 + * the License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
    4.21 + * particular file as subject to the "Classpath" exception as provided by
    4.22 + * Oracle in the GPL Version 2 section of the License file that accompanied
    4.23 + * this code. If applicable, add the following below the License Header, with
    4.24 + * the fields enclosed by brackets [] replaced by your own identifying
    4.25 + * information: "Portions Copyrighted [year] [name of copyright owner]"
    4.26 + * <p/>
    4.27 + * If you wish your version of this file to be governed by only the CDDL or
    4.28 + * only the GPL Version 2, indicate your decision by adding "[Contributor]
    4.29 + * elects to include this software in this distribution under the [CDDL or GPL
    4.30 + * Version 2] license." If you do not indicate a single choice of license, a
    4.31 + * recipient has the option to distribute your version of this file under
    4.32 + * either the CDDL, the GPL Version 2 or to extend the choice of license to its
    4.33 + * licensees as provided above. However, if you add GPL Version 2 code and
    4.34 + * therefore, elected the GPL Version 2 license, then the option applies only
    4.35 + * if the new code is made subject to such option by the copyright holder.
    4.36 + * <p/>
    4.37 + * Contributor(s):
    4.38 + * <p/>
    4.39 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
    4.40 + */
    4.41 +package org.netbeans.modules.jackpot30.file.conditionapi;
    4.42 +
    4.43 +import com.sun.source.util.TreePath;
    4.44 +import java.util.Collection;
    4.45 +import java.util.Collections;
    4.46 +import java.util.Map;
    4.47 +import java.util.regex.Pattern;
    4.48 +import org.netbeans.modules.jackpot30.impl.TestBase;
    4.49 +import org.netbeans.modules.jackpot30.spi.HintContext;
    4.50 +
    4.51 +/**
    4.52 + *
    4.53 + * @author lahvac
    4.54 + */
    4.55 +public class DefaultRuleUtilitiesTest extends TestBase {
    4.56 +
    4.57 +    public DefaultRuleUtilitiesTest(String name) {
    4.58 +        super(name);
    4.59 +    }
    4.60 +
    4.61 +    public void testEnclosingClasses() throws Exception {
    4.62 +        String code = "package test; public class Test { public static class X { private int i|i; } }";
    4.63 +        int pos = code.indexOf("|");
    4.64 +
    4.65 +        code = code.replaceAll(Pattern.quote("|"), "");
    4.66 +
    4.67 +        prepareTest("test/Test.java", code);
    4.68 +
    4.69 +        TreePath tp = info.getTreeUtilities().pathFor(pos);
    4.70 +        Map<String, TreePath> variables = Collections.<String, TreePath>emptyMap();
    4.71 +        Map<String, Collection<? extends TreePath>> multiVariables = Collections.<String, Collection<? extends TreePath>>emptyMap();
    4.72 +        Map<String, String> variables2Names = Collections.emptyMap();
    4.73 +        Context ctx = new Context(HintContext.create(info, null, tp, variables, multiVariables, variables2Names));
    4.74 +        DefaultRuleUtilities utils = new DefaultRuleUtilities(ctx, new Matcher(ctx));
    4.75 +
    4.76 +        assertTrue(utils.inClass("test.Test.X"));
    4.77 +        assertTrue(utils.inClass("test.Test"));
    4.78 +        assertFalse(utils.inClass("test.TestA"));
    4.79 +    }
    4.80 +}