1.1 --- a/o.jython/manifest.mf Fri Sep 18 16:20:24 2015 -0500
1.2 +++ b/o.jython/manifest.mf Mon Sep 21 13:01:16 2015 +0200
1.3 @@ -1,6 +1,6 @@
1.4 Manifest-Version: 1.0
1.5 OpenIDE-Module: org.jython/2
1.6 OpenIDE-Module-Localizing-Bundle: org/jython/Bundle.properties
1.7 -OpenIDE-Module-Specification-Version: 2.7
1.8 +OpenIDE-Module-Specification-Version: 2.12
1.9 AutoUpdate-Show-In-Client: false
1.10
2.1 --- a/o.jython/nbproject/project.xml Fri Sep 18 16:20:24 2015 -0500
2.2 +++ b/o.jython/nbproject/project.xml Mon Sep 21 13:01:16 2015 +0200
2.3 @@ -16,6 +16,8 @@
2.4 </module-dependencies>
2.5 <friend-packages>
2.6 <friend>org.netbeans.modules.python.editor</friend>
2.7 + <friend>org.netbeans.modules.python.hints</friend>
2.8 + <friend>org.netbeans.modules.python.source</friend>
2.9 <package>org.python.antlr</package>
2.10 <package>org.python.antlr.ast</package>
2.11 <package>org.python.antlr.base</package>
3.1 --- a/python.editor/nbproject/project.properties Fri Sep 18 16:20:24 2015 -0500
3.2 +++ b/python.editor/nbproject/project.properties Mon Sep 21 13:01:16 2015 +0200
3.3 @@ -18,7 +18,7 @@
3.4 javac.source=1.7
3.5 javac.compilerargs=-Xlint -Xlint:-serial
3.6 nbm.needs.restart=true
3.7 -spec.version.base=1.8.1
3.8 +spec.version.base=1.8.2
3.9 spec.version.base.fatal.warning=false
3.10
3.11 ant.jar=${ant.core.lib}
4.1 --- a/python.editor/nbproject/project.xml Fri Sep 18 16:20:24 2015 -0500
4.2 +++ b/python.editor/nbproject/project.xml Mon Sep 21 13:01:16 2015 +0200
4.3 @@ -307,7 +307,7 @@
4.4 <build-prerequisite/>
4.5 <compile-dependency/>
4.6 <run-dependency>
4.7 - <specification-version>1.0</specification-version>
4.8 + <specification-version>1.1</specification-version>
4.9 </run-dependency>
4.10 </dependency>
4.11 <dependency>
4.12 @@ -417,12 +417,14 @@
4.13 </dependency>
4.14 </module-dependencies>
4.15 <friend-packages>
4.16 + <friend>org.netbeans.modules.python.hints</friend>
4.17 <friend>org.netbeans.modules.python.project</friend>
4.18 <friend>org.netbeans.modules.python.project2</friend>
4.19 <friend>org.netbeans.modules.python.testrunner</friend>
4.20 <package>org.netbeans.modules.python.editor</package>
4.21 <package>org.netbeans.modules.python.editor.codecoverage</package>
4.22 <package>org.netbeans.modules.python.editor.lexer</package>
4.23 + <package>org.netbeans.modules.python.editor.scopes</package>
4.24 </friend-packages>
4.25 </data>
4.26 </configuration>
5.1 --- a/python.editor/src/org/netbeans/modules/python/editor/AstPath.java Fri Sep 18 16:20:24 2015 -0500
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,436 +0,0 @@
5.4 -/*
5.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5.6 - *
5.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5.8 - *
5.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
5.10 - * Other names may be trademarks of their respective owners.
5.11 - *
5.12 - * The contents of this file are subject to the terms of either the GNU
5.13 - * General Public License Version 2 only ("GPL") or the Common
5.14 - * Development and Distribution License("CDDL") (collectively, the
5.15 - * "License"). You may not use this file except in compliance with the
5.16 - * License. You can obtain a copy of the License at
5.17 - * http://www.netbeans.org/cddl-gplv2.html
5.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
5.19 - * specific language governing permissions and limitations under the
5.20 - * License. When distributing the software, include this License Header
5.21 - * Notice in each file and include the License file at
5.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
5.23 - * particular file as subject to the "Classpath" exception as provided
5.24 - * by Oracle in the GPL Version 2 section of the License file that
5.25 - * accompanied this code. If applicable, add the following below the
5.26 - * License Header, with the fields enclosed by brackets [] replaced by
5.27 - * your own identifying information:
5.28 - * "Portions Copyrighted [year] [name of copyright owner]"
5.29 - *
5.30 - * Contributor(s):
5.31 - *
5.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
5.33 - */
5.34 -package org.netbeans.modules.python.editor;
5.35 -
5.36 -import java.util.ArrayList;
5.37 -import java.util.Iterator;
5.38 -import java.util.ListIterator;
5.39 -import org.openide.util.Exceptions;
5.40 -import org.python.antlr.PythonTree;
5.41 -import org.python.antlr.Visitor;
5.42 -
5.43 -/**
5.44 - * AstPath represents a path from a root node to a particular node in the AST.
5.45 - * This is necessary because the parent node pointers in the nodes aren't always
5.46 - * non null, so we can't just pass a node as a reference to a traversable path
5.47 - * from the root to a node.
5.48 - *
5.49 - * @author Tor Norbye
5.50 - */
5.51 -public class AstPath implements Iterable<PythonTree> {
5.52 - private ArrayList<PythonTree> path = new ArrayList<>(30);
5.53 -
5.54 - public AstPath() {
5.55 - }
5.56 -
5.57 - public AstPath(AstPath other) {
5.58 - path.addAll(other.path);
5.59 - }
5.60 -
5.61 - public AstPath(ArrayList<PythonTree> path) {
5.62 - this.path = path;
5.63 - }
5.64 -
5.65 -// /**
5.66 -// * Initialize a node path to the given caretOffset
5.67 -// */
5.68 -// public AstPath(PythonTree root, int caretOffset) {
5.69 -// findPathTo(root, caretOffset);
5.70 -// }
5.71 -//
5.72 -// /**
5.73 -// * Find the path to the given node in the AST
5.74 -// */
5.75 -// @SuppressWarnings("unchecked")
5.76 -// public AstPath(PythonTree node, PythonTree target) {
5.77 -// if (!find(node, target)) {
5.78 -// path.clear();
5.79 -// } else {
5.80 -// // Reverse the list such that node is on top
5.81 -// // When I get time rewrite the find method to build the list that way in the first place
5.82 -// Collections.reverse(path);
5.83 -// }
5.84 -// }
5.85 - public void descend(PythonTree node) {
5.86 - path.add(node);
5.87 - }
5.88 -
5.89 - public void ascend() {
5.90 - path.remove(path.size() - 1);
5.91 - }
5.92 -
5.93 - /**
5.94 - * Return the closest ancestor of the leaf that is of the given type
5.95 - */
5.96 - public PythonTree getTypedAncestor(Class clz) {
5.97 - return getTypedAncestor(clz, null);
5.98 - }
5.99 -
5.100 - /**
5.101 - * Return the closest ancestor of the given node that is of the given type
5.102 - */
5.103 - public PythonTree getTypedAncestor(Class clz, PythonTree from) {
5.104 - int i = path.size() - 1;
5.105 -
5.106 - // First find the given starting point
5.107 - if (from != null) {
5.108 - for (; i >= 0; i--) {
5.109 - PythonTree node = path.get(i);
5.110 -
5.111 - if (node == from) {
5.112 - break;
5.113 - }
5.114 - }
5.115 - }
5.116 -
5.117 - for (; i >= 0; i--) {
5.118 - PythonTree node = path.get(i);
5.119 -
5.120 - if (clz.isInstance(node)) {
5.121 - return node;
5.122 - }
5.123 - }
5.124 -
5.125 - return null; // not found
5.126 - }
5.127 -
5.128 - /**
5.129 - * Return true iff this path contains a node of the given node type
5.130 - *
5.131 - * @param nodeType The nodeType to check
5.132 - * @return true if the given nodeType is found in the path
5.133 - */
5.134 - public boolean contains(Class clz) {
5.135 - return getTypedAncestor(clz) != null;
5.136 - }
5.137 -
5.138 -// /**
5.139 -// * Find the position closest to the given offset in the AST. Place the path from the leaf up to the path in the
5.140 -// * passed in path list.
5.141 -// */
5.142 -// @SuppressWarnings("unchecked")
5.143 -// public PythonTree findPathTo(PythonTree node, int offset) {
5.144 -// PythonTree result = find(node, offset);
5.145 -// path.add(node);
5.146 -//
5.147 -// // Reverse the list such that node is on top
5.148 -// // When I get time rewrite the find method to build the list that way in the first place
5.149 -// Collections.reverse(path);
5.150 -//
5.151 -// return result;
5.152 -// }
5.153 -//
5.154 -// @SuppressWarnings("unchecked")
5.155 -// private PythonTree find(PythonTree node, int offset) {
5.156 -// int begin = node.getSourceStart();
5.157 -// int end = node.getSourceEnd();
5.158 -//
5.159 -// if ((offset >= begin) && (offset <= end)) {
5.160 -// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
5.161 -// PythonTree found = find(child, offset);
5.162 -//
5.163 -// if (found != null) {
5.164 -// path.add(child);
5.165 -//
5.166 -// return found;
5.167 -// }
5.168 -// }
5.169 -//
5.170 -// return node;
5.171 -// } else {
5.172 -// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
5.173 -// PythonTree found = find(child, offset);
5.174 -//
5.175 -// if (found != null) {
5.176 -// path.add(child);
5.177 -//
5.178 -// return found;
5.179 -// }
5.180 -// }
5.181 -//
5.182 -// return null;
5.183 -// }
5.184 -// }
5.185 -//
5.186 -// /**
5.187 -// * Find the path to the given node in the AST
5.188 -// */
5.189 -// @SuppressWarnings("unchecked")
5.190 -// public boolean find(PythonTree node, PythonTree target) {
5.191 -// if (node == target) {
5.192 -// return true;
5.193 -// }
5.194 -//
5.195 -// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
5.196 -// boolean found = find(child, target);
5.197 -//
5.198 -// if (found) {
5.199 -// path.add(child);
5.200 -//
5.201 -// return found;
5.202 -// }
5.203 -// }
5.204 -//
5.205 -// return false;
5.206 -// }
5.207 - @Override
5.208 - public String toString() {
5.209 - StringBuilder sb = new StringBuilder();
5.210 - sb.append("Path(");
5.211 - sb.append(path.size());
5.212 - sb.append(")=[");
5.213 -
5.214 - for (PythonTree n : path) {
5.215 - String name = n.toString();
5.216 - name = name.substring(name.lastIndexOf('.') + 1);
5.217 - sb.append(name);
5.218 - sb.append(":");
5.219 - }
5.220 -
5.221 - sb.append("]");
5.222 -
5.223 - return sb.toString();
5.224 - }
5.225 -
5.226 - public PythonTree leaf() {
5.227 - if (path.size() == 0) {
5.228 - return null;
5.229 - } else {
5.230 - return path.get(path.size() - 1);
5.231 - }
5.232 - }
5.233 -
5.234 - public PythonTree leafParent() {
5.235 - if (path.size() < 2) {
5.236 - return null;
5.237 - } else {
5.238 - return path.get(path.size() - 2);
5.239 - }
5.240 - }
5.241 -
5.242 - public PythonTree leafGrandParent() {
5.243 - if (path.size() < 3) {
5.244 - return null;
5.245 - } else {
5.246 - return path.get(path.size() - 3);
5.247 - }
5.248 - }
5.249 -
5.250 - /**
5.251 - * Return the top/module level node -- this is not the module node
5.252 - * itself but the first node below it.
5.253 - */
5.254 - public PythonTree topModuleLevel() {
5.255 - if (path.size() >= 2) {
5.256 - return path.get(1);
5.257 - } else {
5.258 - return null;
5.259 - }
5.260 - }
5.261 -
5.262 - public PythonTree root() {
5.263 - if (path.size() == 0) {
5.264 - return null;
5.265 - } else {
5.266 - return path.get(0);
5.267 - }
5.268 - }
5.269 -
5.270 - /** Return an iterator that returns the elements from the leaf back up to the root */
5.271 - @Override
5.272 - public Iterator<PythonTree> iterator() {
5.273 - return new LeafToRootIterator(path);
5.274 - }
5.275 -
5.276 - /** REturn an iterator that starts at the root and walks down to the leaf */
5.277 - public ListIterator<PythonTree> rootToLeaf() {
5.278 - return path.listIterator();
5.279 - }
5.280 -
5.281 - /** Return an iterator that walks from the leaf back up to the root */
5.282 - public ListIterator<PythonTree> leafToRoot() {
5.283 - return new LeafToRootIterator(path);
5.284 - }
5.285 -
5.286 - private static class LeafToRootIterator implements ListIterator<PythonTree> {
5.287 - private final ListIterator<PythonTree> it;
5.288 -
5.289 - private LeafToRootIterator(ArrayList<PythonTree> path) {
5.290 - it = path.listIterator(path.size());
5.291 - }
5.292 -
5.293 - @Override
5.294 - public boolean hasNext() {
5.295 - return it.hasPrevious();
5.296 - }
5.297 -
5.298 - @Override
5.299 - public PythonTree next() {
5.300 - return it.previous();
5.301 - }
5.302 -
5.303 - @Override
5.304 - public boolean hasPrevious() {
5.305 - return it.hasNext();
5.306 - }
5.307 -
5.308 - @Override
5.309 - public PythonTree previous() {
5.310 - return it.next();
5.311 - }
5.312 -
5.313 - @Override
5.314 - public int nextIndex() {
5.315 - return it.previousIndex();
5.316 - }
5.317 -
5.318 - @Override
5.319 - public int previousIndex() {
5.320 - return it.nextIndex();
5.321 - }
5.322 -
5.323 - @Override
5.324 - public void remove() {
5.325 - throw new UnsupportedOperationException("Not supported yet.");
5.326 - }
5.327 -
5.328 - @Override
5.329 - public void set(PythonTree arg0) {
5.330 - throw new UnsupportedOperationException("Not supported yet.");
5.331 - }
5.332 -
5.333 - @Override
5.334 - public void add(PythonTree arg0) {
5.335 - throw new UnsupportedOperationException("Not supported yet.");
5.336 - }
5.337 - }
5.338 -
5.339 - private static class FindByOffsetVisitor extends Visitor {
5.340 - private int targetOffset;
5.341 - private ArrayList<PythonTree> path = new ArrayList<>();
5.342 -
5.343 - private FindByOffsetVisitor(int targetOffset) {
5.344 - this.targetOffset = targetOffset;
5.345 - }
5.346 -
5.347 - @Override
5.348 - public void traverse(PythonTree node) throws Exception {
5.349 - if (targetOffset >= node.getCharStartIndex() && targetOffset <= node.getCharStopIndex()) {
5.350 -// if (targetOffset == node.getCharStopIndex() && node.getClass() == FunctionDef.class) {
5.351 -// // For functions, don't include the last offset, since we can end up with
5.352 -// // functions that overlap - caret at the start position will add BOTH functions
5.353 -// // which we don't want
5.354 -// } else {
5.355 - path.add(node);
5.356 -// }
5.357 - super.traverse(node);
5.358 - }
5.359 - }
5.360 -
5.361 - AstPath getPath() {
5.362 - return new AstPath(path);
5.363 - }
5.364 - }
5.365 -
5.366 - public static AstPath get(PythonTree root, int offset) {
5.367 - FindByOffsetVisitor finder = new FindByOffsetVisitor(offset);
5.368 - try {
5.369 - finder.visit(root);
5.370 - AstPath path = finder.getPath();
5.371 - if (path.path.size() == 0) {
5.372 - path.path.add(root);
5.373 - }
5.374 -
5.375 - return path;
5.376 - } catch (Exception ex) {
5.377 - Exceptions.printStackTrace(ex);
5.378 - }
5.379 -
5.380 - return null;
5.381 - }
5.382 -
5.383 - private static class FindByNodeVisitor extends Visitor {
5.384 - private PythonTree target;
5.385 - private int startOffset;
5.386 - private int endOffset;
5.387 - private ArrayList<PythonTree> path = new ArrayList<>();
5.388 - private boolean found;
5.389 -
5.390 - private FindByNodeVisitor(PythonTree target) {
5.391 - this.target = target;
5.392 - this.startOffset = target.getCharStartIndex();
5.393 - this.endOffset = target.getCharStopIndex();
5.394 - }
5.395 -
5.396 - @Override
5.397 - public void traverse(PythonTree node) throws Exception {
5.398 - if (found) {
5.399 - return;
5.400 - }
5.401 - if (node == target) {
5.402 - path.add(node);
5.403 - found = true;
5.404 - return;
5.405 - }
5.406 - if (startOffset >= node.getCharStartIndex() && endOffset <= node.getCharStopIndex()) {
5.407 - path.add(node);
5.408 - node.traverse(this);
5.409 - if (found) {
5.410 - return;
5.411 - }
5.412 - path.remove(path.size() - 1);
5.413 - }
5.414 - }
5.415 -
5.416 - AstPath getPath() {
5.417 - return new AstPath(path);
5.418 - }
5.419 - }
5.420 -
5.421 - /**
5.422 - * Find the path to the given node in the AST
5.423 - */
5.424 - public static AstPath get(PythonTree root, PythonTree target) {
5.425 - FindByNodeVisitor finder = new FindByNodeVisitor(target);
5.426 - try {
5.427 - finder.visit(root);
5.428 - AstPath path = finder.getPath();
5.429 - if (path.path.size() == 0) {
5.430 - path.path.add(root);
5.431 - }
5.432 -
5.433 - return path;
5.434 - } catch (Exception ex) {
5.435 - Exceptions.printStackTrace(ex);
5.436 - return null;
5.437 - }
5.438 - }
5.439 -}
6.1 --- a/python.editor/src/org/netbeans/modules/python/editor/GoToSuperTypeAction.java Fri Sep 18 16:20:24 2015 -0500
6.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/GoToSuperTypeAction.java Mon Sep 21 13:01:16 2015 +0200
6.3 @@ -43,6 +43,8 @@
6.4 */
6.5 package org.netbeans.modules.python.editor;
6.6
6.7 +import org.netbeans.modules.python.source.PythonParserResult;
6.8 +import org.netbeans.modules.python.source.PythonAstUtils;
6.9 import java.awt.Component;
6.10 import java.awt.Cursor;
6.11 import java.awt.Image;
7.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonAstUtils.java Fri Sep 18 16:20:24 2015 -0500
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,1007 +0,0 @@
7.4 -/*
7.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7.6 - *
7.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
7.8 - *
7.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7.10 - * Other names may be trademarks of their respective owners.
7.11 - *
7.12 - * The contents of this file are subject to the terms of either the GNU
7.13 - * General Public License Version 2 only ("GPL") or the Common
7.14 - * Development and Distribution License("CDDL") (collectively, the
7.15 - * "License"). You may not use this file except in compliance with the
7.16 - * License. You can obtain a copy of the License at
7.17 - * http://www.netbeans.org/cddl-gplv2.html
7.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
7.19 - * specific language governing permissions and limitations under the
7.20 - * License. When distributing the software, include this License Header
7.21 - * Notice in each file and include the License file at
7.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
7.23 - * particular file as subject to the "Classpath" exception as provided
7.24 - * by Oracle in the GPL Version 2 section of the License file that
7.25 - * accompanied this code. If applicable, add the following below the
7.26 - * License Header, with the fields enclosed by brackets [] replaced by
7.27 - * your own identifying information:
7.28 - * "Portions Copyrighted [year] [name of copyright owner]"
7.29 - *
7.30 - * Contributor(s):
7.31 - *
7.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
7.33 - */
7.34 -package org.netbeans.modules.python.editor;
7.35 -
7.36 -import java.util.ArrayList;
7.37 -import java.util.Collections;
7.38 -import java.util.HashSet;
7.39 -import java.util.Iterator;
7.40 -import java.util.List;
7.41 -import java.util.Set;
7.42 -import java.util.logging.Level;
7.43 -import java.util.logging.Logger;
7.44 -import javax.swing.text.BadLocationException;
7.45 -import javax.swing.text.Document;
7.46 -import org.netbeans.api.lexer.LanguagePath;
7.47 -import org.netbeans.api.lexer.TokenHierarchy;
7.48 -import org.netbeans.api.lexer.TokenSequence;
7.49 -import org.netbeans.api.lexer.TokenUtilities;
7.50 -import org.netbeans.editor.BaseDocument;
7.51 -import org.netbeans.editor.Finder;
7.52 -import org.netbeans.editor.FinderFactory;
7.53 -import org.netbeans.modules.csl.api.ElementKind;
7.54 -import org.netbeans.modules.csl.api.OffsetRange;
7.55 -import org.netbeans.modules.csl.api.StructureItem;
7.56 -import org.netbeans.modules.csl.spi.GsfUtilities;
7.57 -import org.netbeans.modules.csl.spi.ParserResult;
7.58 -import org.netbeans.modules.parsing.api.ParserManager;
7.59 -import org.netbeans.modules.parsing.api.ResultIterator;
7.60 -import org.netbeans.modules.parsing.api.Source;
7.61 -import org.netbeans.modules.parsing.api.UserTask;
7.62 -import org.netbeans.modules.parsing.spi.ParseException;
7.63 -import org.netbeans.modules.python.editor.elements.IndexedElement;
7.64 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
7.65 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
7.66 -import org.netbeans.modules.python.editor.lexer.PythonCommentTokenId;
7.67 -import org.netbeans.modules.python.editor.scopes.ScopeInfo;
7.68 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
7.69 -import org.netbeans.modules.python.editor.scopes.SymInfo;
7.70 -import org.openide.filesystems.FileObject;
7.71 -import org.openide.util.Exceptions;
7.72 -import org.python.antlr.PythonTree;
7.73 -import org.python.antlr.Visitor;
7.74 -import org.python.antlr.ast.Assign;
7.75 -import org.python.antlr.ast.Attribute;
7.76 -import org.python.antlr.ast.Call;
7.77 -import org.python.antlr.ast.ClassDef;
7.78 -import org.python.antlr.ast.Expr;
7.79 -import org.python.antlr.ast.FunctionDef;
7.80 -import org.python.antlr.ast.Import;
7.81 -import org.python.antlr.ast.ImportFrom;
7.82 -import org.python.antlr.ast.Module;
7.83 -import org.python.antlr.ast.Name;
7.84 -import org.python.antlr.ast.Str;
7.85 -import org.python.antlr.ast.arguments;
7.86 -import org.python.antlr.base.expr;
7.87 -import org.python.antlr.base.stmt;
7.88 -
7.89 -/**
7.90 - * Utility functions for dealing with the Jython AST
7.91 - *
7.92 - * @author Tor Norbye
7.93 - */
7.94 -public class PythonAstUtils {
7.95 - private PythonAstUtils() {
7.96 - // This is just a utility class, no instances expected so private constructor
7.97 - }
7.98 -
7.99 - public static int getAstOffset(ParserResult result, int lexOffset) {
7.100 - if (result != null) {
7.101 - return result.getSnapshot().getEmbeddedOffset(lexOffset);
7.102 - }
7.103 -
7.104 - return lexOffset;
7.105 - }
7.106 -
7.107 - public static OffsetRange getAstOffsets(ParserResult result, OffsetRange lexicalRange) {
7.108 - if (result != null) {
7.109 - int rangeStart = lexicalRange.getStart();
7.110 - int start = result.getSnapshot().getEmbeddedOffset(rangeStart);
7.111 - if (start == rangeStart) {
7.112 - return lexicalRange;
7.113 - } else if (start == -1) {
7.114 - return OffsetRange.NONE;
7.115 - } else {
7.116 - // Assumes the translated range maintains size
7.117 - return new OffsetRange(start, start + lexicalRange.getLength());
7.118 - }
7.119 - }
7.120 - return lexicalRange;
7.121 - }
7.122 -
7.123 - public static PythonParserResult getParseResult(ParserResult result) {
7.124 - if(result == null || !(result instanceof PythonParserResult)) {
7.125 - return null;
7.126 - } else {
7.127 - return ((PythonParserResult)result);
7.128 - }
7.129 - }
7.130 -
7.131 - public static PythonTree getRoot(ParserResult r) {
7.132 - assert r instanceof PythonParserResult;
7.133 -
7.134 - PythonParserResult result = (PythonParserResult)r;
7.135 -
7.136 - return result.getRoot();
7.137 - }
7.138 -
7.139 - /**
7.140 - * Return a range that matches the given node's source buffer range
7.141 - */
7.142 - @SuppressWarnings("unchecked")
7.143 - public static OffsetRange getNameRange(PythonParserResult info, PythonTree node) {
7.144 -// final int type = node.getType();
7.145 -// switch (type) {
7.146 -// case Token.FUNCTION: {
7.147 -// if (node.hasChildren()) {
7.148 -// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
7.149 -// if (child.getType() == Token.FUNCNAME) {
7.150 -// return getNameRange(child);
7.151 -// }
7.152 -// }
7.153 -// }
7.154 -//
7.155 -// return getRange(node);
7.156 -// }
7.157 -// case Token.NAME:
7.158 -// case Token.BINDNAME:
7.159 -// case Token.FUNCNAME:
7.160 -// case Token.PARAMETER:
7.161 -// case Token.OBJLITNAME:
7.162 -// int start = node.getSourceStart();
7.163 -// String name = node.getString();
7.164 -// return new OffsetRange(start, start+name.length());
7.165 -// case Token.CALL:
7.166 -// PythonTree namePythonTree = findCallNamePythonTree(node);
7.167 -// if (namePythonTree != null) {
7.168 -// return getNameRange(namePythonTree);
7.169 -// }
7.170 -// }
7.171 -
7.172 - // XXX Is there a faster way to determine if it's a function,
7.173 - // e.g. some kind of "kind" or "id" or "type" enum attribute on the tree node
7.174 - if (node instanceof FunctionDef) {
7.175 - FunctionDef def = (FunctionDef)node;
7.176 - //node.getType();
7.177 -
7.178 - int defStart = def.getCharStartIndex();
7.179 -
7.180 - // Turns out that when you have decorators, the function start offset
7.181 - // -includes- the decorators which precede the "def" keyword, thus we
7.182 - // have to scan forwards to find the true beginning.
7.183 - List<expr> decorators = def.getInternalDecorator_list();
7.184 - if (decorators != null && decorators.size() > 0) {
7.185 - int maxEnd = 0;
7.186 - for (expr expr : decorators) {
7.187 - int exprEnd = expr.getCharStopIndex();
7.188 - if (exprEnd > maxEnd) {
7.189 - maxEnd = exprEnd;
7.190 - }
7.191 - }
7.192 - if (decorators.size() > 1) {
7.193 - maxEnd++;
7.194 - }
7.195 - defStart = maxEnd;
7.196 -
7.197 - // At first I was justlooking for the largest end offset of the decorators,
7.198 - // but if you have additional comments etc. that won't work right, so
7.199 - // in this case, go and look at the actual document
7.200 - if (info != null) {
7.201 - BaseDocument doc = GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false);
7.202 - if (doc != null) {
7.203 - int lexOffset = PythonLexerUtils.getLexerOffset(info, defStart);
7.204 - int limitOffset = PythonLexerUtils.getLexerOffset(info, def.getCharStopIndex());
7.205 - if (lexOffset != -1 && limitOffset != -1) {
7.206 - Finder finder = new FinderFactory.StringFwdFinder("def ", true);
7.207 - try {
7.208 - int foundOffset = doc.find(finder, lexOffset, limitOffset);
7.209 - if (foundOffset != -1) {
7.210 - defStart = foundOffset;
7.211 - }
7.212 - } catch (BadLocationException ex) {
7.213 - Exceptions.printStackTrace(ex);
7.214 - }
7.215 - }
7.216 - }
7.217 - }
7.218 - }
7.219 -
7.220 - // HACK: There's no separate node for the name offset itself, so I need
7.221 - // to figure it out. For now assume that it's exactly 4 characters away
7.222 - // from the beginning of "def" - def plus space. If there are multiple spaces
7.223 - // this won't work. I ought to look in the document and ensure that the character
7.224 - // there in fact is the start of the name, and if not, search forwards for it.
7.225 - int DELTA = 4; // HACK:
7.226 - int start = defStart + DELTA;
7.227 - int end = start + def.getInternalName().length();
7.228 -
7.229 - // TODO - look up offset
7.230 -
7.231 - return new OffsetRange(start, end);
7.232 - } else if (node instanceof ClassDef) {
7.233 - ClassDef def = (ClassDef)node;
7.234 - //node.getType();
7.235 -
7.236 - // HACK: There's no separate node for the name offset itself, so I need
7.237 - // to figure it out. For now assume that it's exactly 6 characters away
7.238 - // from the beginning of "class" - class plus space. If there are multiple spaces
7.239 - // this won't work. I ought to look in the document and ensure that the character
7.240 - // there in fact is the start of the name, and if not, search forwards for it.
7.241 - int DELTA = 6; // HACK:
7.242 - int start = def.getCharStartIndex() + DELTA;
7.243 - int end = start + def.getInternalName().length();
7.244 -
7.245 - // TODO - look up offset
7.246 -
7.247 - return new OffsetRange(start, end);
7.248 - } else if (node instanceof Attribute) {
7.249 - Attribute attr = (Attribute)node;
7.250 - return getNameRange(info, attr.getInternalValue());
7.251 - } else if (node instanceof Call) {
7.252 - Call call = (Call)node;
7.253 - if (call.getInternalFunc() instanceof Name) {
7.254 - return getNameRange(info, call.getInternalFunc());
7.255 - } else if (call.getInternalFunc() instanceof Attribute) {
7.256 - // The call name is in the value part of the name.value part
7.257 - Attribute attr = (Attribute)call.getInternalFunc();
7.258 - int start = attr.getInternalValue().getCharStopIndex() + 1; // +1: Skip .
7.259 - String name = attr.getInternalAttr();
7.260 - return new OffsetRange(start, start + name.length());
7.261 - } else {
7.262 - String name = getCallName(call);
7.263 - if (name != null) {
7.264 - int start = call.getCharStartIndex();
7.265 - return new OffsetRange(start, start + name.length());
7.266 - }
7.267 - }
7.268 - }
7.269 -
7.270 - return getRange(node);
7.271 - }
7.272 -
7.273 - /**
7.274 - * Return a range that matches the given node's source buffer range
7.275 - */
7.276 - @SuppressWarnings("unchecked")
7.277 - public static OffsetRange getRange(PythonTree node) {
7.278 - final int start = node.getCharStartIndex();
7.279 - final int end = node.getCharStopIndex();
7.280 -
7.281 -// assert end >= start : "Invalid offsets for " + node + ": start=" + start + " and end=" + end;
7.282 - if (end < start) {
7.283 - Logger logger = Logger.getLogger(PythonAstUtils.class.getName());
7.284 - logger.log(Level.WARNING, "Invalid offsets for " + node + ": start=" + start + " and end=" + end);
7.285 - return new OffsetRange(start, start);
7.286 - }
7.287 -
7.288 - return new OffsetRange(start, end);
7.289 - }
7.290 -
7.291 - public static boolean isNameNode(PythonTree node) {
7.292 - if (node instanceof Name) {
7.293 - return true;
7.294 - }
7.295 -
7.296 - return false;
7.297 - }
7.298 -
7.299 - /** Return if a function is a staticmethod **/
7.300 - public static boolean isStaticMethod(PythonTree node) {
7.301 - if (node instanceof FunctionDef) {
7.302 - FunctionDef def = (FunctionDef)node;
7.303 - List<expr> decorators = def.getInternalDecorator_list();
7.304 - if (decorators != null && decorators.size() > 0) {
7.305 - for (expr decorator : decorators) {
7.306 - if (decorator instanceof Name) {
7.307 - String decoratorName = ((Name)decorator).getText();
7.308 - if (decoratorName.equals("staticmethod")) { // NOI18N
7.309 - return true;
7.310 - }
7.311 - }
7.312 - }
7.313 - }
7.314 - }
7.315 -
7.316 - return false;
7.317 - }
7.318 -
7.319 - /** Compute the module/class name for the given node path */
7.320 - public static String getFqnName(AstPath path) {
7.321 - StringBuilder sb = new StringBuilder();
7.322 -
7.323 - Iterator<PythonTree> it = path.rootToLeaf();
7.324 -
7.325 - while (it.hasNext()) {
7.326 - PythonTree node = it.next();
7.327 -
7.328 - if (node instanceof ClassDef) {
7.329 - if (sb.length() > 0) {
7.330 - sb.append('.'); // NOI18N
7.331 - }
7.332 - ClassDef cls = (ClassDef)node;
7.333 - sb.append(cls.getInternalName());
7.334 - }
7.335 - }
7.336 -
7.337 - return sb.toString();
7.338 - }
7.339 -
7.340 - /** Return the node for the local scope containing the given node */
7.341 - public static PythonTree getLocalScope(AstPath path) {
7.342 - for (PythonTree node : path) {
7.343 - if (node instanceof FunctionDef) {
7.344 - return node;
7.345 - }
7.346 - }
7.347 -
7.348 - return path.root();
7.349 - }
7.350 -
7.351 - public static PythonTree getClassScope(AstPath path) {
7.352 - for (PythonTree node : path) {
7.353 - if (node instanceof ClassDef) {
7.354 - return node;
7.355 - }
7.356 - }
7.357 -
7.358 - return path.root();
7.359 - }
7.360 -
7.361 - public static ClassDef getClassDef(AstPath path) {
7.362 - for (PythonTree node : path) {
7.363 - if (node instanceof ClassDef) {
7.364 - return (ClassDef)node;
7.365 - }
7.366 - }
7.367 -
7.368 - return null;
7.369 - }
7.370 -
7.371 - public static boolean isClassMethod(AstPath path, FunctionDef def) {
7.372 - // Check to see if (a) the function is inside a class, and (b) it's
7.373 - // not nested in a function
7.374 - for (PythonTree node : path) {
7.375 - if (node instanceof ClassDef) {
7.376 - return true;
7.377 - }
7.378 - // Nested method private to this one?
7.379 - if (node instanceof FunctionDef && node != def) {
7.380 - return false;
7.381 - }
7.382 - }
7.383 -
7.384 - return false;
7.385 - }
7.386 -
7.387 - public static FunctionDef getFuncDef(AstPath path) {
7.388 - for (PythonTree node : path) {
7.389 - if (node instanceof FunctionDef) {
7.390 - return (FunctionDef)node;
7.391 - }
7.392 - }
7.393 -
7.394 - return null;
7.395 - }
7.396 -
7.397 - /**
7.398 - * Return true iff this call looks like a "getter". If we're not sure,
7.399 - * return the default value passed into this method, unknownDefault.
7.400 - */
7.401 - public static boolean isGetter(Call call, boolean unknownDefault) {
7.402 - String name = PythonAstUtils.getCallName(call);
7.403 - if (name == null) {
7.404 - return unknownDefault;
7.405 - }
7.406 -
7.407 - return name.startsWith("get") || name.startsWith("_get"); // NOI18N
7.408 - }
7.409 -
7.410 - public static String getCallName(Call call) {
7.411 - expr func = call.getInternalFunc();
7.412 -
7.413 - return getExprName(func);
7.414 - }
7.415 -
7.416 - public static String getExprName(expr type) {
7.417 - if (type instanceof Attribute) {
7.418 - Attribute attr = (Attribute)type;
7.419 - return attr.getInternalAttr();
7.420 - } else if (type instanceof Name) {
7.421 - return ((Name)type).getInternalId();
7.422 - } else if (type instanceof Call) {
7.423 - Call call = (Call)type;
7.424 - return getExprName(call.getInternalFunc());
7.425 - //} else if (type instanceof Str) {
7.426 - // return ((Str)type).getText();
7.427 - } else {
7.428 - return null;
7.429 - }
7.430 - }
7.431 -
7.432 - public static String getName(PythonTree node) {
7.433 - if (node instanceof Name) {
7.434 - return ((Name)node).getInternalId();
7.435 - }
7.436 - if (node instanceof Attribute) {
7.437 - Attribute attrib = (Attribute)node;
7.438 - String prefix = getName(attrib.getInternalValue());
7.439 - return (prefix + '.' + attrib.getInternalAttr());
7.440 - }
7.441 - NameVisitor visitor = new NameVisitor();
7.442 - try {
7.443 - Object result = visitor.visit(node);
7.444 - if (result instanceof String) {
7.445 - return (String)result;
7.446 - } else {
7.447 - // TODO HANDLE THIS!
7.448 - }
7.449 - } catch (Exception ex) {
7.450 - Exceptions.printStackTrace(ex);
7.451 - }
7.452 -
7.453 - return null;
7.454 - }
7.455 -
7.456 - public static List<String> getParameters(FunctionDef def) {
7.457 - arguments args = def.getInternalArgs();
7.458 - List<String> params = new ArrayList<>();
7.459 -
7.460 - NameVisitor visitor = new NameVisitor();
7.461 -
7.462 - for (expr e : args.getInternalArgs()) {
7.463 - try {
7.464 - Object result = visitor.visit(e);
7.465 - if (result instanceof String) {
7.466 - params.add((String)result);
7.467 - } else {
7.468 - // TODO HANDLE THIS!
7.469 - }
7.470 - } catch (Exception ex) {
7.471 - Exceptions.printStackTrace(ex);
7.472 - }
7.473 - }
7.474 -
7.475 - String vararg = args.getInternalVararg();
7.476 - if (vararg != null) {
7.477 - params.add(vararg);
7.478 - }
7.479 - String kwarg = args.getInternalKwarg();
7.480 - if (kwarg != null) {
7.481 - params.add(kwarg);
7.482 - }
7.483 -
7.484 - return params;
7.485 - }
7.486 -
7.487 - private static Str searchForDocNode(stmt stmt) {
7.488 - if (stmt instanceof Expr) {
7.489 - Expr expr = (Expr)stmt;
7.490 - expr value = expr.getInternalValue();
7.491 - if (value instanceof Str) {
7.492 - return (Str)value;
7.493 - }
7.494 - }
7.495 -
7.496 - return null;
7.497 - }
7.498 -
7.499 - public static Str getDocumentationNode(PythonTree node) {
7.500 - // DocString processing.
7.501 - // See http://www.python.org/dev/peps/pep-0257/
7.502 -
7.503 - // For modules, it's the first Str in the document.
7.504 - // For classes and methods, it's the first Str in the object.
7.505 - // For others, nothing.
7.506 -
7.507 - if (node instanceof FunctionDef) {
7.508 - // Function
7.509 - FunctionDef def = (FunctionDef)node;
7.510 - List<stmt> body = def.getInternalBody();
7.511 - if (body != null && body.size() > 0) {
7.512 - return searchForDocNode(body.get(0));
7.513 - }
7.514 - } else if (node instanceof ClassDef) {
7.515 - // Class
7.516 - ClassDef def = (ClassDef)node;
7.517 - List<stmt> body = def.getInternalBody();
7.518 - if (body != null && body.size() > 0) {
7.519 - return searchForDocNode(body.get(0));
7.520 - }
7.521 - } else if (node instanceof Module) {
7.522 - // Module
7.523 - Module module = (Module)node;
7.524 - List<stmt> body = module.getInternalBody();
7.525 - if (body != null && body.size() > 0) {
7.526 - return searchForDocNode(body.get(0));
7.527 - }
7.528 - }
7.529 - // TODO: As per http://www.python.org/dev/peps/pep-0257/ I should
7.530 - // also look for "additional docstrings" (Str node following a Str node)
7.531 - // and Assign str nodes
7.532 -
7.533 - return null;
7.534 - }
7.535 -
7.536 - public static String getStrContent(Str str) {
7.537 - String doc = str.getText();
7.538 -
7.539 - // Strip quotes
7.540 - // and U and/or R for unicode/raw string. U must always preceede r if present.
7.541 - if (doc.startsWith("ur") || doc.startsWith("UR") || // NOI18N
7.542 - doc.startsWith("Ur") || doc.startsWith("uR")) { // NOI18N
7.543 - doc = doc.substring(2);
7.544 - } else if (doc.startsWith("r") || doc.startsWith("u") || // NOI18N
7.545 - doc.startsWith("R") || doc.startsWith("U")) { // NOI18N
7.546 - doc = doc.substring(1);
7.547 - }
7.548 -
7.549 - if (doc.startsWith("\"\"\"") && doc.endsWith("\"\"\"")) { // NOI18N
7.550 - doc = doc.substring(3, doc.length() - 3);
7.551 - } else if (doc.startsWith("r\"\"\"") && doc.endsWith("\"\"\"")) { // NOI18N
7.552 - doc = doc.substring(4, doc.length() - 3);
7.553 - } else if (doc.startsWith("'''") && doc.endsWith("'''")) { // NOI18N
7.554 - doc = doc.substring(3, doc.length() - 3);
7.555 - } else if (doc.startsWith("r'''") && doc.endsWith("'''")) { // NOI18N
7.556 - doc = doc.substring(4, doc.length() - 3);
7.557 - } else if (doc.startsWith("\"") && doc.endsWith("\"")) { // NOI18N
7.558 - doc = doc.substring(1, doc.length() - 1);
7.559 - } else if (doc.startsWith("'") && doc.endsWith("'")) { // NOI18N
7.560 - doc = doc.substring(1, doc.length() - 1);
7.561 - }
7.562 -
7.563 - return doc;
7.564 - }
7.565 -
7.566 - public static String getDocumentation(PythonTree node) {
7.567 - Str str = getDocumentationNode(node);
7.568 - if (str != null) {
7.569 - return getStrContent(str);
7.570 - }
7.571 -
7.572 - return null;
7.573 - }
7.574 -
7.575 - public static PythonTree getForeignNode(final IndexedElement o, PythonParserResult[] parserResultRet) {
7.576 - FileObject fo = o.getFileObject();
7.577 -
7.578 - if (fo == null) {
7.579 - return null;
7.580 - }
7.581 -
7.582 - Source source = Source.create(fo);
7.583 - if(source == null) {
7.584 - return null;
7.585 - }
7.586 - final PythonParserResult[] resultHolder = new PythonParserResult[1];
7.587 - try {
7.588 - ParserManager.parse(Collections.singleton(source), new UserTask() {
7.589 -
7.590 - @Override
7.591 - public void run(ResultIterator resultIterator) throws Exception {
7.592 - resultHolder[0] = (PythonParserResult) resultIterator.getParserResult();
7.593 - }
7.594 - });
7.595 - } catch (ParseException ex) {
7.596 - Exceptions.printStackTrace(ex);
7.597 - }
7.598 -
7.599 - PythonParserResult info = resultHolder[0];
7.600 - if (parserResultRet != null) {
7.601 - parserResultRet[0] = info;
7.602 - }
7.603 - PythonParserResult result = getParseResult(info);
7.604 - if (result == null) {
7.605 - return null;
7.606 - }
7.607 -
7.608 - PythonTree root = getRoot(result);
7.609 - if (root == null) {
7.610 - return null;
7.611 - }
7.612 -
7.613 - if (o.getKind() == ElementKind.MODULE && root instanceof Module) {
7.614 - return root;
7.615 - }
7.616 -
7.617 - String signature = o.getSignature();
7.618 -
7.619 - if (signature == null) {
7.620 - return null;
7.621 - }
7.622 -
7.623 - SymbolTable symbolTable = result.getSymbolTable();
7.624 - SymInfo sym = symbolTable.findBySignature(o.getKind(), signature);
7.625 - if (sym != null && sym.node != null) {
7.626 - // Temporary diagnostic checking
7.627 - //assert ((o.getKind() != ElementKind.CONSTRUCTOR && o.getKind() != ElementKind.METHOD) ||
7.628 - // sym.node instanceof FunctionDef);
7.629 - //assert o.getKind() != ElementKind.CLASS || sym.node instanceof ClassDef;
7.630 -
7.631 - return sym.node;
7.632 - }
7.633 -
7.634 - // TODO - check args etc.
7.635 -// String name = o.getName();
7.636 -// boolean lookForFunction = o.getKind() == ElementKind.CONSTRUCTOR || o.getKind() == ElementKind.METHOD;
7.637 -// if (lookForFunction) {
7.638 -// for (AstElement element : result.getStructure().getElements()) {
7.639 -// if (element.getName().equals(name) && element.getSignature().equals(signature)) {
7.640 -// return element.getNode();
7.641 -// }
7.642 -// }
7.643 -// }
7.644 -// }
7.645 -
7.646 - ElementKind kind = o.getKind();
7.647 - List<PythonStructureItem> items = PythonStructureScanner.analyze(info).getElements();
7.648 - if (items != null) {
7.649 - return find(items, signature, kind);
7.650 - } else {
7.651 - return null;
7.652 - }
7.653 - }
7.654 -
7.655 - private static PythonTree find(List<? extends StructureItem> items, String signature, ElementKind kind) {
7.656 - for (StructureItem item : items) {
7.657 - ElementKind childKind = item.getKind();
7.658 - if (childKind == kind &&
7.659 - item instanceof PythonStructureItem &&
7.660 - signature.equals(((PythonStructureItem)item).getSignature())) {
7.661 - return ((PythonStructureItem)item).getNode();
7.662 - }
7.663 - if (childKind == ElementKind.CLASS && signature.contains(item.getName())) {
7.664 - @SuppressWarnings("unchecked")
7.665 - List<? extends StructureItem> children = item.getNestedItems();
7.666 - PythonTree result = find(children, signature, kind);
7.667 - if (result != null) {
7.668 - return result;
7.669 - }
7.670 - }
7.671 - }
7.672 -
7.673 - return null;
7.674 - }
7.675 -
7.676 - public static Set<OffsetRange> getAllOffsets(PythonParserResult info, AstPath path, int lexOffset, String name, boolean abortOnFree) {
7.677 - if (path == null) {
7.678 - path = AstPath.get(PythonAstUtils.getRoot(info), lexOffset);
7.679 - }
7.680 - PythonTree scope = PythonAstUtils.getLocalScope(path);
7.681 - SymbolTable symbolTable = PythonAstUtils.getParseResult(info).getSymbolTable();
7.682 - List<PythonTree> nodes = symbolTable.getOccurrences(scope, name, abortOnFree);
7.683 - if (nodes == null) {
7.684 - return null;
7.685 - }
7.686 - Set<OffsetRange> offsets = new HashSet<>();
7.687 - Document doc = GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false);
7.688 - if (doc == null) {
7.689 - return Collections.emptySet();
7.690 - }
7.691 - for (PythonTree node : nodes) {
7.692 - OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
7.693 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
7.694 -
7.695 - if (node instanceof Import || node instanceof ImportFrom) {
7.696 - // Try to find the exact spot
7.697 - if (abortOnFree) {
7.698 - return null;
7.699 - } else {
7.700 - lexRange = PythonLexerUtils.getImportNameOffset((BaseDocument)doc, lexRange, node, name);
7.701 - }
7.702 - } else if (abortOnFree && (node instanceof FunctionDef || node instanceof ClassDef)) {
7.703 - return null;
7.704 - }
7.705 -
7.706 - if (lexRange != OffsetRange.NONE) {
7.707 - offsets.add(lexRange);
7.708 - }
7.709 - }
7.710 - // Look for type variables
7.711 - ScopeInfo scopeInfo = symbolTable.getScopeInfo(scope);
7.712 - if (scopeInfo != null) {
7.713 - SymInfo sym = scopeInfo.tbl.get(name);
7.714 - if (sym != null && sym.isVariable(false)) {
7.715 - // Look for type declarations that can apply to this variable
7.716 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, PythonAstUtils.getRange(scope));
7.717 - if (lexRange != OffsetRange.NONE) {
7.718 - BaseDocument bdoc = (BaseDocument)doc;
7.719 - try {
7.720 - bdoc.readLock(); // For TokenHierarchy usage
7.721 - TokenHierarchy hi = TokenHierarchy.get(doc);
7.722 - LanguagePath languagePath = LanguagePath.get(LanguagePath.get(PythonTokenId.language()), PythonCommentTokenId.language());
7.723 - int startOffset = Math.min(lexRange.getStart(), doc.getLength());
7.724 - if (scope instanceof Module) {
7.725 - startOffset = 0; // Pick up comments before code starts
7.726 - }
7.727 - int endOffset = Math.min(lexRange.getEnd(), doc.getLength());
7.728 - @SuppressWarnings("unchecked")
7.729 - List<TokenSequence<? extends PythonCommentTokenId>> tsl = hi.tokenSequenceList(languagePath, startOffset, endOffset);
7.730 - for (TokenSequence<? extends PythonCommentTokenId> ts : tsl) {
7.731 - ts.moveStart();
7.732 - while (ts.moveNext()) {
7.733 - PythonCommentTokenId id = ts.token().id();
7.734 - if (id == PythonCommentTokenId.TYPEKEY) {
7.735 - if (ts.moveNext() && // skip separator
7.736 - ts.moveNext()) {
7.737 - if (ts.token().id() == PythonCommentTokenId.VARNAME) {
7.738 - if (TokenUtilities.equals(ts.token().text(), name)) {
7.739 - int start = ts.offset();
7.740 - OffsetRange nameRange = new OffsetRange(start, start + name.length());
7.741 - offsets.add(nameRange);
7.742 - }
7.743 - }
7.744 - }
7.745 - }
7.746 - }
7.747 - }
7.748 - } finally {
7.749 - bdoc.readUnlock();
7.750 - }
7.751 -
7.752 - }
7.753 - }
7.754 - }
7.755 -
7.756 - return offsets;
7.757 - }
7.758 -
7.759 - private static final class NameVisitor extends Visitor {
7.760 - @Override
7.761 - public Object visitName(Name name) throws Exception {
7.762 - return name.getInternalId();
7.763 - }
7.764 - }
7.765 -
7.766 - public static Set<OffsetRange> getLocalVarOffsets(PythonParserResult info, int lexOffset) {
7.767 - int astOffset = getAstOffset(info, lexOffset);
7.768 - if (astOffset != -1) {
7.769 - PythonTree root = getRoot(info);
7.770 - if (root != null) {
7.771 - AstPath path = AstPath.get(root, astOffset);
7.772 - if (path != null) {
7.773 - PythonTree closest = path.leaf();
7.774 - PythonTree scope = getLocalScope(path);
7.775 - String name = ((Name)closest).getInternalId();
7.776 -
7.777 - return getLocalVarOffsets(info, scope, name);
7.778 - }
7.779 - }
7.780 - }
7.781 -
7.782 - return Collections.emptySet();
7.783 - }
7.784 -
7.785 - public static Set<OffsetRange> getLocalVarOffsets(PythonParserResult info, PythonTree scope, String name) {
7.786 - LocalVarVisitor visitor = new LocalVarVisitor(info, name, false, true);
7.787 - try {
7.788 - visitor.visit(scope);
7.789 - return visitor.getOffsets();
7.790 - } catch (Exception ex) {
7.791 - Exceptions.printStackTrace(ex);
7.792 - return Collections.emptySet();
7.793 - }
7.794 - }
7.795 -
7.796 - public static List<Name> getLocalVarNodes(PythonParserResult info, PythonTree scope, String name) {
7.797 - LocalVarVisitor visitor = new LocalVarVisitor(info, name, true, false);
7.798 - try {
7.799 - visitor.visit(scope);
7.800 - return visitor.getVars();
7.801 - } catch (Exception ex) {
7.802 - Exceptions.printStackTrace(ex);
7.803 - return Collections.emptyList();
7.804 - }
7.805 - }
7.806 -
7.807 - public static List<Name> getLocalVarAssignNodes(PythonParserResult info, PythonTree scope, String name) {
7.808 - LocalVarAssignVisitor visitor = new LocalVarAssignVisitor(info, name, true, false);
7.809 - try {
7.810 - visitor.visit(scope);
7.811 - return visitor.getVars();
7.812 - } catch (Exception ex) {
7.813 - Exceptions.printStackTrace(ex);
7.814 - return Collections.emptyList();
7.815 - }
7.816 - }
7.817 -
7.818 - private static class LocalVarVisitor extends Visitor {
7.819 - private List<Name> vars = new ArrayList<>();
7.820 - private Set<OffsetRange> offsets = new HashSet<>();
7.821 - private String name;
7.822 - private PythonParserResult info;
7.823 - private boolean collectNames;
7.824 - private boolean collectOffsets;
7.825 - private PythonTree parent;
7.826 -
7.827 - private LocalVarVisitor(PythonParserResult info, String name, boolean collectNames, boolean collectOffsets) {
7.828 - this.info = info;
7.829 - this.name = name;
7.830 - this.collectNames = collectNames;
7.831 - this.collectOffsets = collectOffsets;
7.832 - }
7.833 -
7.834 - @Override
7.835 - public void traverse(PythonTree node) throws Exception {
7.836 - PythonTree oldParent = parent;
7.837 - parent = node;
7.838 - super.traverse(node);
7.839 - parent = oldParent;
7.840 - }
7.841 -
7.842 - @Override
7.843 - public Object visitName(Name node) throws Exception {
7.844 - if (parent instanceof Call && ((Call)parent).getInternalFunc() == node) {
7.845 - return super.visitName(node);
7.846 - }
7.847 -
7.848 - if ((name == null && !PythonUtils.isClassName(node.getInternalId(), false)) ||
7.849 - (name != null && name.equals(node.getInternalId()))) {
7.850 - if (collectOffsets) {
7.851 - OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
7.852 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
7.853 - if (lexRange != OffsetRange.NONE) {
7.854 - offsets.add(astRange);
7.855 - }
7.856 - }
7.857 - if (collectNames) {
7.858 - vars.add(node);
7.859 - }
7.860 - }
7.861 -
7.862 - return super.visitName(node);
7.863 - }
7.864 -
7.865 - public Set<OffsetRange> getOffsets() {
7.866 - return offsets;
7.867 - }
7.868 -
7.869 - public List<Name> getVars() {
7.870 - return vars;
7.871 - }
7.872 - }
7.873 -
7.874 - private static class LocalVarAssignVisitor extends Visitor {
7.875 - private List<Name> vars = new ArrayList<>();
7.876 - private Set<OffsetRange> offsets = new HashSet<>();
7.877 - private String name;
7.878 - private PythonParserResult info;
7.879 - private boolean collectNames;
7.880 - private boolean collectOffsets;
7.881 - private PythonTree parent;
7.882 -
7.883 - private LocalVarAssignVisitor(PythonParserResult info, String name, boolean collectNames, boolean collectOffsets) {
7.884 - this.info = info;
7.885 - this.name = name;
7.886 - this.collectNames = collectNames;
7.887 - this.collectOffsets = collectOffsets;
7.888 - }
7.889 -
7.890 - @Override
7.891 - public Object visitName(Name node) throws Exception {
7.892 - if (parent instanceof FunctionDef || parent instanceof Assign) {
7.893 - if ((name == null && !PythonUtils.isClassName(node.getInternalId(), false)) ||
7.894 - (name != null && name.equals(node.getInternalId()))) {
7.895 - if (collectOffsets) {
7.896 - OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
7.897 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
7.898 - if (lexRange != OffsetRange.NONE) {
7.899 - offsets.add(astRange);
7.900 - }
7.901 - }
7.902 - if (collectNames) {
7.903 - vars.add(node);
7.904 - }
7.905 - }
7.906 - }
7.907 -
7.908 - return super.visitName(node);
7.909 - }
7.910 -
7.911 - @Override
7.912 - public void traverse(PythonTree node) throws Exception {
7.913 - PythonTree oldParent = parent;
7.914 - parent = node;
7.915 - super.traverse(node);
7.916 - parent = oldParent;
7.917 - }
7.918 -
7.919 - public Set<OffsetRange> getOffsets() {
7.920 - return offsets;
7.921 - }
7.922 -
7.923 - public List<Name> getVars() {
7.924 - return vars;
7.925 - }
7.926 - }
7.927 -
7.928 - /** Collect nodes of the given types (node.nodeId==NodeTypes.x) under the given root */
7.929 - public static void addNodesByType(PythonTree root, Class[] nodeClasses, List<PythonTree> result) {
7.930 - try {
7.931 - new NodeTypeVisitor(result, nodeClasses).visit(root);
7.932 - } catch (Exception ex) {
7.933 - Exceptions.printStackTrace(ex);
7.934 - }
7.935 - }
7.936 -
7.937 - private static class NodeTypeVisitor extends Visitor {
7.938 - private Class[] nodeClasses;
7.939 - private List<PythonTree> result;
7.940 -
7.941 - NodeTypeVisitor(List<PythonTree> result, Class[] nodeClasses) {
7.942 - this.result = result;
7.943 - this.nodeClasses = nodeClasses;
7.944 - }
7.945 -
7.946 - @Override
7.947 - public void traverse(PythonTree node) throws Exception {
7.948 - for (Class nodeClasse : nodeClasses) {
7.949 - if (node.getClass() == nodeClasse) {
7.950 - result.add(node);
7.951 - break;
7.952 - }
7.953 - }
7.954 -
7.955 - super.traverse(node);
7.956 - }
7.957 - }
7.958 -
7.959 - public static Name getParentClassFromNode(AstPath path, PythonTree from, String name) {
7.960 - ClassDef curClass = (ClassDef)path.getTypedAncestor(ClassDef.class, from);
7.961 - if (curClass == null) {
7.962 - return null;
7.963 - }
7.964 -
7.965 - List<expr> baseClasses = curClass.getInternalBases();
7.966 - if (baseClasses == null) {
7.967 - return null; // no inheritance ;
7.968 - }
7.969 - int ii = 0;
7.970 - while (ii < baseClasses.size()) {
7.971 - if (baseClasses.get(ii) instanceof Name) {
7.972 - Name cur = (Name)baseClasses.get(ii);
7.973 - if (cur.getInternalId().equals(name)) {
7.974 - return cur;
7.975 - }
7.976 - }
7.977 - ii++;
7.978 - }
7.979 - return null;
7.980 - }
7.981 -
7.982 - /**
7.983 - * Look for the caret offset in the parameter list; return the
7.984 - * index of the parameter that contains it.
7.985 - */
7.986 - public static int findArgumentIndex(Call call, int astOffset, AstPath path) {
7.987 -
7.988 - // On the name part in the call rather than the args?
7.989 - if (astOffset <= call.getInternalFunc().getCharStopIndex()) {
7.990 - return -1;
7.991 - }
7.992 - List<expr> args = call.getInternalArgs();
7.993 - if (args != null) {
7.994 - int index = 0;
7.995 - for (; index < args.size(); index++) {
7.996 - expr et = args.get(index);
7.997 - if (et.getCharStopIndex() >= astOffset) {
7.998 - return index;
7.999 - }
7.1000 - }
7.1001 - }
7.1002 -
7.1003 - // TODO what about the other stuff in there --
7.1004 - //call.keywords;
7.1005 - //call.kwargs;
7.1006 - //call.starargs;
7.1007 -
7.1008 - return -1;
7.1009 - }
7.1010 -}
8.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonCodeCompleter.java Fri Sep 18 16:20:24 2015 -0500
8.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonCodeCompleter.java Mon Sep 21 13:01:16 2015 +0200
8.3 @@ -30,6 +30,12 @@
8.4 */
8.5 package org.netbeans.modules.python.editor;
8.6
8.7 +import org.netbeans.modules.python.source.PythonUtils;
8.8 +import org.netbeans.modules.python.source.AstPath;
8.9 +import org.netbeans.modules.python.source.PythonIndex;
8.10 +import org.netbeans.modules.python.source.RstFormatter;
8.11 +import org.netbeans.modules.python.source.PythonAstUtils;
8.12 +import org.netbeans.modules.python.source.PythonParserResult;
8.13 import java.util.ArrayList;
8.14 import java.util.Collections;
8.15 import java.util.HashSet;
8.16 @@ -45,12 +51,12 @@
8.17 import javax.swing.text.JTextComponent;
8.18 import org.netbeans.api.editor.EditorRegistry;
8.19 import org.netbeans.api.editor.completion.Completion;
8.20 -import org.netbeans.modules.python.editor.elements.Element;
8.21 -import org.netbeans.modules.python.editor.elements.IndexedElement;
8.22 -import org.netbeans.modules.python.editor.elements.IndexedMethod;
8.23 -import org.netbeans.modules.python.editor.lexer.Call;
8.24 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
8.25 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
8.26 +import org.netbeans.modules.python.source.elements.Element;
8.27 +import org.netbeans.modules.python.source.elements.IndexedElement;
8.28 +import org.netbeans.modules.python.source.elements.IndexedMethod;
8.29 +import org.netbeans.modules.python.source.lexer.Call;
8.30 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
8.31 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
8.32 import org.netbeans.api.lexer.Token;
8.33 import org.netbeans.api.lexer.TokenHierarchy;
8.34 import org.netbeans.api.lexer.TokenId;
8.35 @@ -74,13 +80,13 @@
8.36 import org.netbeans.modules.editor.indent.api.IndentUtils;
8.37 import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
8.38 import org.netbeans.modules.python.api.PythonMIMEResolver;
8.39 -import org.netbeans.modules.python.editor.PythonParser.Sanitize;
8.40 -import org.netbeans.modules.python.editor.elements.IndexedPackage;
8.41 -import org.netbeans.modules.python.editor.imports.ImportManager;
8.42 -import org.netbeans.modules.python.editor.lexer.PythonCommentTokenId;
8.43 -import org.netbeans.modules.python.editor.lexer.PythonLexer;
8.44 -import org.netbeans.modules.python.editor.options.CodeStyle;
8.45 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
8.46 +import org.netbeans.modules.python.source.PythonParser.Sanitize;
8.47 +import org.netbeans.modules.python.source.elements.IndexedPackage;
8.48 +import org.netbeans.modules.python.source.ImportManager;
8.49 +import org.netbeans.modules.python.source.lexer.PythonCommentTokenId;
8.50 +import org.netbeans.modules.python.source.lexer.PythonLexer;
8.51 +import org.netbeans.modules.python.source.CodeStyle;
8.52 +import org.netbeans.modules.python.source.scopes.SymbolTable;
8.53 import org.openide.filesystems.FileObject;
8.54 import org.openide.util.Exceptions;
8.55 import org.openide.util.ImageUtilities;
8.56 @@ -305,8 +311,8 @@
8.57 return completionResult;
8.58 }
8.59
8.60 - org.netbeans.modules.python.editor.lexer.Call call =
8.61 - org.netbeans.modules.python.editor.lexer.Call.getCallType(doc, th, lexOffset);
8.62 + org.netbeans.modules.python.source.lexer.Call call =
8.63 + org.netbeans.modules.python.source.lexer.Call.getCallType(doc, th, lexOffset);
8.64 request.call = call;
8.65
8.66 if ((fqn != null) &&
8.67 @@ -1088,7 +1094,7 @@
8.68 PythonParserResult info = request.result;
8.69 String prefix = request.prefix;
8.70 QuerySupport.Kind kind = request.kind;
8.71 - org.netbeans.modules.python.editor.lexer.Call call = request.call;
8.72 + org.netbeans.modules.python.source.lexer.Call call = request.call;
8.73
8.74 // Only call local and inherited methods if we don't have an LHS, such as Foo::
8.75 if (call.getLhs() == null) {
8.76 @@ -1187,7 +1193,7 @@
8.77 * @todo Look for self or this or super; these should be limited to inherited.
8.78 */
8.79 private boolean completeObjectMethod(List<CompletionProposal> proposals, CompletionRequest request, String fqn,
8.80 - org.netbeans.modules.python.editor.lexer.Call call) {
8.81 + org.netbeans.modules.python.source.lexer.Call call) {
8.82
8.83 PythonIndex index = request.index;
8.84 String prefix = request.prefix;
8.85 @@ -1211,8 +1217,8 @@
8.86 if ((index != null) && (ts != null)) {
8.87 boolean skipPrivate = true;
8.88
8.89 - if ((call == org.netbeans.modules.python.editor.lexer.Call.LOCAL) ||
8.90 - (call == org.netbeans.modules.python.editor.lexer.Call.NONE)) {
8.91 + if ((call == org.netbeans.modules.python.source.lexer.Call.LOCAL) ||
8.92 + (call == org.netbeans.modules.python.source.lexer.Call.NONE)) {
8.93 return false;
8.94 }
8.95
8.96 @@ -1563,6 +1569,41 @@
8.97
8.98 return true;
8.99 }
8.100 +
8.101 + // Keywords - according to http://docs.python.org/ref/keywords.html
8.102 + static final String[] PYTHON_KEYWORDS = new String[]{
8.103 + "and", // NOI18N
8.104 + "as", // NOI18N
8.105 + "assert", // NOI18N
8.106 + "break", // NOI18N
8.107 + "class", // NOI18N
8.108 + "continue", // NOI18N
8.109 + "def", // NOI18N
8.110 + "del", // NOI18N
8.111 + "elif", // NOI18N
8.112 + "else", // NOI18N
8.113 + "except", // NOI18N
8.114 + "exec", // NOI18N
8.115 + "finally", // NOI18N
8.116 + "for", // NOI18N
8.117 + "from", // NOI18N
8.118 + "global", // NOI18N
8.119 + "if", // NOI18N
8.120 + "import", // NOI18N
8.121 + "in", // NOI18N
8.122 + "is", // NOI18N
8.123 + "lambda", // NOI18N
8.124 + "not", // NOI18N
8.125 + "or", // NOI18N
8.126 + "pass", // NOI18N
8.127 + "print", // NOI18N
8.128 + "raise", // NOI18N
8.129 + "return", // NOI18N
8.130 + "try", // NOI18N
8.131 + "while", // NOI18N
8.132 + "with", // NOI18N
8.133 + "yield", // NOI18N
8.134 + };
8.135
8.136 private void completeKeywords(List<CompletionProposal> proposals, CompletionRequest request) {
8.137 // No keywords possible in the RHS of a call (except for "this"?)
8.138 @@ -1573,8 +1614,8 @@
8.139 String prefix = request.prefix;
8.140
8.141
8.142 - for (int i = 0, n = PythonUtils.PYTHON_KEYWORDS.length; i < n; i++) {
8.143 - String keyword = PythonUtils.PYTHON_KEYWORDS[i];
8.144 + for (int i = 0, n = PYTHON_KEYWORDS.length; i < n; i++) {
8.145 + String keyword = PYTHON_KEYWORDS[i];
8.146 if (startsWith(keyword, prefix)) {
8.147 KeywordItem item = new KeywordItem(keyword, null, request, Integer.toString(10000 + i));
8.148
8.149 @@ -1830,7 +1871,7 @@
8.150 private PythonParserResult result;
8.151 private QueryType queryType;
8.152 private FileObject fileObject;
8.153 - private org.netbeans.modules.python.editor.lexer.Call call;
8.154 + private org.netbeans.modules.python.source.lexer.Call call;
8.155 private boolean inCall;
8.156 private String fqn;
8.157 private String searchUrl;
8.158 @@ -2601,7 +2642,7 @@
8.159
8.160 if (item instanceof PythonCompletionItem) {
8.161 PythonCompletionItem pythonItem = (PythonCompletionItem)item;
8.162 - org.netbeans.modules.python.editor.lexer.Call call = pythonItem.request.call;
8.163 + org.netbeans.modules.python.source.lexer.Call call = pythonItem.request.call;
8.164 // Only insert imports when we add new top-level items
8.165 if (pythonItem.getAddImport() != null) {
8.166 String module = pythonItem.getAddImport();
9.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonDeclarationFinder.java Fri Sep 18 16:20:24 2015 -0500
9.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonDeclarationFinder.java Mon Sep 21 13:01:16 2015 +0200
9.3 @@ -30,6 +30,11 @@
9.4 */
9.5 package org.netbeans.modules.python.editor;
9.6
9.7 +import org.netbeans.modules.python.source.PythonUtils;
9.8 +import org.netbeans.modules.python.source.AstPath;
9.9 +import org.netbeans.modules.python.source.PythonIndex;
9.10 +import org.netbeans.modules.python.source.PythonAstUtils;
9.11 +import org.netbeans.modules.python.source.PythonParserResult;
9.12 import java.net.MalformedURLException;
9.13 import java.net.URL;
9.14 import java.util.Collections;
9.15 @@ -38,11 +43,11 @@
9.16 import java.util.Set;
9.17 import javax.swing.text.BadLocationException;
9.18 import javax.swing.text.Document;
9.19 -import org.netbeans.modules.python.editor.elements.IndexedElement;
9.20 -import org.netbeans.modules.python.editor.elements.IndexedMethod;
9.21 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
9.22 -import org.netbeans.modules.python.editor.lexer.PythonStringTokenId;
9.23 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
9.24 +import org.netbeans.modules.python.source.elements.IndexedElement;
9.25 +import org.netbeans.modules.python.source.elements.IndexedMethod;
9.26 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
9.27 +import org.netbeans.modules.python.source.lexer.PythonStringTokenId;
9.28 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
9.29 import org.netbeans.api.lexer.Token;
9.30 import org.netbeans.api.lexer.TokenHierarchy;
9.31 import org.netbeans.api.lexer.TokenId;
9.32 @@ -57,9 +62,9 @@
9.33 import org.netbeans.modules.csl.api.OffsetRange;
9.34 import org.netbeans.modules.csl.spi.ParserResult;
9.35 import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
9.36 -import org.netbeans.modules.python.editor.lexer.PythonLexer;
9.37 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
9.38 -import org.netbeans.modules.python.editor.scopes.SymInfo;
9.39 +import org.netbeans.modules.python.source.lexer.PythonLexer;
9.40 +import org.netbeans.modules.python.source.scopes.SymbolTable;
9.41 +import org.netbeans.modules.python.source.scopes.SymInfo;
9.42 import org.openide.filesystems.FileObject;
9.43 import org.openide.filesystems.FileStateInvalidException;
9.44 import org.openide.util.Exceptions;
9.45 @@ -406,8 +411,8 @@
9.46 }
9.47
9.48 final TokenHierarchy<Document> th = TokenHierarchy.get(document);
9.49 - org.netbeans.modules.python.editor.lexer.Call call =
9.50 - org.netbeans.modules.python.editor.lexer.Call.getCallType(doc, th, lexOffset);
9.51 + org.netbeans.modules.python.source.lexer.Call call =
9.52 + org.netbeans.modules.python.source.lexer.Call.getCallType(doc, th, lexOffset);
9.53
9.54 FileObject fileObject = info.getSnapshot().getSource().getFileObject();
9.55
10.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonExample.py Fri Sep 18 16:20:24 2015 -0500
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,10 +0,0 @@
10.4 -"""Sample Module"""
10.5 -import foo
10.6 -CONSTANT = "VALUE"
10.7 -
10.8 -class Foo(Bar):
10.9 - """Class doc"""
10.10 -
10.11 - def __init__(self,args=''):
10.12 - # Comment
10.13 - print 1+2.0
11.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonFormatter.java Fri Sep 18 16:20:24 2015 -0500
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,657 +0,0 @@
11.4 -/*
11.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
11.6 - *
11.7 - * Copyright 2010 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 2008 Sun Microsystems, Inc.
11.44 - */
11.45 -package org.netbeans.modules.python.editor;
11.46 -
11.47 -import java.util.ArrayList;
11.48 -import java.util.Collections;
11.49 -import java.util.HashMap;
11.50 -import java.util.List;
11.51 -import java.util.Map;
11.52 -import javax.swing.text.BadLocationException;
11.53 -import javax.swing.text.Document;
11.54 -import javax.swing.text.JTextComponent;
11.55 -import org.netbeans.api.editor.EditorRegistry;
11.56 -import org.netbeans.api.lexer.TokenSequence;
11.57 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
11.58 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
11.59 -import org.netbeans.api.lexer.Token;
11.60 -import org.netbeans.api.lexer.TokenId;
11.61 -import org.netbeans.api.lexer.TokenUtilities;
11.62 -import org.netbeans.editor.BaseDocument;
11.63 -import org.netbeans.editor.Utilities;
11.64 -import org.netbeans.modules.csl.api.EditList;
11.65 -import org.netbeans.modules.csl.api.Formatter;
11.66 -import org.netbeans.modules.csl.spi.GsfUtilities;
11.67 -import org.netbeans.modules.csl.spi.ParserResult;
11.68 -import org.netbeans.modules.editor.indent.api.IndentUtils;
11.69 -import org.netbeans.modules.editor.indent.spi.Context;
11.70 -import org.netbeans.modules.python.editor.imports.ImportManager;
11.71 -import org.netbeans.modules.python.editor.options.CodeStyle;
11.72 -import org.openide.util.Exceptions;
11.73 -
11.74 -/**
11.75 - * Implement formatting for Python. Since there are no {}'s etc. to uniquely
11.76 - * impose indentation on Python, this formatter really just tries to enforce
11.77 - * spaces-versus-tabs, and indentation width. E.g. it uses the existing indentation
11.78 - * to determine whether the next line should be idented more, same or less as the
11.79 - * current line and then enforces the current space and indent size settings.
11.80 - *
11.81 - * @todo Implement pretty printing: inserting newlines, removing spaces inside
11.82 - * parentheses, etc. See the recommendations in
11.83 - * http://www.python.org/dev/peps/pep-0008/
11.84 - * Do import statement cleanup too.
11.85 - * @todo Line up comment lines (# as a suffix, continued from a previous line)
11.86 - * @todo Handle continuation lines with extra indentation
11.87 - * @todo Line up list initializations better?
11.88 - *
11.89 - * @author Tor Norbye
11.90 - */
11.91 -public class PythonFormatter implements Formatter {
11.92 - private int indentSize;
11.93 - private int continuationIndentSize;
11.94 - private CodeStyle codeStyle;
11.95 -
11.96 - public PythonFormatter() {
11.97 - }
11.98 -
11.99 - public PythonFormatter(CodeStyle codeStyle) {
11.100 - this.codeStyle = codeStyle;
11.101 - }
11.102 -
11.103 - @Override
11.104 - public void reformat(Context context, ParserResult compilationInfo) {
11.105 -
11.106 - // No AST pretty printing yet
11.107 - // I should offer to go and do space insert/removal around commas, parentheses, etc.
11.108 - // as well as balancing long argument lists across lines
11.109 - Document document = context.document();
11.110 - int startOffset = context.startOffset();
11.111 - int endOffset = context.endOffset();
11.112 -
11.113 - reformat(context, document, startOffset, endOffset, (PythonParserResult) compilationInfo);
11.114 - }
11.115 -
11.116 - public void reformat(final Context context, Document document, int startOffset, int endOffset, PythonParserResult info) {
11.117 - if (codeStyle == null) {
11.118 - codeStyle = CodeStyle.getDefault(context.document());
11.119 - }
11.120 - if (info != null && codeStyle != null && codeStyle.formatImports() && !GsfUtilities.isCodeTemplateEditing(document) &&
11.121 - PythonAstUtils.getParseResult(info) != null) {
11.122 - new ImportManager(info, (BaseDocument)document, codeStyle).cleanup(null, startOffset, endOffset, false);
11.123 - }
11.124 -
11.125 - if (codeStyle != null) {
11.126 - cleanup(document, info, startOffset, endOffset);
11.127 - }
11.128 -
11.129 - reindent(context, document, startOffset, endOffset);
11.130 - }
11.131 -
11.132 - @Override
11.133 - public boolean needsParserResult() {
11.134 -// if (SourceUtils.isScanInProgress()) {
11.135 -// return false;
11.136 -// }
11.137 -
11.138 - // If we're going to format imports, then yes, we need the parser result
11.139 - JTextComponent target = EditorRegistry.lastFocusedComponent();
11.140 - if (target != null) {
11.141 - CodeStyle cs = CodeStyle.getDefault(target.getDocument());
11.142 - return cs != null ? cs.formatImports() : false;
11.143 - }
11.144 - return false;
11.145 - }
11.146 -
11.147 - @Override
11.148 - public int indentSize() {
11.149 - // 4 spaces: See http://www.python.org/dev/peps/pep-0008/
11.150 - return 4;
11.151 - }
11.152 -
11.153 - @Override
11.154 - public int hangingIndentSize() {
11.155 - return 4;
11.156 - }
11.157 -
11.158 - // Challenge: Two inconsistently formatted
11.159 - // Idea: Given a list of offsets and indentation, produce a graph (or recurse) where I mark all
11.160 - // siblings the exact same level
11.161 -
11.162 - // Algorithm:
11.163 - // Find smallest indent: That's the top level
11.164 - // Build a graph? Each indent line.
11.165 - //
11.166 - @Override
11.167 - public void reindent(final Context context) {
11.168 - Document document = context.document();
11.169 - int startOffset = context.startOffset();
11.170 - int endOffset = context.endOffset();
11.171 -
11.172 - reindent(context, document, startOffset, endOffset);
11.173 - }
11.174 -
11.175 - @SuppressWarnings("deprecation") // For doc.getFormatter()
11.176 - public void reindent(final Context context, Document document, int startOffset, int endOffset) {
11.177 - endOffset = Math.min(endOffset, document.getLength());
11.178 - startOffset = Math.min(startOffset, endOffset);
11.179 -
11.180 - continuationIndentSize = indentSize = IndentUtils.indentLevelSize(document);
11.181 -
11.182 -
11.183 - final BaseDocument doc = (BaseDocument)document;
11.184 - try {
11.185 - // Plan: Go through the lines, one by one, and compute the indentation levels relative to each other,
11.186 - // then normalize them (except inside strings), then apply!!
11.187 - // Also track whether we are used for newline indentation and if so, do smart bracket stuff
11.188 -
11.189 - // Current indentation for the given line. -1 means that it should be left alone (e.g.
11.190 - // we don't mess with multiline string literals.
11.191 - final List<Integer> offsets = new ArrayList<>();
11.192 -
11.193 - // Current indentation for the given line. -1 means that it should be left alone (e.g.
11.194 - // we don't mess with multiline string literals. Other negative numbers are offsets
11.195 - // pointing at a particular left parenthesis that this line should be aligned with
11.196 - final List<Integer> indentation = new ArrayList<>();
11.197 - final List<Integer> lParenOffsets = new ArrayList<>();
11.198 -
11.199 - try {
11.200 - doc.readLock(); // For token hierarchy usage
11.201 -
11.202 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, startOffset);
11.203 -
11.204 - int currentOffset = Utilities.getRowStart(doc, startOffset);
11.205 - int balance = 0;
11.206 - while (currentOffset <= endOffset) {
11.207 - if (!(Utilities.isRowEmpty(doc, currentOffset) || Utilities.isRowWhite(doc, currentOffset))) {
11.208 - Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, currentOffset);
11.209 - int indent = GsfUtilities.getLineIndent(doc, currentOffset);
11.210 - if (token != null) {
11.211 - if (token.id() == PythonTokenId.STRING_LITERAL || token.id() == PythonTokenId.STRING_END) {
11.212 - indent = -1;
11.213 - }
11.214 - }
11.215 -
11.216 - if (indent != -1) {
11.217 - if (balance <= 0) {
11.218 - indentation.add(indent);
11.219 - offsets.add(currentOffset);
11.220 - } else {
11.221 - assert balance <= lParenOffsets.size();
11.222 - int parenOffset = lParenOffsets.get(lParenOffsets.size()-balance);
11.223 - indentation.add(-parenOffset);
11.224 - offsets.add(currentOffset);
11.225 - }
11.226 - }
11.227 - }
11.228 -
11.229 - // TODO - look up the tokens to make sure we don't have a problem with literal nodes
11.230 -
11.231 - if (currentOffset > doc.getLength()) {
11.232 - break;
11.233 - }
11.234 -
11.235 - // Update the line balance
11.236 - int begin = Utilities.getRowStart(doc, currentOffset);
11.237 - int end = Utilities.getRowEnd(doc, currentOffset);
11.238 -
11.239 - ts.move(begin);
11.240 -
11.241 - if (ts.moveNext()) {
11.242 - do {
11.243 - Token<? extends PythonTokenId> token = ts.token();
11.244 - TokenId id = token.id();
11.245 -
11.246 - if (id == PythonTokenId.LPAREN) {
11.247 - balance++;
11.248 - lParenOffsets.add(ts.offset());
11.249 - } else if (id == PythonTokenId.RPAREN) {
11.250 - balance--;
11.251 - if (!lParenOffsets.isEmpty()) {
11.252 - lParenOffsets.remove(lParenOffsets.size()-1);
11.253 - }
11.254 - }
11.255 - } while (ts.moveNext() && (ts.offset() <= end));
11.256 - }
11.257 -
11.258 - currentOffset = Utilities.getRowEnd(doc, currentOffset) + 1;
11.259 - }
11.260 - } finally {
11.261 - doc.readUnlock();
11.262 - }
11.263 -
11.264 - // Nothing to do
11.265 - if (offsets.size() == 0) {
11.266 - return;
11.267 - }
11.268 -
11.269 - assert indentation.size() == offsets.size();
11.270 -
11.271 - final Map<Integer, Integer> offsetToLevel = new HashMap<>();
11.272 - final Map<Integer,Integer> offsetToIndex = new HashMap<>();
11.273 - List<Integer> parentIndentations = new ArrayList<>();
11.274 - int currentParentIndent = -1;
11.275 - int currentLevel = -1;
11.276 -
11.277 - int firstIndent = indentation.get(0);
11.278 - List<Integer> sorted = new ArrayList<>(indentation);
11.279 - Collections.sort(sorted);
11.280 - // Attempt to shift the computed indentation to fit the right indentation levels
11.281 - // that are currently in the file?
11.282 - int firstNonNeg = 0;
11.283 - for (; firstNonNeg < sorted.size(); firstNonNeg++) {
11.284 - if (sorted.get(firstNonNeg) >= 0) {
11.285 - break;
11.286 - }
11.287 - }
11.288 - boolean shiftToCurrent = true;
11.289 - if (firstIndent > sorted.get(firstNonNeg)) {
11.290 - shiftToCurrent = false;
11.291 - // The start is not at the top level... e.g. we have something like
11.292 - // foo
11.293 - // else
11.294 - // bar
11.295 - // (e.g. we are formatting a fragment of code which doesn't include
11.296 - // the top). Here we need to find the "true" top levels, so we
11.297 - // push levels on to the stack
11.298 - int prev = -1;
11.299 - for (int indent : sorted) {
11.300 - if (prev == indent) {
11.301 - continue;
11.302 - }
11.303 - prev = indent;
11.304 - if (indent < firstIndent) {
11.305 - parentIndentations.add(currentParentIndent);
11.306 - currentParentIndent = indent;
11.307 - currentLevel++;
11.308 - } else {
11.309 - break;
11.310 - }
11.311 - }
11.312 - }
11.313 -
11.314 -
11.315 - // TODO: What if I start in the middle of an expression such that I outdent
11.316 - // more than I indent? I have to build up the index levels if necessary
11.317 - // Go count popping levels
11.318 -
11.319 - for (int i = 0, n = offsets.size(); i < n; i++) {
11.320 - int offset = offsets.get(i);
11.321 - int indent = indentation.get(i);
11.322 - if (indent == -1) {
11.323 - // Leave line alone
11.324 - offsetToLevel.put(offset, -1);
11.325 - continue;
11.326 - }
11.327 - offsetToIndex.put(offset, i);
11.328 -
11.329 - if (indent < 0) {
11.330 - // Want to keep everything the same as the prev, plus delta
11.331 - } else if (indent > currentParentIndent) {
11.332 - // New level
11.333 - currentLevel++;
11.334 - parentIndentations.add(currentParentIndent);
11.335 - currentParentIndent = indent;
11.336 - } else if (indent < currentParentIndent) {
11.337 - while (currentParentIndent > indent) {
11.338 - currentLevel--;
11.339 - if (parentIndentations.size() > 0) {
11.340 - currentParentIndent = parentIndentations.remove(parentIndentations.size() - 1);
11.341 - } else {
11.342 - currentParentIndent = indent;
11.343 - }
11.344 - }
11.345 - }
11.346 -
11.347 - offsetToLevel.put(offset, currentLevel);
11.348 - }
11.349 -
11.350 - // Compute relative shift
11.351 - int firstLineIndent = indentation.get(0);
11.352 - int firstLineLevel = offsetToLevel.get(offsets.get(0));
11.353 - int computedIndent = firstLineLevel * indentSize;
11.354 - final int relativeShift = shiftToCurrent ? computedIndent - firstLineIndent : 0;
11.355 -
11.356 - doc.runAtomic(new Runnable() {
11.357 - @Override
11.358 - public void run() {
11.359 - int[] computedIndents = new int[offsets.size()];
11.360 - // Process backwards so I don't have to worry about updating offsets affected by
11.361 - // indentation changes
11.362 - for (int i = offsets.size() - 1; i >= 0; i--) {
11.363 - int indent = indentation.get(i);
11.364 - if (indent == -1) {
11.365 - // Leave line alone
11.366 - continue;
11.367 - }
11.368 - if (indent >= 0) {
11.369 - int offset = offsets.get(i);
11.370 - int level = offsetToLevel.get(offset);
11.371 - int computedIndent = level * indentSize - relativeShift;
11.372 - if (computedIndent < 0) {
11.373 - computedIndent = 0;
11.374 - }
11.375 - computedIndents[i] =computedIndent;
11.376 - } else {
11.377 - computedIndents[i] = -1;
11.378 - }
11.379 - }
11.380 -
11.381 - for (int i = offsets.size() - 1; i >= 0; i--) {
11.382 - int indent = indentation.get(i);
11.383 - if (indent < -1) {
11.384 - try {
11.385 - // Negative offset pointing to a left parenthesis we should align with
11.386 - int parenOffset = -indent;
11.387 - int lineStart = Utilities.getRowStart(doc, parenOffset);
11.388 - if (lineStart != -1) {
11.389 - int parenLineIndent = computedIndents[offsetToIndex.get(lineStart)];
11.390 - assert parenLineIndent >= 0;
11.391 - int textBegin = Utilities.getRowFirstNonWhite(doc, lineStart);
11.392 - assert textBegin != -1;
11.393 - // Indent to new indentation + text up to paren plus the paren itself
11.394 - int newIndent = parenLineIndent + (parenOffset-textBegin) + 1;
11.395 - computedIndents[i] = newIndent;
11.396 - }
11.397 - } catch (BadLocationException ble) {
11.398 - Exceptions.printStackTrace(ble);
11.399 - }
11.400 - }
11.401 - }
11.402 -
11.403 - // Process backwards so I don't have to worry about updating offsets affected by
11.404 - // indentation changes
11.405 - for (int i = offsets.size() - 1; i >= 0; i--) {
11.406 - int indent = indentation.get(i);
11.407 - if (indent == -1) {
11.408 - // Leave line alone
11.409 - continue;
11.410 - }
11.411 - int offset = offsets.get(i);
11.412 - int computedIndent = computedIndents[i];
11.413 - if (computedIndent < 0) {
11.414 - computedIndent = 0;
11.415 - }
11.416 -
11.417 - if (computedIndent != indent) {
11.418 - try {
11.419 - context.modifyIndent(offset, computedIndent);
11.420 - } catch (BadLocationException ex) {
11.421 - Exceptions.printStackTrace(ex);
11.422 - }
11.423 - }
11.424 - }
11.425 - }
11.426 - });
11.427 - } catch (BadLocationException ble) {
11.428 - Exceptions.printStackTrace(ble);
11.429 - }
11.430 - }
11.431 -
11.432 - private boolean isLinePrefix(BaseDocument doc, int offset) throws BadLocationException {
11.433 - return Utilities.getRowFirstNonWhite(doc, offset) == offset;
11.434 - }
11.435 -
11.436 - private void cleanup(Document document, PythonParserResult info, int startOffset, int endOffset) {
11.437 - BaseDocument doc = (BaseDocument)document;
11.438 - final EditList edits = new EditList(doc);
11.439 - try {
11.440 - doc.readLock(); // For token hierarchy usage
11.441 -
11.442 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, startOffset);
11.443 - if (ts == null) {
11.444 - return;
11.445 - }
11.446 -
11.447 - ts.move(startOffset);
11.448 -
11.449 -
11.450 -
11.451 - // TODO:
11.452 - // Control whether I collapse spaces to a single space, or just ensure there is at least one
11.453 - // "None", "1", "At least 1", "Leave Alone"
11.454 -
11.455 - // TODO: Insert and remove needed or unnecessary parentheses!
11.456 - // TODO: Alignment! Especially of trailing line comments on adjacent lines!
11.457 - // TODO: Collapse blank newlines!
11.458 - boolean addSpaceAroundOperators = true;
11.459 - boolean removeSpaceInsideParens = true; // also applies to braces and brackets
11.460 - boolean addSpaceAfterComma = true;
11.461 - // boolean spaceArondParens = false;
11.462 - // boolean spaceBeforeArgs = false; // before parentheses in a call
11.463 - boolean removeSpaceBeforeSep = true; // before comma, semicolon or colon
11.464 - // boolean alignAssignments = false; // Only one space around assignments
11.465 - boolean removeSpaceInParamAssign = true; // Around assignment in parameter list, e.g.
11.466 - boolean collapseSpaces = true;
11.467 - //def complex(real, imag=0.0):
11.468 - // return magic(r=real, i=imag)
11.469 - if (codeStyle != null) {
11.470 - addSpaceAroundOperators = codeStyle.addSpaceAroundOperators();
11.471 - removeSpaceInsideParens = codeStyle.removeSpaceInsideParens();
11.472 - addSpaceAfterComma = codeStyle.addSpaceAfterComma();
11.473 - removeSpaceBeforeSep = codeStyle.removeSpaceBeforeSep();
11.474 - removeSpaceInParamAssign = codeStyle.removeSpaceInParamAssign();
11.475 - collapseSpaces = codeStyle.collapseSpaces();
11.476 - }
11.477 -
11.478 - // TODO - back up to the nearest function or class or beginning of the document to get the right
11.479 - // parenthesis balance.
11.480 - int parenBalance = 0;
11.481 -
11.482 - Token<? extends PythonTokenId> prev = null;
11.483 - Token<? extends PythonTokenId> token = null;
11.484 - Token<? extends PythonTokenId> next = null;
11.485 - int tokenOffset = 0;
11.486 - int nextOffset = 0;
11.487 - int prevOffset = -1;
11.488 - if (ts.moveNext()) {
11.489 - token = ts.token();
11.490 - tokenOffset = ts.offset();
11.491 - if (ts.moveNext()) {
11.492 - next = ts.token();
11.493 - nextOffset = ts.offset();
11.494 - } else {
11.495 - return;
11.496 - }
11.497 - }
11.498 - boolean prevRemoved = false;
11.499 - boolean tokenRemoved = false;
11.500 - boolean nextRemoved = false;
11.501 - while (token != null) {
11.502 - TokenId prevId = prev != null ? prev.id() : null;
11.503 - TokenId id = token.id();
11.504 - TokenId nextId = next != null ? next.id() : null;
11.505 -
11.506 - if (id == PythonTokenId.LPAREN) {
11.507 - parenBalance++;
11.508 - } else if (id == PythonTokenId.RPAREN) {
11.509 - parenBalance--;
11.510 - }
11.511 -
11.512 - if (removeSpaceInsideParens) {
11.513 - if (id == PythonTokenId.LPAREN) {
11.514 - if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
11.515 - edits.replace(nextOffset, next.length(), null, false, 0);
11.516 - nextRemoved = true;
11.517 - }
11.518 - } else if (id == PythonTokenId.RPAREN) {
11.519 - if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
11.520 - // I don't remove space in front of paren's at the beginning of the line; these might have
11.521 - // been aligned with indented content above
11.522 - edits.replace(prevOffset, prev.length(), null, false, 0);
11.523 - prevRemoved = true;
11.524 - }
11.525 - } else if (id == PythonTokenId.LBRACKET) {
11.526 - if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
11.527 - edits.replace(nextOffset, next.length(), null, false, 0);
11.528 - nextRemoved = true;
11.529 - }
11.530 - } else if (id == PythonTokenId.RBRACKET) {
11.531 - if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
11.532 - edits.replace(prevOffset, prev.length(), null, false, 0);
11.533 - prevRemoved = true;
11.534 - }
11.535 - } else if (id == PythonTokenId.LBRACE) {
11.536 - if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
11.537 - edits.replace(nextOffset, next.length(), null, false, 0);
11.538 - nextRemoved = true;
11.539 - }
11.540 - } else if (id == PythonTokenId.RBRACE) {
11.541 - if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
11.542 - edits.replace(prevOffset, prev.length(), null, false, 0);
11.543 - prevRemoved = true;
11.544 - }
11.545 - }
11.546 - }
11.547 -
11.548 - if (addSpaceAfterComma) {
11.549 - if (id == PythonTokenId.COMMA) {
11.550 - if (collapseSpaces && nextId == PythonTokenId.WHITESPACE && next.length() > 1) {
11.551 - edits.replace(nextOffset, next.length() - 1, null, false, 1); // NOI18N
11.552 - } else if (next == null ||
11.553 - (nextId != PythonTokenId.WHITESPACE && nextId != PythonTokenId.NEWLINE)) {
11.554 - edits.replace(nextOffset, 0, " ", false, 1); // NOI18N
11.555 - }
11.556 - }
11.557 - }
11.558 -
11.559 - if (removeSpaceBeforeSep &&
11.560 - (id == PythonTokenId.COMMA || id == PythonTokenId.COLON ||
11.561 - (id == PythonTokenId.ANY_OPERATOR && TokenUtilities.equals(token.text(), ";"))) && // NOI18N
11.562 - prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
11.563 - edits.replace(prevOffset, prev.length(), null, false, 2);
11.564 - prevRemoved = true;
11.565 - }
11.566 -
11.567 - if (addSpaceAroundOperators && id == PythonTokenId.ANY_OPERATOR) {
11.568 - CharSequence seq = token.text();
11.569 -
11.570 - // These aren't binary, and ; isn't really an operator and has its own setting
11.571 - if (!(TokenUtilities.equals(seq, "@") || // NOI18N
11.572 - TokenUtilities.equals(seq, "`") || // NOI18N
11.573 - TokenUtilities.equals(seq, ";"))) { // NOI18N
11.574 -
11.575 - boolean insertSpace = true;
11.576 - if (removeSpaceInParamAssign && TokenUtilities.equals(seq, "=")) { // NOI18N
11.577 - // Special handling: keyword arguments should typically NOT
11.578 - // have space inserted
11.579 - if (parenBalance > 0) {
11.580 - insertSpace = false;
11.581 - // Remove spaces around the =
11.582 - if (prevId == PythonTokenId.WHITESPACE && !prevRemoved) {
11.583 - edits.replace(prevOffset, prev.length(), null, false, 5); // NOI18N
11.584 - prevRemoved = true;
11.585 - }
11.586 - if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
11.587 - edits.replace(nextOffset, next.length(), null, false, 6); // NOI18N
11.588 - nextRemoved = true;
11.589 - }
11.590 - }
11.591 - }
11.592 -
11.593 - if (insertSpace && TokenUtilities.equals(seq, "-")/* && (nextId == PythonTokenId.FLOAT_LITERAL || nextId == PythonTokenId.INT_LITERAL)*/) {
11.594 - // Leave -'s alone for now. The code is a little unclear on the difference between
11.595 - // x-1 and =-1 etc. For numbers (floating and integer) the minus isn't part of the lexical token for the number;
11.596 - // it's a separate operator. However, it's tricky to tell this apart from the binary subtraction, since it depends
11.597 - // on what came before. For now play it safe an leave these alone.
11.598 - // TODO - implement this properly.
11.599 - insertSpace = false;
11.600 - }
11.601 -
11.602 - if (insertSpace && TokenUtilities.equals(seq, "*")) { // NOI18N
11.603 - // "*" in (*foo) doesn't mean multiplication; it's not a binary operator here,
11.604 - // it's many args.
11.605 - if (prevId == PythonTokenId.COMMA || prevId == PythonTokenId.LPAREN) {
11.606 - insertSpace = false;
11.607 - }
11.608 - }
11.609 -
11.610 - if (insertSpace) {
11.611 - // Ensure that we have space on both sides
11.612 - if (collapseSpaces && prevId == PythonTokenId.WHITESPACE && next.length() > 1 &&
11.613 - !isLinePrefix(doc, tokenOffset)) {
11.614 - edits.replace(prevOffset, prev.length() - 1, null, false, 1); // NOI18N
11.615 - } else if (prevId != PythonTokenId.WHITESPACE) {
11.616 - edits.replace(tokenOffset, 0, " ", false, 3); // NOI18N
11.617 - }
11.618 -
11.619 - if (collapseSpaces && nextId == PythonTokenId.WHITESPACE && next.length() > 1) {
11.620 - edits.replace(nextOffset, next.length() - 1, null, false, 1); // NOI18N
11.621 - } else if (nextId != PythonTokenId.WHITESPACE && nextId != PythonTokenId.NEWLINE) {
11.622 - edits.replace(nextOffset, 0, " ", false, 4); // NOI18N
11.623 - }
11.624 - }
11.625 - }
11.626 - }
11.627 -
11.628 - if (tokenOffset + token.length() >= endOffset) {
11.629 - break;
11.630 - }
11.631 -
11.632 - prevRemoved = tokenRemoved;
11.633 - tokenRemoved = nextRemoved;
11.634 - nextRemoved = false;
11.635 -
11.636 - prev = token;
11.637 - token = next;
11.638 - prevOffset = tokenOffset;
11.639 - tokenOffset = nextOffset;
11.640 - if (ts.moveNext()) {
11.641 - next = ts.token();
11.642 - nextOffset = ts.offset();
11.643 - } else {
11.644 - next = null;
11.645 - }
11.646 - }
11.647 - } catch (BadLocationException ble) {
11.648 - Exceptions.printStackTrace(ble);
11.649 - } finally {
11.650 - doc.readUnlock();
11.651 - }
11.652 -
11.653 - doc.runAtomic(new Runnable() {
11.654 - @Override
11.655 - public void run() {
11.656 - edits.apply();
11.657 - }
11.658 - });
11.659 - }
11.660 -}
12.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonHintOptions.java Fri Sep 18 16:20:24 2015 -0500
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,72 +0,0 @@
12.4 -/*
12.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
12.6 - *
12.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
12.8 - *
12.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
12.10 - * Other names may be trademarks of their respective owners.
12.11 - *
12.12 - * The contents of this file are subject to the terms of either the GNU
12.13 - * General Public License Version 2 only ("GPL") or the Common
12.14 - * Development and Distribution License("CDDL") (collectively, the
12.15 - * "License"). You may not use this file except in compliance with the
12.16 - * License. You can obtain a copy of the License at
12.17 - * http://www.netbeans.org/cddl-gplv2.html
12.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
12.19 - * specific language governing permissions and limitations under the
12.20 - * License. When distributing the software, include this License Header
12.21 - * Notice in each file and include the License file at
12.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
12.23 - * particular file as subject to the "Classpath" exception as provided
12.24 - * by Oracle in the GPL Version 2 section of the License file that
12.25 - * accompanied this code. If applicable, add the following below the
12.26 - * License Header, with the fields enclosed by brackets [] replaced by
12.27 - * your own identifying information:
12.28 - * "Portions Copyrighted [year] [name of copyright owner]"
12.29 - *
12.30 - * Contributor(s):
12.31 - *
12.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
12.33 - */
12.34 -package org.netbeans.modules.python.editor;
12.35 -
12.36 -import org.netbeans.modules.csl.api.HintsProvider;
12.37 -import org.netbeans.modules.csl.api.HintsProvider.HintsManager;
12.38 -import org.netbeans.modules.python.api.PythonMIMEResolver;
12.39 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
12.40 -import org.netbeans.spi.options.AdvancedOption;
12.41 -import org.netbeans.spi.options.OptionsPanelController;
12.42 -import org.openide.util.NbBundle;
12.43 -
12.44 -/**
12.45 - * Hint settings for Python
12.46 - */
12.47 -public class PythonHintOptions extends AdvancedOption {
12.48 - OptionsPanelController panelController;
12.49 -
12.50 - @Override
12.51 - public String getDisplayName() {
12.52 - return NbBundle.getMessage(PythonHintOptions.class, "CTL_Hints_DisplayName"); // NOI18N
12.53 - }
12.54 -
12.55 - @Override
12.56 - public String getTooltip() {
12.57 - return NbBundle.getMessage(PythonHintOptions.class, "CTL_Hints_ToolTip"); // NOI18N
12.58 - }
12.59 -
12.60 - @Override
12.61 - public synchronized OptionsPanelController create() {
12.62 - if (panelController == null) {
12.63 - HintsManager manager = HintsProvider.HintsManager.getManagerForMimeType(PythonMIMEResolver.PYTHON_MIME_TYPE);
12.64 - assert manager != null;
12.65 - panelController = manager.getOptionsController();
12.66 - }
12.67 -
12.68 - return panelController;
12.69 - }
12.70 -
12.71 - //TODO: temporary solution, this should be solved on GSF level
12.72 - public static OptionsPanelController createStatic() {
12.73 - return new PythonHintOptions().create();
12.74 - }
12.75 -}
13.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonIndex.java Fri Sep 18 16:20:24 2015 -0500
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,1470 +0,0 @@
13.4 -/*
13.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
13.6 - *
13.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
13.8 - *
13.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
13.10 - * Other names may be trademarks of their respective owners.
13.11 - *
13.12 - * The contents of this file are subject to the terms of either the GNU
13.13 - * General Public License Version 2 only ("GPL") or the Common
13.14 - * Development and Distribution License("CDDL") (collectively, the
13.15 - * "License"). You may not use this file except in compliance with the
13.16 - * License. You can obtain a copy of the License at
13.17 - * http://www.netbeans.org/cddl-gplv2.html
13.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13.19 - * specific language governing permissions and limitations under the
13.20 - * License. When distributing the software, include this License Header
13.21 - * Notice in each file and include the License file at
13.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
13.23 - * particular file as subject to the "Classpath" exception as provided
13.24 - * by Oracle in the GPL Version 2 section of the License file that
13.25 - * accompanied this code. If applicable, add the following below the
13.26 - * License Header, with the fields enclosed by brackets [] replaced by
13.27 - * your own identifying information:
13.28 - * "Portions Copyrighted [year] [name of copyright owner]"
13.29 - *
13.30 - * Contributor(s):
13.31 - *
13.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
13.33 - */
13.34 -package org.netbeans.modules.python.editor;
13.35 -
13.36 -import java.io.File;
13.37 -import java.io.IOException;
13.38 -import java.net.MalformedURLException;
13.39 -import java.net.URL;
13.40 -import java.util.ArrayList;
13.41 -import java.util.Arrays;
13.42 -import java.util.Collection;
13.43 -import java.util.Collections;
13.44 -import java.util.EnumSet;
13.45 -import java.util.HashMap;
13.46 -import java.util.HashSet;
13.47 -import java.util.Iterator;
13.48 -import java.util.List;
13.49 -import java.util.Map;
13.50 -import java.util.Set;
13.51 -import java.util.WeakHashMap;
13.52 -import java.util.logging.Level;
13.53 -import java.util.logging.Logger;
13.54 -import org.netbeans.api.project.Project;
13.55 -import org.netbeans.modules.csl.api.ElementKind;
13.56 -import org.netbeans.modules.parsing.spi.indexing.PathRecognizer;
13.57 -import org.netbeans.modules.parsing.spi.indexing.support.IndexResult;
13.58 -import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
13.59 -import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CAMEL_CASE;
13.60 -import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CASE_INSENSITIVE_PREFIX;
13.61 -import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CASE_INSENSITIVE_REGEXP;
13.62 -import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.PREFIX;
13.63 -import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.REGEXP;
13.64 -import org.netbeans.modules.python.editor.elements.IndexedElement;
13.65 -import org.netbeans.modules.python.api.PythonPlatform;
13.66 -import org.netbeans.modules.python.api.PythonPlatformManager;
13.67 -import org.netbeans.modules.python.editor.elements.IndexedPackage;
13.68 -import org.netbeans.modules.python.editor.imports.ImportManager;
13.69 -import org.openide.filesystems.FileObject;
13.70 -import org.openide.filesystems.FileStateInvalidException;
13.71 -import org.openide.filesystems.URLMapper;
13.72 -import org.openide.modules.InstalledFileLocator;
13.73 -import org.openide.util.Exceptions;
13.74 -import org.openide.util.Lookup;
13.75 -import org.python.antlr.ast.Import;
13.76 -import org.python.antlr.ast.ImportFrom;
13.77 -import org.python.antlr.ast.alias;
13.78 -
13.79 -/**
13.80 - *
13.81 - * @author alley
13.82 - * @author Tor Norbye
13.83 - */
13.84 -public class PythonIndex {
13.85 -// public static final Set<SearchScope> ALL_SCOPE = EnumSet.allOf(SearchScope.class);
13.86 -// public static final Set<SearchScope> SOURCE_SCOPE = EnumSet.of(SearchScope.SOURCE);
13.87 - static final String CLUSTER_URL = "cluster:"; // NOI18N
13.88 - static final String PYTHONHOME_URL = "python:"; // NOI18N
13.89 - private static final String STUB_MISSING = "stub_missing"; // NOI18N
13.90 -
13.91 - // The "functions" module is always imported by the interpreter, and ditto
13.92 - // for exceptions, constants, etc.
13.93 - public static Set<String> BUILTIN_MODULES = new HashSet<>();
13.94 -
13.95 -
13.96 - private static final Logger LOG = Logger.getLogger(PythonIndex.class.getName());
13.97 - public static final String OBJECT = "object"; // NOI18N
13.98 - static Map<String, Set<String>> wildcardImports = new HashMap<>();
13.99 - static Set<String> systemModules;
13.100 - // TODO - make weak?
13.101 - static Set<String> availableClasses;
13.102 - private static String clusterUrl = null;
13.103 - static {
13.104 - //BUILTIN_MODULES.add("objects"); // NOI18N -- just links to the others
13.105 - BUILTIN_MODULES.add("stdtypes"); // NOI18N
13.106 - //BUILTIN_MODULES.add("types"); // NOI18N
13.107 - BUILTIN_MODULES.add("exceptions"); // NOI18N
13.108 - BUILTIN_MODULES.add("functions"); // NOI18N
13.109 - BUILTIN_MODULES.add("constants"); // NOI18N
13.110 - }
13.111 -
13.112 - public static PythonIndex get(Collection<FileObject> roots) {
13.113 - // XXX no cache - is it needed?
13.114 - LOG.log(Level.FINE, "PythonIndex for roots: {0}", roots); //NOI18N
13.115 - return new PythonIndex(QuerySupportFactory.get(roots), false);
13.116 - }
13.117 -
13.118 - public static PythonIndex get(Project project) {
13.119 - Set<String> sourceIds = new HashSet<>();
13.120 - Set<String> libraryIds = new HashSet<>();
13.121 - Collection<? extends PathRecognizer> lookupAll = Lookup.getDefault().lookupAll(PathRecognizer.class);
13.122 - for (PathRecognizer pathRecognizer : lookupAll) {
13.123 - Set<String> source = pathRecognizer.getSourcePathIds();
13.124 - if (source != null) {
13.125 - sourceIds.addAll(source);
13.126 - }
13.127 - Set<String> library = pathRecognizer.getLibraryPathIds();
13.128 - if (library != null) {
13.129 - libraryIds.addAll(library);
13.130 - }
13.131 - }
13.132 -
13.133 - final Collection<FileObject> findRoots = QuerySupport.findRoots(project,
13.134 - sourceIds,
13.135 - libraryIds,
13.136 - Collections.<String>emptySet());
13.137 - return PythonIndex.get(findRoots);
13.138 - }
13.139 -
13.140 - private static final WeakHashMap<FileObject, PythonIndex> INDEX_CACHE = new WeakHashMap<>();
13.141 - public static PythonIndex get(FileObject fo) {
13.142 - PythonIndex index = INDEX_CACHE.get(fo);
13.143 - if (index == null) {
13.144 - LOG.log(Level.FINE, "Creating PythonIndex for FileObject: {0}", fo); //NOI18N
13.145 - index = new PythonIndex(QuerySupportFactory.get(fo), true);
13.146 - INDEX_CACHE.put(fo, index);
13.147 - }
13.148 - return index;
13.149 - }
13.150 -
13.151 - public static boolean isBuiltinModule(String module) {
13.152 - return BUILTIN_MODULES.contains(module) || STUB_MISSING.equals(module);
13.153 - }
13.154 -
13.155 - // For testing only
13.156 - public static void setClusterUrl(String url) {
13.157 - clusterUrl = url;
13.158 - }
13.159 -
13.160 - static String getPreindexUrl(String url) {
13.161 - // TODO - look up the correct platform to use!
13.162 - final PythonPlatformManager manager = PythonPlatformManager.getInstance();
13.163 - final String platformName = manager.getDefaultPlatform();
13.164 - PythonPlatform platform = manager.getPlatform(platformName);
13.165 - if (platform != null) {
13.166 - String s = platform.getHomeUrl();
13.167 - if (s != null) {
13.168 - if (url.startsWith(s)) {
13.169 - url = PYTHONHOME_URL + url.substring(s.length());
13.170 - return url;
13.171 - }
13.172 - }
13.173 - }
13.174 -
13.175 - String s = getClusterUrl();
13.176 -
13.177 - if (url.startsWith(s)) {
13.178 - return CLUSTER_URL + url.substring(s.length());
13.179 - }
13.180 -
13.181 - if (url.startsWith("jar:file:")) { // NOI18N
13.182 - String sub = url.substring(4);
13.183 - if (sub.startsWith(s)) {
13.184 - return CLUSTER_URL + sub.substring(s.length());
13.185 - }
13.186 - }
13.187 -
13.188 - return url;
13.189 - }
13.190 -
13.191 -/** Get the FileObject corresponding to a URL returned from the index */
13.192 - public static FileObject getFileObject(String url) {
13.193 - return getFileObject(url, null);
13.194 - }
13.195 -
13.196 - public static FileObject getFileObject(String url, FileObject context) {
13.197 - try {
13.198 - if (url.startsWith(PYTHONHOME_URL)) {
13.199 - Iterator<String> it = null;
13.200 -
13.201 - // TODO - look up the right platform for the given project
13.202 - //if (context != null) {
13.203 - // Project project = FileOwnerQuery.getOwner(context);
13.204 - // if (project != null) {
13.205 - // PythonPlatform platform = PythonPlatform.platformFor(project);
13.206 - // if (platform != null) {
13.207 - // it = Collections.singleton(platform).iterator();
13.208 - // }
13.209 - // }
13.210 - //}
13.211 -
13.212 - PythonPlatformManager manager = PythonPlatformManager.getInstance();
13.213 - if (it == null) {
13.214 - it = manager.getPlatformList().iterator();
13.215 - }
13.216 - while (it.hasNext()) {
13.217 - String name = it.next();
13.218 - PythonPlatform platform = manager.getPlatform(name);
13.219 - if (platform != null) {
13.220 - String u = platform.getHomeUrl();
13.221 - if (u != null) {
13.222 - try {
13.223 - u = u + url.substring(PYTHONHOME_URL.length());
13.224 - FileObject fo = URLMapper.findFileObject(new URL(u));
13.225 - if (fo != null) {
13.226 - return fo;
13.227 - }
13.228 - } catch (MalformedURLException mue) {
13.229 - Exceptions.printStackTrace(mue);
13.230 - }
13.231 - }
13.232 - }
13.233 - }
13.234 -
13.235 - return null;
13.236 - } else if (url.startsWith(CLUSTER_URL)) {
13.237 - url = getClusterUrl() + url.substring(CLUSTER_URL.length()); // NOI18N
13.238 - if (url.contains(".egg!/")) { // NOI18N
13.239 - url = "jar:" + url; // NOI18N
13.240 - }
13.241 - }
13.242 -
13.243 - return URLMapper.findFileObject(new URL(url));
13.244 - } catch (MalformedURLException ex) {
13.245 - Exceptions.printStackTrace(ex);
13.246 - }
13.247 -
13.248 - return null;
13.249 - }
13.250 -
13.251 - static String getClusterUrl() {
13.252 - if (clusterUrl == null) {
13.253 - File f =
13.254 - InstalledFileLocator.getDefault().locate("modules/org-netbeans-modules-python-editor.jar", null, false); // NOI18N
13.255 -
13.256 - if (f == null) {
13.257 - throw new RuntimeException("Can't find cluster");
13.258 - }
13.259 -
13.260 - f = new File(f.getParentFile().getParentFile().getAbsolutePath());
13.261 -
13.262 - try {
13.263 - f = f.getCanonicalFile();
13.264 - clusterUrl = f.toURI().toURL().toExternalForm();
13.265 - } catch (IOException ioe) {
13.266 - Exceptions.printStackTrace(ioe);
13.267 - }
13.268 - }
13.269 -
13.270 - return clusterUrl;
13.271 - }
13.272 -
13.273 - private final QuerySupport index;
13.274 - private final boolean updateCache;
13.275 -
13.276 - /** Creates a new instance of PythonIndex */
13.277 - private PythonIndex(QuerySupport index, boolean updateCache) {
13.278 - this.index = index;
13.279 - this.updateCache = updateCache;
13.280 - }
13.281 -
13.282 - private boolean search(String fieldName, String fieldValue, QuerySupport.Kind kind, Set<? super IndexResult> result, final String... fieldsToLoad) {
13.283 - try {
13.284 - result.addAll(index.query(fieldName, fieldValue, kind, fieldsToLoad));
13.285 - return true;
13.286 - } catch (IOException ioe) {
13.287 - Exceptions.printStackTrace(ioe);
13.288 -
13.289 - return false;
13.290 - } catch (UnsupportedOperationException iuoe) {
13.291 - return false;
13.292 - }
13.293 - }
13.294 -
13.295 - public Set<IndexedElement> getModules(String name, final QuerySupport.Kind kind) {
13.296 - final Set<IndexResult> result = new HashSet<>();
13.297 -
13.298 - // if (!isValid()) {
13.299 - // LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
13.300 - // return;
13.301 - // }
13.302 -
13.303 - // TODO - handle case insensitive searches etc?
13.304 - String field = PythonIndexer.FIELD_MODULE_NAME;
13.305 -
13.306 - search(field, name, kind, result, PythonIndexer.FIELD_MODULE_ATTR_NAME, PythonIndexer.FIELD_MODULE_NAME);
13.307 -
13.308 - final Set<IndexedElement> modules = new HashSet<>();
13.309 -
13.310 - for (IndexResult map : result) {
13.311 - URL url = map.getUrl();
13.312 - if (url == null) {
13.313 - continue;
13.314 - }
13.315 - String path = url.toExternalForm();
13.316 - String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
13.317 - if (STUB_MISSING.equals(module)) {
13.318 - continue;
13.319 - }
13.320 -
13.321 - IndexedElement element = new IndexedElement(module, ElementKind.MODULE, path, null, null, null);
13.322 -
13.323 - String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
13.324 - if (attrs != null && attrs.indexOf('D') != -1) {
13.325 - element.setFlags(IndexedElement.DEPRECATED);
13.326 - }
13.327 -
13.328 - String rhs = path.substring(path.lastIndexOf('/') + 1);
13.329 - element.setRhs(rhs);
13.330 - modules.add(element);
13.331 - }
13.332 -
13.333 - return modules;
13.334 - }
13.335 -
13.336 - public Set<IndexedPackage> getPackages(String name, final QuerySupport.Kind kind) {
13.337 - final Set<IndexResult> result = new HashSet<>();
13.338 -
13.339 - String field = PythonIndexer.FIELD_MODULE_NAME;
13.340 - search(field, name, kind, result, PythonIndexer.FIELD_MODULE_NAME);
13.341 -
13.342 - final Set<IndexedPackage> packages = new HashSet<>();
13.343 -
13.344 - for (IndexResult map : result) {
13.345 - String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
13.346 -
13.347 - String pkgName = null;
13.348 - String pkg = null;
13.349 -
13.350 - int nextNextDot = -1;
13.351 - int lastDot = module.lastIndexOf('.');
13.352 - int nameLength = name.length();
13.353 - if (nameLength < lastDot) {
13.354 - int nextDot = module.indexOf('.', nameLength);
13.355 - if (nextDot != -1) {
13.356 - pkg = module.substring(0, nextDot);
13.357 - nextNextDot = module.indexOf('.', nextDot + 1);
13.358 - int start = module.lastIndexOf('.', name.length());
13.359 - if (start == -1) {
13.360 - start = 0;
13.361 - } else {
13.362 - start++;
13.363 - }
13.364 - pkgName = module.substring(start, nextDot);
13.365 - }
13.366 - } else if (lastDot != -1) {
13.367 - pkgName = module.substring(lastDot + 1);
13.368 - pkg = module;
13.369 - }
13.370 -
13.371 - if (pkgName != null) {
13.372 - String url = map.getUrl().toExternalForm();
13.373 - IndexedPackage element = new IndexedPackage(pkgName, pkg, url, nextNextDot != -1);
13.374 - element.setRhs("");
13.375 - packages.add(element);
13.376 - }
13.377 - }
13.378 -
13.379 - return packages;
13.380 - }
13.381 -
13.382 - public Set<IndexedElement> getClasses(String name, final QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
13.383 - final Set<IndexResult> result = new HashSet<>();
13.384 -
13.385 - // if (!isValid()) {
13.386 - // LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
13.387 - // return;
13.388 - // }
13.389 - String field;
13.390 -
13.391 - switch (kind) {
13.392 - case EXACT:
13.393 - case PREFIX:
13.394 - case CAMEL_CASE:
13.395 - case REGEXP:
13.396 - field = PythonIndexer.FIELD_CLASS_NAME;
13.397 -
13.398 - break;
13.399 -
13.400 - case CASE_INSENSITIVE_PREFIX:
13.401 - case CASE_INSENSITIVE_REGEXP:
13.402 - case CASE_INSENSITIVE_CAMEL_CASE:
13.403 - field = PythonIndexer.FIELD_CASE_INSENSITIVE_CLASS_NAME;
13.404 -
13.405 - break;
13.406 -
13.407 - default:
13.408 - throw new UnsupportedOperationException(kind.toString());
13.409 - }
13.410 -
13.411 - search(field, name, kind, result, PythonIndexer.FIELD_IN, PythonIndexer.FIELD_CLASS_ATTR_NAME, PythonIndexer.FIELD_CLASS_NAME);
13.412 -
13.413 - Set<String> uniqueClasses = includeDuplicates ? null : new HashSet<String>();
13.414 -
13.415 - final Set<IndexedElement> classes = new HashSet<>();
13.416 -
13.417 - for (IndexResult map : result) {
13.418 - String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.419 - if (clz == null) {
13.420 - // A module without classes
13.421 - continue;
13.422 - }
13.423 - String url = map.getUrl().toExternalForm();
13.424 - String module = map.getValue(PythonIndexer.FIELD_IN);
13.425 - boolean isBuiltin = isBuiltinModule(module);
13.426 -
13.427 - String fqn = clz; // No further namespaces in Python, right?
13.428 - if (!includeDuplicates) {
13.429 - if (!uniqueClasses.contains(fqn)) { // use a map to point right to the class
13.430 - uniqueClasses.add(fqn);
13.431 - IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
13.432 - if (isBuiltin) {
13.433 - element.setRhs("<i>builtin</i>");
13.434 - }
13.435 - String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
13.436 - if (attrs != null) {
13.437 - int flags = IndexedElement.decode(attrs, 0, 0);
13.438 - element.setFlags(flags);
13.439 - }
13.440 - element.setInherited(true);
13.441 -
13.442 - classes.add(element);
13.443 - } // else: Possibly pick the best version... based on which items have documentation attributes etc.
13.444 - } else {
13.445 - IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
13.446 - classes.add(element);
13.447 - }
13.448 - }
13.449 -
13.450 - return classes;
13.451 - }
13.452 -
13.453 -// /** Return the most distant method in the hierarchy that is overriding the given method, or null
13.454 -// * @todo Make this method actually compute most distant ancestor
13.455 -// * @todo Use arglist arity comparison to reject methods that are not overrides...
13.456 -// */
13.457 -// public IndexedMethod getOverridingMethod(String className, String methodName) {
13.458 -// Set<IndexedElement> methods = getInheritedElements(className, methodName, QuerySupport.Kind.EXACT);
13.459 -//
13.460 -// // TODO - this is only returning ONE match, not the most distant one. I really need to
13.461 -// // produce a PythonIndex method for this which can walk in there and do a decent job!
13.462 -//
13.463 -// for (IndexedElement method : methods) {
13.464 -// if (method.getKind() == ElementKind.METHOD || method.getKind() == ElementKind.CONSTRUCTOR) {
13.465 -// // getInheritedMethods may return methods ON fqn itself
13.466 -// if (!method.getIn().equals(className)) {
13.467 -// return (IndexedMethod)method;
13.468 -// }
13.469 -// }
13.470 -// }
13.471 -//
13.472 -// return null;
13.473 -// }
13.474 - /** Get the super implementation of the given method */
13.475 - public Set<IndexedElement> getOverridingMethods(String className, String function) {
13.476 - Set<IndexedElement> methods = getInheritedElements(className, function, QuerySupport.Kind.EXACT, true);
13.477 -
13.478 - // TODO - remove all methods that are in the same file
13.479 - if (methods.size() > 0) {
13.480 - Set<IndexedElement> result = new HashSet<>(methods.size());
13.481 - for (IndexedElement element : methods) {
13.482 - if (!className.equals(element.getClz())) {
13.483 - result.add(element);
13.484 - }
13.485 - }
13.486 - methods = result;
13.487 - }
13.488 -
13.489 - return methods;
13.490 -// // TODO - this is only returning ONE match, not the most distant one. I really need to
13.491 -// // produce a PythonIndex method for this which can walk in there and do a decent job!
13.492 -//
13.493 -// for (IndexedElement method : methods) {
13.494 -// if (method.getKind() == ElementKind.METHOD || method.getKind() == ElementKind.CONSTRUCTOR) {
13.495 -// // getInheritedMethods may return methods ON fqn itself
13.496 -// if (!method.getIn().equals(className)) {
13.497 -// return (IndexedMethod)method;
13.498 -// }
13.499 -// }
13.500 -// }
13.501 -//
13.502 -// return null;
13.503 - }
13.504 -
13.505 - /** Get the super class of the given class */
13.506 - public Set<IndexedElement> getSuperClasses(String className) {
13.507 - final Set<IndexResult> result = new HashSet<>();
13.508 -
13.509 - search(PythonIndexer.FIELD_CLASS_NAME, className, QuerySupport.Kind.EXACT, result, PythonIndexer.FIELD_EXTENDS_NAME, PythonIndexer.FIELD_CLASS_NAME);
13.510 -
13.511 - Set<String> classNames = new HashSet<>();
13.512 - for (IndexResult map : result) {
13.513 - String[] extendsClasses = map.getValues(PythonIndexer.FIELD_EXTENDS_NAME);
13.514 - if (extendsClasses != null && extendsClasses.length > 0) {
13.515 - for (String clzName : extendsClasses) {
13.516 - classNames.add(clzName);
13.517 - }
13.518 - }
13.519 - }
13.520 -
13.521 - String[] terms = { PythonIndexer.FIELD_IN, PythonIndexer.FIELD_CLASS_NAME };
13.522 -
13.523 - Set<IndexedElement> superClasses = new HashSet<>();
13.524 -
13.525 - for (String superClz : classNames) {
13.526 - result.clear();
13.527 - search(PythonIndexer.FIELD_CLASS_NAME, superClz, QuerySupport.Kind.EXACT, result, terms);
13.528 - for (IndexResult map : result) {
13.529 - assert superClz.equals(map.getValue(PythonIndexer.FIELD_CLASS_NAME));
13.530 - String url = map.getUrl().toExternalForm();
13.531 - String module = map.getValue(PythonIndexer.FIELD_IN);
13.532 - IndexedElement clz = new IndexedElement(superClz, ElementKind.CLASS, url, module, null, null);
13.533 - superClasses.add(clz);
13.534 - }
13.535 - }
13.536 -
13.537 - return superClasses;
13.538 - }
13.539 -
13.540 - /**
13.541 - * Get the set of inherited (through super classes and mixins) for the given fully qualified class name.
13.542 - * @param classFqn FQN: module1::module2::moduleN::class
13.543 - * @param prefix If kind is QuerySupport.Kind.PREFIX/CASE_INSENSITIVE_PREFIX, a prefix to filter methods by. Else,
13.544 - * if kind is QuerySupport.Kind.EXACT filter methods by the exact name.
13.545 - * @param kind Whether the prefix field should be taken as a prefix or a whole name
13.546 - */
13.547 - public Set<IndexedElement> getInheritedElements(String classFqn, String prefix, QuerySupport.Kind kind) {
13.548 - return getInheritedElements(classFqn, prefix, kind, false);
13.549 - }
13.550 -
13.551 - public Set<IndexedElement> getInheritedElements(String classFqn, String prefix, QuerySupport.Kind kind, boolean includeOverrides) {
13.552 - boolean haveRedirected = false;
13.553 -
13.554 - if (classFqn == null) {
13.555 - classFqn = OBJECT;
13.556 - haveRedirected = true;
13.557 - }
13.558 -
13.559 - //String field = PythonIndexer.FIELD_FQN_NAME;
13.560 - Set<IndexedElement> elements = new HashSet<>();
13.561 - Set<String> scannedClasses = new HashSet<>();
13.562 - Set<String> seenSignatures = new HashSet<>();
13.563 -
13.564 - if (prefix == null) {
13.565 - prefix = "";
13.566 - }
13.567 -
13.568 -// String searchUrl = null;
13.569 -// if (context != null) {
13.570 -// try {
13.571 -// searchUrl = context.getFile().getFileObject().getURL().toExternalForm();
13.572 -// } catch (FileStateInvalidException ex) {
13.573 -// Exceptions.printStackTrace(ex);
13.574 -// }
13.575 -// }
13.576 -
13.577 - addMethodsFromClass(prefix, kind, classFqn, elements, seenSignatures, scannedClasses,
13.578 - haveRedirected, false, includeOverrides, 0);
13.579 -
13.580 - return elements;
13.581 - }
13.582 -
13.583 - /** Return whether the specific class referenced (classFqn) was found or not. This is
13.584 - * not the same as returning whether any classes were added since it may add
13.585 - * additional methods from parents (Object/Class).
13.586 - */
13.587 - private boolean addMethodsFromClass(String prefix, QuerySupport.Kind kind, String classFqn, Set<IndexedElement> elements, Set<String> seenSignatures, Set<String> scannedClasses, boolean haveRedirected, boolean inheriting, boolean includeOverrides, int depth) {
13.588 - // Prevent problems with circular includes or redundant includes
13.589 - if (scannedClasses.contains(classFqn)) {
13.590 - return false;
13.591 - }
13.592 -
13.593 - scannedClasses.add(classFqn);
13.594 -
13.595 - String searchField = PythonIndexer.FIELD_CLASS_NAME;
13.596 -
13.597 - Set<IndexResult> result = new HashSet<>();
13.598 -
13.599 - String[] terms = {PythonIndexer.FIELD_IN,
13.600 - PythonIndexer.FIELD_EXTENDS_NAME,
13.601 - PythonIndexer.FIELD_MEMBER,
13.602 - PythonIndexer.FIELD_CLASS_NAME};
13.603 -
13.604 -
13.605 - search(searchField, classFqn, QuerySupport.Kind.EXACT, result, terms);
13.606 -
13.607 - boolean foundIt = result.size() > 0;
13.608 -
13.609 - // If this is a bogus class entry (no search rsults) don't continue
13.610 - if (!foundIt) {
13.611 - return foundIt;
13.612 - }
13.613 -
13.614 - List<String> extendsClasses = null;
13.615 -
13.616 - String classIn = null;
13.617 - int fqnIndex = classFqn.lastIndexOf("::"); // NOI18N
13.618 -
13.619 - if (fqnIndex != -1) {
13.620 - classIn = classFqn.substring(0, fqnIndex);
13.621 - }
13.622 - int prefixLength = prefix.length();
13.623 -
13.624 - for (IndexResult map : result) {
13.625 - assert map != null;
13.626 -
13.627 - String url = map.getUrl().toExternalForm();
13.628 - String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.629 - String module = map.getValue(PythonIndexer.FIELD_IN);
13.630 -
13.631 - if (extendsClasses == null) {
13.632 - String[] ext = map.getValues(PythonIndexer.FIELD_EXTENDS_NAME);
13.633 - if (ext != null && ext.length > 0) {
13.634 - if (extendsClasses == null) {
13.635 - extendsClasses = Arrays.asList(ext);
13.636 - } else {
13.637 - extendsClasses = new ArrayList<>(extendsClasses);
13.638 - extendsClasses.addAll(Arrays.asList(ext));
13.639 - }
13.640 - }
13.641 - }
13.642 -
13.643 - String[] members = map.getValues(PythonIndexer.FIELD_MEMBER);
13.644 -
13.645 - if (members != null) {
13.646 - for (String signature : members) {
13.647 - // Prevent duplicates when method is redefined
13.648 - if (includeOverrides || !seenSignatures.contains(signature)) {
13.649 - if (signature.startsWith(prefix)) {
13.650 - if (kind == QuerySupport.Kind.EXACT) {
13.651 - if (signature.charAt(prefixLength) != ';') {
13.652 - continue;
13.653 - }
13.654 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, prefix, 0, prefix.length())) {
13.655 - continue;
13.656 - } else {
13.657 - // REGEXP, CAMELCASE filtering etc. not supported here
13.658 - assert (kind == QuerySupport.Kind.PREFIX) ||
13.659 - (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
13.660 - }
13.661 -
13.662 - if (!includeOverrides) {
13.663 - seenSignatures.add(signature);
13.664 - }
13.665 - IndexedElement element = IndexedElement.create(signature, module, url, clz);
13.666 - // TODO - filter out private? Or let code completer do that? Probably should, in case
13.667 - // we have more rights when inheriting
13.668 - element.setSmart(!haveRedirected);
13.669 - element.setInherited(inheriting);
13.670 - if (includeOverrides) {
13.671 - element.setOrder(depth);
13.672 - }
13.673 - elements.add(element);
13.674 - }
13.675 - }
13.676 - }
13.677 - }
13.678 - }
13.679 -
13.680 - if (classFqn.equals(OBJECT)) {
13.681 - return foundIt;
13.682 - }
13.683 -
13.684 - if (extendsClasses == null || extendsClasses.size() == 0) {
13.685 - addMethodsFromClass(prefix, kind, OBJECT, elements, seenSignatures, scannedClasses,
13.686 - true, true, includeOverrides, depth + 1);
13.687 - } else {
13.688 - // We're not sure we have a fully qualified path, so try some different candidates
13.689 - for (String extendsClass : extendsClasses) {
13.690 - if (!addMethodsFromClass(prefix, kind, extendsClass, elements, seenSignatures,
13.691 - scannedClasses, haveRedirected, true, includeOverrides, depth + 1)) {
13.692 - // Search by classIn
13.693 - String fqn = classIn;
13.694 -
13.695 - while (fqn != null) {
13.696 - if (addMethodsFromClass(prefix, kind, fqn + "::" + extendsClass, elements,
13.697 - seenSignatures, scannedClasses, haveRedirected, true, includeOverrides, depth + 1)) {
13.698 - break;
13.699 - }
13.700 -
13.701 - int f = fqn.lastIndexOf("::"); // NOI18N
13.702 -
13.703 - if (f == -1) {
13.704 - break;
13.705 - } else {
13.706 - fqn = fqn.substring(0, f);
13.707 - }
13.708 - }
13.709 - }
13.710 - }
13.711 - }
13.712 -
13.713 - return foundIt;
13.714 - }
13.715 -
13.716 -
13.717 - public Set<IndexedElement> getAllMembers(String name, QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
13.718 - final Set<IndexResult> result = new HashSet<>();
13.719 - // TODO - handle case sensitivity better...
13.720 - String field = PythonIndexer.FIELD_MEMBER;
13.721 - QuerySupport.Kind originalKind = kind;
13.722 - if (kind == QuerySupport.Kind.EXACT) {
13.723 - // I can't do exact searches on methods because the method
13.724 - // entries include signatures etc. So turn this into a prefix
13.725 - // search and then compare chopped off signatures with the name
13.726 - kind = QuerySupport.Kind.PREFIX;
13.727 - }
13.728 -
13.729 - String searchUrl = null;
13.730 - if (context != null) {
13.731 - searchUrl = context.getSnapshot().getSource().getFileObject().toURL().toExternalForm();
13.732 - }
13.733 -
13.734 - String[] terms = {PythonIndexer.FIELD_IN,
13.735 - PythonIndexer.FIELD_EXTENDS_NAME,
13.736 - PythonIndexer.FIELD_MEMBER,
13.737 - PythonIndexer.FIELD_CLASS_NAME};
13.738 -
13.739 - search(field, name, kind, result, terms);
13.740 -
13.741 -// Set<String> uniqueClasses = null;
13.742 -// if (includeDuplicates) {
13.743 -// uniqueClasses = null;
13.744 -// } else if (uniqueClasses == null) {
13.745 -// uniqueClasses = new HashSet<String>();
13.746 -// }
13.747 -
13.748 - final Set<IndexedElement> members = new HashSet<>();
13.749 - int nameLength = name.length();
13.750 -
13.751 - for (IndexResult map : result) {
13.752 - String[] signatures = map.getValues(PythonIndexer.FIELD_MEMBER);
13.753 - if (signatures != null && signatures.length > 0) {
13.754 - String url = map.getUrl().toExternalForm();
13.755 - String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.756 - String module = map.getValue(PythonIndexer.FIELD_IN);
13.757 - boolean inherited = searchUrl == null || !searchUrl.equals(url);
13.758 -
13.759 - for (String signature : signatures) {
13.760 - if (originalKind == QuerySupport.Kind.EXACT) {
13.761 - if (signature.charAt(nameLength) != ';') {
13.762 - continue;
13.763 - }
13.764 - } else if (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, name, 0, name.length())) {
13.765 - continue;
13.766 - } else {
13.767 - // REGEXP, CAMELCASE filtering etc. not supported here
13.768 - assert (originalKind == QuerySupport.Kind.PREFIX) ||
13.769 - (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
13.770 - }
13.771 -
13.772 - IndexedElement element = IndexedElement.create(signature, module, url, clz);
13.773 - element.setInherited(inherited);
13.774 - members.add(element);
13.775 - }
13.776 - }
13.777 - }
13.778 -
13.779 - return members;
13.780 - }
13.781 -
13.782 - public Set<IndexedElement> getAllElements(String name, QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
13.783 - final Set<IndexResult> result = new HashSet<>();
13.784 - // TODO - handle case sensitivity better...
13.785 - String field = PythonIndexer.FIELD_ITEM;
13.786 - QuerySupport.Kind originalKind = kind;
13.787 - if (kind == QuerySupport.Kind.EXACT) {
13.788 - // I can't do exact searches on methods because the method
13.789 - // entries include signatures etc. So turn this into a prefix
13.790 - // search and then compare chopped off signatures with the name
13.791 - kind = QuerySupport.Kind.PREFIX;
13.792 - }
13.793 -
13.794 - String searchUrl = null;
13.795 - if (context != null) {
13.796 - searchUrl = context.getSnapshot().getSource().getFileObject().toURL().toExternalForm();
13.797 - }
13.798 -
13.799 - String[] terms = { PythonIndexer.FIELD_ITEM,
13.800 - PythonIndexer.FIELD_MODULE_NAME };
13.801 -
13.802 - search(field, name, kind, result, terms);
13.803 -
13.804 - final Set<IndexedElement> elements = new HashSet<>();
13.805 - int nameLength = name.length();
13.806 -
13.807 - for (IndexResult map : result) {
13.808 - String[] signatures = map.getValues(PythonIndexer.FIELD_ITEM);
13.809 - if (signatures != null && signatures.length > 0) {
13.810 - String url = map.getUrl().toExternalForm();
13.811 - String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
13.812 - boolean inherited = searchUrl == null || !searchUrl.equals(url);
13.813 -
13.814 - for (String signature : signatures) {
13.815 - if (originalKind == QuerySupport.Kind.EXACT) {
13.816 - if (signature.charAt(nameLength) != ';') {
13.817 - continue;
13.818 - }
13.819 - } else if (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, name, 0, name.length())) {
13.820 - continue;
13.821 - } else {
13.822 - // REGEXP, CAMELCASE filtering etc. not supported here
13.823 - assert (originalKind == QuerySupport.Kind.PREFIX) ||
13.824 - (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
13.825 - }
13.826 -
13.827 - IndexedElement element = IndexedElement.create(signature, module, url, null);
13.828 - if (element.isPrivate() && !url.equals(searchUrl)) {
13.829 - continue;
13.830 - }
13.831 - element.setInherited(inherited);
13.832 - elements.add(element);
13.833 - }
13.834 - }
13.835 - }
13.836 -
13.837 - return elements;
13.838 - }
13.839 -
13.840 - public Set<String> getBuiltinSymbols() {
13.841 - Set<String> modules = new HashSet<>();
13.842 -
13.843 - // The "functions" module is always imported by the interpreter, and ditto
13.844 - // for exceptions, constants, etc.
13.845 - //modules.add("objects"); // NOI18N -- just links to the others
13.846 - modules.addAll(BUILTIN_MODULES);
13.847 -
13.848 - Set<String> symbols = new HashSet<>(250);
13.849 -
13.850 - String[] terms = { PythonIndexer.FIELD_MODULE_NAME,
13.851 - PythonIndexer.FIELD_ITEM };
13.852 -
13.853 - // Look up all symbols
13.854 - for (String module : modules) {
13.855 - final Set<IndexResult> result = new HashSet<>();
13.856 - // TODO - handle case sensitivity better...
13.857 - String field = PythonIndexer.FIELD_MODULE_NAME;
13.858 - QuerySupport.Kind kind = QuerySupport.Kind.EXACT;
13.859 -
13.860 - search(field, module, kind, result, terms);
13.861 -
13.862 - for (IndexResult map : result) {
13.863 - String[] signatures = map.getValues(PythonIndexer.FIELD_ITEM);
13.864 - if (signatures != null) {
13.865 - for (String signature : signatures) {
13.866 - int semi = signature.indexOf(';');
13.867 - assert semi != -1;
13.868 - int flags = IndexedElement.decode(signature, semi + 3, 0);
13.869 - if ((flags & IndexedElement.PRIVATE) != 0) {
13.870 - // Skip private symbols - can't import those
13.871 - continue;
13.872 - }
13.873 - String name = signature.substring(0, semi);
13.874 - symbols.add(name);
13.875 - }
13.876 - }
13.877 - }
13.878 - }
13.879 -
13.880 - // Computed as described below
13.881 - String[] MISSING = {
13.882 - "Ellipsis", "False", "IndentationError", "None", "NotImplemented", "TabError", // NOI18N
13.883 - "True", "__debug__", "__doc__", "__name__", "copyright", "credits", "exit", "license", // NOI18N
13.884 - "quit" // NOI18N
13.885 - };
13.886 - for (String s : MISSING) {
13.887 - symbols.add(s);
13.888 - }
13.889 - symbols.add("__builtins__"); // NOI18N
13.890 - symbols.add("__file__"); // NOI18N
13.891 -
13.892 - //// COMPUTING MISSING SYMBOLS:
13.893 - //// My builtin .rst files don't seem to define all the builtin symbols that the Python
13.894 - //// interpreter is configured with. I generated these pretty trivially; run
13.895 - //// python and type "dir(__builtins__)" and you end up a list like the below:
13.896 - ////String[] EXTRA_BUILTINS = {"ArithmeticError", "AssertionError", "AttributeError", "BaseException",
13.897 - // "DeprecationWarning", "EOFError", "Ellipsis", "EnvironmentError", "Exception", "False",
13.898 - // "FloatingPointError", "FutureWarning", "GeneratorExit", "IOError", "ImportError",
13.899 - // "ImportWarning", "IndentationError", "IndexError", "KeyError", "KeyboardInterrupt",
13.900 - // "LookupError", "MemoryError", "NameError", "None", "NotImplemented", "NotImplementedError",
13.901 - // "OSError", "OverflowError", "PendingDeprecationWarning", "ReferenceError", "RuntimeError",
13.902 - // "RuntimeWarning", "StandardError", "StopIteration", "SyntaxError", "SyntaxWarning", "SystemError",
13.903 - // "SystemExit", "TabError", "True", "TypeError", "UnboundLocalError", "UnicodeDecodeError",
13.904 - // "UnicodeEncodeError", "UnicodeError", "UnicodeTranslateError", "UnicodeWarning", "UserWarning",
13.905 - // "ValueError", "Warning", "ZeroDivisionError", "__debug__", "__doc__", "__import__", "__name__",
13.906 - // "abs", "all", "any", "apply", "basestring", "bool", "buffer", "callable", "chr", "classmethod",
13.907 - // "cmp", "coerce", "compile", "complex", "copyright", "credits", "delattr", "dict", "dir", "divmod",
13.908 - // "enumerate", "eval", "execfile", "exit", "file", "filter", "float", "frozenset", "getattr",
13.909 - // "globals", "hasattr", "hash", "help", "hex", "id", "input", "int", "intern", "isinstance",
13.910 - // "issubclass", "iter", "len", "license", "list", "locals", "long", "map", "max", "min", "object",
13.911 - // "oct", "open", "ord", "pow", "property", "quit", "range", "raw_input", "reduce", "reload",
13.912 - // "repr", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum",
13.913 - // "super", "tuple", "type", "unichr", "unicode", "vars", "xrange", "zip"};
13.914 - //// Most of these will be defined by my index search. However, for the missing ones, let's add them
13.915 - //// in. The following code computes the delta and produces a source-like string for it.
13.916 - //// It also counts the total symbol map size so we can pick a reasonable default:
13.917 - //List<String> asList = Arrays.asList(EXTRA_BUILTINS);
13.918 - //Set<String> asSet = new HashSet<String>(asList);
13.919 - //asSet.removeAll(symbols);
13.920 - //List<String> missing = new ArrayList<String>(asSet);
13.921 - //Collections.sort(missing);
13.922 - //int width = 0;
13.923 - //StringBuilder sb = new StringBuilder();
13.924 - //for (String s : missing) {
13.925 - // sb.append('"');
13.926 - // sb.append(s);
13.927 - // sb.append('"');
13.928 - // sb.append(',');
13.929 - // sb.append(' ');
13.930 - // width += s.length()+4;
13.931 - // if (width > 70) {
13.932 - // sb.append("\n");
13.933 - // width = 0;
13.934 - // }
13.935 - //}
13.936 - //String missingCode = "String[] MISSING = {\n" + sb.toString() + "\n};\n";
13.937 - //symbols.addAll(asList);
13.938 - //int requiredSetSize = symbols.size();
13.939 -
13.940 - return symbols;
13.941 - }
13.942 -
13.943 - @SuppressWarnings("unchecked")
13.944 - public Set<String> getImportsFor(String ident, boolean includeSymbol) {
13.945 - Set<String> modules = new HashSet<>(10);
13.946 -
13.947 - final Set<IndexResult> result = new HashSet<>();
13.948 - search(PythonIndexer.FIELD_MODULE_NAME, ident, QuerySupport.Kind.EXACT, result, PythonIndexer.FIELD_MODULE_NAME);
13.949 - for (IndexResult map : result) {
13.950 - String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
13.951 - if (module != null) {
13.952 - // TODO - record more information about this, such as the FQN
13.953 - // so it's easier for the user to disambiguate
13.954 - modules.add(module);
13.955 - }
13.956 - }
13.957 -
13.958 - // TODO - handle case sensitivity better...
13.959 - String field = PythonIndexer.FIELD_ITEM;
13.960 - QuerySupport.Kind kind = QuerySupport.Kind.PREFIX; // We're storing encoded signatures so not exact matches
13.961 -
13.962 - String[] terms = { PythonIndexer.FIELD_ITEM,
13.963 - PythonIndexer.FIELD_MODULE_NAME };
13.964 -
13.965 - result.clear();
13.966 - search(field, ident, kind, result, terms);
13.967 - String match = ident + ";";
13.968 -
13.969 - MapSearch:
13.970 - for (IndexResult map : result) {
13.971 - String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
13.972 - if (module == null) {
13.973 - continue;
13.974 - }
13.975 -
13.976 - if (module.indexOf('-') != -1) {
13.977 - // Don't include modules with -; these aren't real module
13.978 - // names (usually python scripts in directories containing a dash
13.979 - // that I incorrectly compute a module name for
13.980 - continue;
13.981 - }
13.982 -
13.983 - String[] members = map.getValues(PythonIndexer.FIELD_ITEM);
13.984 - if (members == null || members.length == 0) {
13.985 - continue;
13.986 - }
13.987 -
13.988 - int semi = match.length() - 1;
13.989 -
13.990 - for (String signature : members) {
13.991 - if (signature.startsWith(match)) {
13.992 - if (includeSymbol) {
13.993 - int flags = IndexedElement.decode(signature, semi + 3, 0);
13.994 - if ((flags & IndexedElement.PRIVATE) != 0) {
13.995 - // Skip private symbols - can't import those
13.996 - continue;
13.997 - }
13.998 - String sig = ident;
13.999 - char type = signature.charAt(semi + 1);
13.1000 - if (type == 'F') {
13.1001 - int sigStart = signature.indexOf(';', semi + 3) + 1;
13.1002 - int sigEnd = signature.indexOf(';', sigStart);
13.1003 - sig = ident + "(" + signature.substring(sigStart, sigEnd) + ")"; // NOI18N
13.1004 - } else if (type == 'I') {
13.1005 - // Don't provide modules that just -import- the symbol
13.1006 - continue;
13.1007 - }
13.1008 - if (!sig.equals(module)) {
13.1009 - modules.add(module + ": " + sig); // NOI18N
13.1010 - } else {
13.1011 - modules.add(module);
13.1012 - }
13.1013 - } else {
13.1014 - modules.add(module);
13.1015 - }
13.1016 - continue MapSearch;
13.1017 - }
13.1018 - }
13.1019 - }
13.1020 -
13.1021 - return modules;
13.1022 - }
13.1023 -
13.1024 - public Set<IndexedElement> getImportedElements(String prefix, QuerySupport.Kind kind, PythonParserResult context, List<Import> imports, List<ImportFrom> importsFrom) {
13.1025 - // TODO - separate methods from variables?? E.g. if you have method Foo() and class Foo
13.1026 - // coming from different places
13.1027 -
13.1028 -
13.1029 -// Set<String> imported = new HashSet<String>();
13.1030 -//
13.1031 - Set<IndexedElement> elements = new HashSet<>();
13.1032 -
13.1033 - // Look up the imports and compute all the symbols we get from the import
13.1034 - Set<String> modules = new HashSet<>();
13.1035 -
13.1036 - // ImportsFrom require no index lookup
13.1037 - for (ImportFrom from : importsFrom) {
13.1038 - if (ImportManager.isFutureImport(from)) {
13.1039 - continue;
13.1040 - }
13.1041 - List<alias> names = from.getInternalNames();
13.1042 - if (names != null) {
13.1043 - for (alias at : names) {
13.1044 - if ("*".equals(at.getInternalName())) { // NOI18N
13.1045 - modules.add(from.getInternalModule());
13.1046 -// } else {
13.1047 -// String name = at.getInternalAsname() != null ? at.getInternalAsname() : at.getInternalName();
13.1048 -// assert name.length() > 0;
13.1049 -// imported.add(name);
13.1050 - }
13.1051 - }
13.1052 - }
13.1053 - }
13.1054 -
13.1055 -// for (Import imp : imports) {
13.1056 -// if (imp.names != null) {
13.1057 -// for (alias at : imp.getInternalNames()) {
13.1058 -// if (at.getInternalAsname() != null) {
13.1059 -// String name = at.getInternalAsname();
13.1060 -// assert name.length() > 0;
13.1061 -// imported.add(name);
13.1062 -// } else {
13.1063 -// imported.add(at.getInternalName());
13.1064 -// }
13.1065 -// }
13.1066 -// }
13.1067 -// }
13.1068 -//
13.1069 -//
13.1070 -// // Create variable items for the locally imported symbols
13.1071 -// for (String name : imported) {
13.1072 -// if (name.startsWith(prefix)) {
13.1073 -// if (kind == QuerySupport.Kind.EXACT) {
13.1074 -// // Ensure that the method is not longer than the prefix
13.1075 -// if ((name.length() > prefix.length()) &&
13.1076 -// (name.charAt(prefix.length()) != '(') &&
13.1077 -// (name.charAt(prefix.length()) != ';')) {
13.1078 -// continue;
13.1079 -// }
13.1080 -// } else {
13.1081 -// // REGEXP, CAMELCASE filtering etc. not supported here
13.1082 -// assert (kind == QuerySupport.Kind.PREFIX) ||
13.1083 -// (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
13.1084 -// }
13.1085 -// String url = null;
13.1086 -// ElementKind elementKind = ElementKind.VARIABLE;
13.1087 -// if (Character.isUpperCase(name.charAt(0))) {
13.1088 -// // Class?
13.1089 -// elementKind = ElementKind.CLASS;
13.1090 -// }
13.1091 -// IndexedElement element = new IndexedElement(name, elementKind, url, null);
13.1092 -// element.setSmart(true);
13.1093 -// elements.add(element);
13.1094 -// // TODO - imported class symbls should be shown as classes!
13.1095 -// }
13.1096 -// }
13.1097 -
13.1098 - // Always include the current file as imported
13.1099 - String moduleName = null;
13.1100 - if (context != null) {
13.1101 - moduleName = PythonUtils.getModuleName(context.getSnapshot().getSource().getFileObject());
13.1102 - modules.add(moduleName);
13.1103 - }
13.1104 -
13.1105 - modules.addAll(BUILTIN_MODULES);
13.1106 -
13.1107 - addImportedElements(prefix, kind, modules, elements, null);
13.1108 -
13.1109 - return elements;
13.1110 - }
13.1111 - public Set<String> getImportedFromWildcards(List<ImportFrom> importsFrom) {
13.1112 - Set<String> symbols = new HashSet<>(100);
13.1113 -
13.1114 - // Look up the imports and compute all the symbols we get from the import
13.1115 - Set<String> modules = new HashSet<>();
13.1116 -
13.1117 - // ImportsFrom require no index lookup
13.1118 - for (ImportFrom from : importsFrom) {
13.1119 - List<alias> names = from.getInternalNames();
13.1120 - if (names != null) {
13.1121 - for (alias at : names) {
13.1122 - if ("*".equals(at.getInternalName())) { // NOI18N
13.1123 - modules.add(from.getInternalModule());
13.1124 - }
13.1125 - }
13.1126 - }
13.1127 - }
13.1128 -
13.1129 - String[] terms = { PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MODULE_NAME };
13.1130 -
13.1131 - // Look up all symbols
13.1132 - for (String module : modules) {
13.1133 - // TODO - cache builtins?
13.1134 - Set<String> moduleSymbols = symbols;
13.1135 - boolean isSystem = isSystemModule(module);
13.1136 - if (isSystem) {
13.1137 - Set<String> s = wildcardImports.get(module);
13.1138 - if (s != null) {
13.1139 - symbols.addAll(s);
13.1140 - continue;
13.1141 - } else {
13.1142 - moduleSymbols = new HashSet<>(100);
13.1143 - }
13.1144 - }
13.1145 -
13.1146 -
13.1147 - final Set<IndexResult> result = new HashSet<>();
13.1148 - // TODO - handle case sensitivity better...
13.1149 -
13.1150 - search(PythonIndexer.FIELD_MODULE_NAME, module, QuerySupport.Kind.EXACT, result, terms);
13.1151 -
13.1152 - for (IndexResult map : result) {
13.1153 - String[] items = map.getValues(PythonIndexer.FIELD_ITEM);
13.1154 - if (items != null) {
13.1155 - for (String signature : items) {
13.1156 - int semi = signature.indexOf(';');
13.1157 - assert semi != -1;
13.1158 - int flags = IndexedElement.decode(signature, semi + 3, 0);
13.1159 - if ((flags & IndexedElement.PRIVATE) != 0) {
13.1160 - // Skip private symbols - can't import those
13.1161 - continue;
13.1162 - }
13.1163 -
13.1164 - String name = signature.substring(0, semi);
13.1165 - moduleSymbols.add(name);
13.1166 - }
13.1167 - }
13.1168 - }
13.1169 -
13.1170 - if (isSystem) {
13.1171 - assert moduleSymbols != symbols;
13.1172 - symbols.addAll(moduleSymbols);
13.1173 - wildcardImports.put(module, moduleSymbols);
13.1174 - }
13.1175 - }
13.1176 -
13.1177 - return symbols;
13.1178 - }
13.1179 -
13.1180 - public Set<IndexedElement> getImportedElements(String prefix, QuerySupport.Kind kind, Set<String> modules, Set<String> systemModuleHolder) {
13.1181 - Set<IndexedElement> elements = new HashSet<>();
13.1182 -
13.1183 - addImportedElements(prefix, kind, modules, elements, systemModuleHolder);
13.1184 -
13.1185 - return elements;
13.1186 - }
13.1187 -
13.1188 - public boolean isSystemModule(String module) {
13.1189 - if (systemModules == null) {
13.1190 - systemModules = new HashSet<>(800); // measured: 623
13.1191 - String[] terms = { PythonIndexer.FIELD_MODULE_ATTR_NAME,
13.1192 - PythonIndexer.FIELD_MODULE_NAME };
13.1193 - final Set<IndexResult> result = new HashSet<>();
13.1194 -
13.1195 - // This doesn't work because the attrs field isn't searchable:
13.1196 - //search(PythonIndexer.FIELD_MODULE_ATTR_NAME, "S", QuerySupport.Kind.PREFIX, result, ALL_SCOPE, terms);
13.1197 - //for (IndexResult map : result) {
13.1198 - // assert map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME).indexOf("S") != -1;
13.1199 - // systemModules.add(map.getValue(PythonIndexer.FIELD_MODULE_NAME));
13.1200 - //}
13.1201 -
13.1202 - search(PythonIndexer.FIELD_MODULE_NAME, "", QuerySupport.Kind.PREFIX, result, terms);
13.1203 -
13.1204 - for (IndexResult map : result) {
13.1205 - String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
13.1206 - if (attrs != null && attrs.indexOf('S') != -1) {
13.1207 - String mod = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
13.1208 - systemModules.add(mod);
13.1209 - }
13.1210 - }
13.1211 - }
13.1212 -
13.1213 - return systemModules.contains(module);
13.1214 - }
13.1215 -
13.1216 - public boolean isLowercaseClassName(String clz) {
13.1217 - if (availableClasses == null) {
13.1218 - availableClasses = new HashSet<>(300); // measured: 193
13.1219 - final Set<IndexResult> result = new HashSet<>();
13.1220 -
13.1221 - search(PythonIndexer.FIELD_CLASS_NAME, "", QuerySupport.Kind.PREFIX, result, PythonIndexer.FIELD_CLASS_NAME);
13.1222 -
13.1223 - for (IndexResult map : result) {
13.1224 - String c = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.1225 - if (c != null && !Character.isUpperCase(c.charAt(0))) {
13.1226 - availableClasses.add(c);
13.1227 - }
13.1228 - }
13.1229 - }
13.1230 -
13.1231 - return availableClasses.contains(clz);
13.1232 - }
13.1233 -
13.1234 - public void addImportedElements(String prefix, QuerySupport.Kind kind, Set<String> modules, Set<IndexedElement> elements, Set<String> systemModuleHolder) {
13.1235 -
13.1236 - String[] terms = { PythonIndexer.FIELD_ITEM,
13.1237 - PythonIndexer.FIELD_MODULE_ATTR_NAME,
13.1238 - PythonIndexer.FIELD_MODULE_NAME };
13.1239 -
13.1240 - // Look up all symbols
13.1241 - for (String module : modules) {
13.1242 - boolean isBuiltin = isBuiltinModule(module);
13.1243 - boolean isSystem = isBuiltin;
13.1244 -
13.1245 - final Set<IndexResult> result = new HashSet<>();
13.1246 - // TODO - handle case sensitivity better...
13.1247 -
13.1248 - search(PythonIndexer.FIELD_MODULE_NAME, module, QuerySupport.Kind.EXACT, result, terms);
13.1249 - int prefixLength = prefix.length();
13.1250 -
13.1251 - for (IndexResult map : result) {
13.1252 - String url = map.getUrl().toExternalForm();
13.1253 - String[] items = map.getValues(PythonIndexer.FIELD_ITEM);
13.1254 - if (items != null) {
13.1255 - String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
13.1256 - if (attrs != null && attrs.indexOf('S') != -1) {
13.1257 - isSystem = true;
13.1258 - }
13.1259 - for (String signature : items) {
13.1260 - if (signature.startsWith(prefix)) {
13.1261 - if (kind == QuerySupport.Kind.EXACT) {
13.1262 - if (signature.charAt(prefixLength) != ';') {
13.1263 - continue;
13.1264 - }
13.1265 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, prefix, 0, prefix.length())) {
13.1266 - continue;
13.1267 - } else {
13.1268 - // REGEXP, CAMELCASE filtering etc. not supported here
13.1269 - assert (kind == QuerySupport.Kind.PREFIX) ||
13.1270 - (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
13.1271 - }
13.1272 -
13.1273 - IndexedElement element = IndexedElement.create(signature, module, url, null);
13.1274 - if (element.isPrivate()) {
13.1275 - continue;
13.1276 - }
13.1277 - if (isBuiltin) {
13.1278 - element.setRhs("<i>builtin</i>");
13.1279 - } else {
13.1280 - element.setSmart(true);
13.1281 - }
13.1282 - element.setInherited(true);
13.1283 - elements.add(element);
13.1284 - }
13.1285 - }
13.1286 - }
13.1287 - }
13.1288 -
13.1289 - if (systemModuleHolder != null && isSystem) {
13.1290 - systemModuleHolder.add(module);
13.1291 - }
13.1292 - }
13.1293 - }
13.1294 -
13.1295 - public Set<IndexedElement> getExceptions(String prefix, QuerySupport.Kind kind) {
13.1296 - final Set<IndexResult> result = new HashSet<>();
13.1297 - String[] terms = { PythonIndexer.FIELD_EXTENDS_NAME,
13.1298 - PythonIndexer.FIELD_CLASS_NAME,
13.1299 - PythonIndexer.FIELD_CLASS_ATTR_NAME,
13.1300 - PythonIndexer.FIELD_IN };
13.1301 - search(PythonIndexer.FIELD_EXTENDS_NAME, "", QuerySupport.Kind.PREFIX, result, terms); // NOI18N
13.1302 - Map<String, String> extendsMap = new HashMap<>(100);
13.1303 - // First iteration: Compute inheritance hierarchy
13.1304 - for (IndexResult map : result) {
13.1305 -
13.1306 - String superClass = map.getValue(PythonIndexer.FIELD_EXTENDS_NAME);
13.1307 - if (superClass != null) {
13.1308 - String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.1309 - if (clz != null) {
13.1310 - extendsMap.put(clz, superClass);
13.1311 - }
13.1312 - }
13.1313 - }
13.1314 -
13.1315 - // Compute set of classes that extend Exception
13.1316 -
13.1317 - Set<String> exceptionClasses = new HashSet<>();
13.1318 - Set<String> notExceptionClasses = new HashSet<>();
13.1319 - exceptionClasses.add("Exception"); // NOI18N
13.1320 - Outer:
13.1321 - for (String cls : extendsMap.keySet()) {
13.1322 - if (notExceptionClasses.contains(cls)) {
13.1323 - continue;
13.1324 - } else if (!exceptionClasses.contains(cls)) {
13.1325 - // See if this extends exception:
13.1326 - String c = cls;
13.1327 - int depth = 0;
13.1328 - while (c != null) {
13.1329 - c = extendsMap.get(c);
13.1330 - String prev = null;
13.1331 - if (c != null) {
13.1332 - if (exceptionClasses.contains(c)) {
13.1333 - exceptionClasses.add(cls);
13.1334 - continue Outer;
13.1335 - }
13.1336 - depth++;
13.1337 - if (depth == 15) {
13.1338 - // we're probably going in circles, perhaps a extends b extends a.
13.1339 - // This doesn't really happen in Python, but can happen when there
13.1340 - // are unrelated classes with the same name getting treated as one here -
13.1341 - // class a in library X, and class a in library Y,
13.1342 - break;
13.1343 - }
13.1344 - } else if (prev != null) {
13.1345 - notExceptionClasses.add(prev);
13.1346 - break;
13.1347 - }
13.1348 - }
13.1349 - notExceptionClasses.add(cls);
13.1350 - }
13.1351 - }
13.1352 -
13.1353 - // Next add elements for all the exceptions
13.1354 - final Set<IndexedElement> classes = new HashSet<>();
13.1355 - for (IndexResult map : result) {
13.1356 - String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.1357 - if (clz == null || !exceptionClasses.contains(clz)) {
13.1358 - continue;
13.1359 - }
13.1360 -
13.1361 - if ((kind == QuerySupport.Kind.PREFIX) && !clz.startsWith(prefix)) {
13.1362 - continue;
13.1363 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !clz.regionMatches(true, 0, prefix, 0, prefix.length())) {
13.1364 - continue;
13.1365 - } else if (kind == QuerySupport.Kind.EXACT && !clz.equals(prefix)) {
13.1366 - continue;
13.1367 - }
13.1368 -
13.1369 - String url = map.getUrl().toExternalForm();
13.1370 - String module = map.getValue(PythonIndexer.FIELD_IN);
13.1371 - IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
13.1372 - String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
13.1373 - if (attrs != null) {
13.1374 - int flags = IndexedElement.decode(attrs, 0, 0);
13.1375 - element.setFlags(flags);
13.1376 - }
13.1377 - classes.add(element);
13.1378 - }
13.1379 -
13.1380 - return classes;
13.1381 - }
13.1382 -
13.1383 - /** Find the subclasses of the given class name, with the POSSIBLE fqn from the
13.1384 - * context of the usage. */
13.1385 - public Set<IndexedElement> getSubClasses(String fqn, String possibleFqn, String name, boolean directOnly) {
13.1386 - //String field = PythonIndexer.FIELD_FQN_NAME;
13.1387 - Set<IndexedElement> classes = new HashSet<>();
13.1388 - Set<String> scannedClasses = new HashSet<>();
13.1389 - Set<String> seenClasses = new HashSet<>();
13.1390 -
13.1391 - if (fqn != null) {
13.1392 - addSubclasses(fqn, classes, seenClasses, scannedClasses, directOnly);
13.1393 - } else {
13.1394 - fqn = possibleFqn;
13.1395 - if (name.equals(possibleFqn)) {
13.1396 - fqn = null;
13.1397 - }
13.1398 -
13.1399 - // Try looking at the libraries too
13.1400 - while ((classes.size() == 0) && (fqn != null && fqn.length() > 0)) {
13.1401 - // TODO - use the boolvalue from addclasses instead!
13.1402 - boolean found = addSubclasses(fqn + "::" + name, classes, seenClasses, scannedClasses, directOnly);
13.1403 - if (found) {
13.1404 - return classes;
13.1405 - }
13.1406 -
13.1407 - int f = fqn.lastIndexOf("::");
13.1408 -
13.1409 - if (f == -1) {
13.1410 - break;
13.1411 - } else {
13.1412 - fqn = fqn.substring(0, f);
13.1413 - }
13.1414 - }
13.1415 -
13.1416 - if (classes.size() == 0) {
13.1417 - addSubclasses(name, classes, seenClasses, scannedClasses, directOnly);
13.1418 - }
13.1419 - }
13.1420 -
13.1421 - return classes;
13.1422 - }
13.1423 -
13.1424 - private boolean addSubclasses(String classFqn, Set<IndexedElement> classes, Set<String> seenClasses, Set<String> scannedClasses, boolean directOnly) {
13.1425 - // Prevent problems with circular includes or redundant includes
13.1426 - if (scannedClasses.contains(classFqn)) {
13.1427 - return false;
13.1428 - }
13.1429 -
13.1430 - scannedClasses.add(classFqn);
13.1431 -
13.1432 - String searchField = PythonIndexer.FIELD_EXTENDS_NAME;
13.1433 -
13.1434 - Set<IndexResult> result = new HashSet<>();
13.1435 -
13.1436 - String[] terms = { PythonIndexer.FIELD_IN,
13.1437 - PythonIndexer.FIELD_EXTENDS_NAME,
13.1438 - PythonIndexer.FIELD_CLASS_ATTR_NAME,
13.1439 - PythonIndexer.FIELD_CLASS_NAME };
13.1440 -
13.1441 - search(searchField, classFqn, QuerySupport.Kind.EXACT, result, terms);
13.1442 -
13.1443 - boolean foundIt = result.size() > 0;
13.1444 -
13.1445 - // If this is a bogus class entry (no search rsults) don't continue
13.1446 - if (!foundIt) {
13.1447 - return foundIt;
13.1448 - }
13.1449 -
13.1450 - for (IndexResult map : result) {
13.1451 - String className = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
13.1452 - if (className != null && !seenClasses.contains(className)) {
13.1453 - String url = map.getUrl().toExternalForm();
13.1454 - String module = map.getValue(PythonIndexer.FIELD_IN);
13.1455 - IndexedElement clz = new IndexedElement(className, ElementKind.CLASS, url, module, null, null);
13.1456 - String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
13.1457 - if (attrs != null) {
13.1458 - int flags = IndexedElement.decode(attrs, 0, 0);
13.1459 - clz.setFlags(flags);
13.1460 - }
13.1461 - classes.add(clz);
13.1462 -
13.1463 - seenClasses.add(className);
13.1464 -
13.1465 - if (!directOnly) {
13.1466 - addSubclasses(className, classes, seenClasses, scannedClasses, directOnly);
13.1467 - }
13.1468 - }
13.1469 - }
13.1470 -
13.1471 - return foundIt;
13.1472 - }
13.1473 -}
14.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonIndexSearcher.java Fri Sep 18 16:20:24 2015 -0500
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,252 +0,0 @@
14.4 -/*
14.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
14.6 - *
14.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
14.8 - *
14.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
14.10 - * Other names may be trademarks of their respective owners.
14.11 - *
14.12 - * The contents of this file are subject to the terms of either the GNU
14.13 - * General Public License Version 2 only ("GPL") or the Common
14.14 - * Development and Distribution License("CDDL") (collectively, the
14.15 - * "License"). You may not use this file except in compliance with the
14.16 - * License. You can obtain a copy of the License at
14.17 - * http://www.netbeans.org/cddl-gplv2.html
14.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
14.19 - * specific language governing permissions and limitations under the
14.20 - * License. When distributing the software, include this License Header
14.21 - * Notice in each file and include the License file at
14.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
14.23 - * particular file as subject to the "Classpath" exception as provided
14.24 - * by Oracle in the GPL Version 2 section of the License file that
14.25 - * accompanied this code. If applicable, add the following below the
14.26 - * License Header, with the fields enclosed by brackets [] replaced by
14.27 - * your own identifying information:
14.28 - * "Portions Copyrighted [year] [name of copyright owner]"
14.29 - *
14.30 - * Contributor(s):
14.31 - *
14.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
14.33 - */
14.34 -package org.netbeans.modules.python.editor;
14.35 -
14.36 -import java.awt.Toolkit;
14.37 -import java.util.HashSet;
14.38 -import java.util.Set;
14.39 -import java.util.logging.Logger;
14.40 -import javax.swing.Icon;
14.41 -import org.netbeans.modules.python.editor.elements.IndexedElement;
14.42 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
14.43 -import org.netbeans.api.project.FileOwnerQuery;
14.44 -import org.netbeans.api.project.Project;
14.45 -import org.netbeans.api.project.ProjectInformation;
14.46 -import org.netbeans.api.project.ProjectUtils;
14.47 -import org.netbeans.modules.csl.api.ElementHandle;
14.48 -import org.netbeans.modules.csl.api.IndexSearcher;
14.49 -import org.netbeans.modules.csl.api.IndexSearcher.Descriptor;
14.50 -import org.netbeans.modules.csl.api.IndexSearcher.Helper;
14.51 -import org.netbeans.modules.csl.spi.GsfUtilities;
14.52 -import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
14.53 -import org.openide.filesystems.FileObject;
14.54 -import org.openide.util.ImageUtilities;
14.55 -import org.python.antlr.PythonTree;
14.56 -
14.57 -/**
14.58 - *
14.59 - * @author Tor Norbye
14.60 - */
14.61 -public class PythonIndexSearcher implements IndexSearcher {
14.62 -
14.63 - @Override
14.64 - public Set<? extends Descriptor> getTypes(Project prjct, String textForQuery, QuerySupport.Kind kind, Helper helper) {
14.65 - PythonIndex index = PythonIndex.get(prjct);
14.66 - Set<PythonSymbol> result = new HashSet<>();
14.67 - Set<? extends IndexedElement> elements;
14.68 -
14.69 - // TODO - do some filtering if you use ./#
14.70 - // int dot = textForQuery.lastIndexOf('.');
14.71 - // if (dot != -1 && (kind == QuerySupport.Kind.PREFIX || kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX)) {
14.72 - // String prefix = textForQuery.substring(dot+1);
14.73 - // String in = textForQuery.substring(0, dot);
14.74 -
14.75 - elements = index.getClasses(textForQuery, kind, null, true);
14.76 - for (IndexedElement element : elements) {
14.77 - result.add(new PythonSymbol(element, helper));
14.78 - }
14.79 -
14.80 - return result;
14.81 - }
14.82 -
14.83 - @Override
14.84 - public Set<? extends Descriptor> getSymbols(Project prjct, String textForQuery, QuerySupport.Kind kind, Helper helper) {
14.85 - PythonIndex index = PythonIndex.get(prjct);
14.86 - Set<PythonSymbol> result = new HashSet<>();
14.87 - Set<? extends IndexedElement> elements;
14.88 -
14.89 - // TODO - do some filtering if you use ./#
14.90 - // int dot = textForQuery.lastIndexOf('.');
14.91 - // if (dot != -1 && (kind == QuerySupport.Kind.PREFIX || kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX)) {
14.92 - // String prefix = textForQuery.substring(dot+1);
14.93 - // String in = textForQuery.substring(0, dot);
14.94 -
14.95 - elements = index.getAllMembers(textForQuery, kind, null, true);
14.96 - for (IndexedElement element : elements) {
14.97 - result.add(new PythonSymbol(element, helper));
14.98 - }
14.99 - elements = index.getClasses(textForQuery, kind, null, true);
14.100 - for (IndexedElement element : elements) {
14.101 - result.add(new PythonSymbol(element, helper));
14.102 - }
14.103 - elements = index.getModules(textForQuery, kind);
14.104 - for (IndexedElement element : elements) {
14.105 - result.add(new PythonSymbol(element, helper));
14.106 - }
14.107 -
14.108 - return result;
14.109 - }
14.110 -
14.111 - private class PythonSymbol extends Descriptor {
14.112 - private final IndexedElement element;
14.113 - private String projectName;
14.114 - private Icon projectIcon;
14.115 - private final Helper helper;
14.116 - private boolean isLibrary;
14.117 - private static final String ICON_PATH = "org/netbeans/modules/python/editor/resources/pyc_16.png"; //NOI18N
14.118 -
14.119 - public PythonSymbol(IndexedElement element, Helper helper) {
14.120 - this.element = element;
14.121 - this.helper = helper;
14.122 - }
14.123 -
14.124 - @Override
14.125 - public Icon getIcon() {
14.126 - if (projectName == null) {
14.127 - initProjectInfo();
14.128 - }
14.129 - //if (isLibrary) {
14.130 - // return new ImageIcon(org.openide.util.ImageUtilities.loadImage(PYTHON_KEYWORD));
14.131 - //}
14.132 - return helper.getIcon(element);
14.133 - }
14.134 -
14.135 - @Override
14.136 - public String getTypeName() {
14.137 - return element.getName();
14.138 - }
14.139 -
14.140 - @Override
14.141 - public String getProjectName() {
14.142 - if (projectName == null) {
14.143 - initProjectInfo();
14.144 - }
14.145 - return projectName;
14.146 - }
14.147 -
14.148 - private void initProjectInfo() {
14.149 - FileObject fo = element.getFileObject();
14.150 - if (fo != null) {
14.151 -// File f = FileUtil.toFile(fo);
14.152 - Project p = FileOwnerQuery.getOwner(fo);
14.153 - if (p != null) {
14.154 -// JsPlatform platform = JsPlatform.platformFor(p);
14.155 -// if (platform != null) {
14.156 -// String lib = platform.getLib();
14.157 -// if (lib != null && f.getPath().startsWith(lib)) {
14.158 -// projectName = "Js Library";
14.159 -// isLibrary = true;
14.160 -// }
14.161 -// } else {
14.162 - ProjectInformation pi = ProjectUtils.getInformation(p);
14.163 - projectName = pi.getDisplayName();
14.164 - projectIcon = pi.getIcon();
14.165 -// }
14.166 - }
14.167 - } else {
14.168 - isLibrary = true;
14.169 - Logger.getLogger(PythonIndexSearcher.class.getName()).fine("No fileobject for " + element.toString() + " with fileurl=" + element.getFilenameUrl());
14.170 - }
14.171 - if (projectName == null) {
14.172 - projectName = "";
14.173 - }
14.174 - }
14.175 -
14.176 - @Override
14.177 - public Icon getProjectIcon() {
14.178 - if (projectName == null) {
14.179 - initProjectInfo();
14.180 - }
14.181 - if (isLibrary) {
14.182 - return ImageUtilities.loadImageIcon(ICON_PATH, false);
14.183 - }
14.184 - return projectIcon;
14.185 - }
14.186 -
14.187 - @Override
14.188 - public FileObject getFileObject() {
14.189 - return element.getFileObject();
14.190 - }
14.191 -
14.192 - @Override
14.193 - public void open() {
14.194 - PythonParserResult[] parserResultRet = new PythonParserResult[1];
14.195 - PythonTree node = PythonAstUtils.getForeignNode(element, parserResultRet);
14.196 -
14.197 - if (node != null) {
14.198 - int astOffset = PythonAstUtils.getRange(node).getStart();
14.199 - int lexOffset = PythonLexerUtils.getLexerOffset(parserResultRet[0], astOffset);
14.200 - if (lexOffset == -1) {
14.201 - lexOffset = 0;
14.202 - }
14.203 - GsfUtilities.open(element.getFileObject(), lexOffset, element.getName());
14.204 - return;
14.205 - }
14.206 -
14.207 - FileObject fileObject = element.getFileObject();
14.208 - if (fileObject == null) {
14.209 - // This should no longer be needed - we perform auto deletion in GSF
14.210 - Toolkit.getDefaultToolkit().beep();
14.211 - return;
14.212 - }
14.213 -
14.214 - helper.open(fileObject, element);
14.215 - }
14.216 -
14.217 - @Override
14.218 - public String getContextName() {
14.219 - // XXX This is lame - move formatting logic to the goto action!
14.220 -// StringBuilder sb = new StringBuilder();
14.221 -// String require = element.getRequire();
14.222 -// String fqn = element.getFqn();
14.223 - String fqn = element.getIn() != null ? element.getIn() + "." + element.getName() : element.getName();
14.224 - if (element.getName().equals(fqn)) {
14.225 - fqn = null;
14.226 - String url = element.getFilenameUrl();
14.227 - if (url != null) {
14.228 - return url.substring(url.lastIndexOf('/') + 1);
14.229 - }
14.230 - }
14.231 -
14.232 - return fqn;
14.233 - }
14.234 -
14.235 - @Override
14.236 - public ElementHandle getElement() {
14.237 - return element;
14.238 - }
14.239 -
14.240 - @Override
14.241 - public int getOffset() {
14.242 - throw new UnsupportedOperationException("Not supported yet.");
14.243 - }
14.244 -
14.245 - @Override
14.246 - public String getSimpleName() {
14.247 - return element.getName();
14.248 - }
14.249 -
14.250 - @Override
14.251 - public String getOuterName() {
14.252 - return null;
14.253 - }
14.254 - }
14.255 -}
15.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonIndexer.java Fri Sep 18 16:20:24 2015 -0500
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,1400 +0,0 @@
15.4 -/*
15.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
15.6 - *
15.7 - * Copyright 1997-2010 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 - * Contributor(s):
15.31 - *
15.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
15.33 - */
15.34 -package org.netbeans.modules.python.editor;
15.35 -
15.36 -import java.io.File;
15.37 -import java.io.IOException;
15.38 -import java.net.MalformedURLException;
15.39 -import java.net.URL;
15.40 -import java.util.ArrayList;
15.41 -import java.util.Collections;
15.42 -import java.util.HashMap;
15.43 -import java.util.List;
15.44 -import java.util.Map;
15.45 -import java.util.logging.Level;
15.46 -import java.util.logging.Logger;
15.47 -import java.util.regex.Matcher;
15.48 -import java.util.regex.Pattern;
15.49 -import javax.swing.text.BadLocationException;
15.50 -import org.netbeans.editor.BaseDocument;
15.51 -import org.netbeans.modules.csl.spi.GsfUtilities;
15.52 -import org.netbeans.modules.csl.spi.ParserResult;
15.53 -import org.netbeans.modules.parsing.api.Snapshot;
15.54 -import org.netbeans.modules.parsing.spi.Parser;
15.55 -import org.netbeans.modules.parsing.spi.indexing.Context;
15.56 -import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer;
15.57 -import org.netbeans.modules.parsing.spi.indexing.Indexable;
15.58 -import org.netbeans.modules.parsing.spi.indexing.support.IndexDocument;
15.59 -import org.netbeans.modules.parsing.spi.indexing.support.IndexingSupport;
15.60 -import org.netbeans.modules.python.api.PythonPlatform;
15.61 -import org.netbeans.modules.python.api.PythonPlatformManager;
15.62 -import org.netbeans.modules.python.editor.elements.IndexedElement;
15.63 -import org.netbeans.modules.python.editor.hints.Deprecations;
15.64 -import org.netbeans.modules.python.editor.scopes.ScopeConstants;
15.65 -import org.netbeans.modules.python.editor.scopes.ScopeInfo;
15.66 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
15.67 -import org.netbeans.modules.python.editor.scopes.SymInfo;
15.68 -import org.openide.filesystems.FileObject;
15.69 -import org.openide.filesystems.FileStateInvalidException;
15.70 -import org.openide.filesystems.FileUtil;
15.71 -import org.openide.filesystems.URLMapper;
15.72 -import org.openide.util.Exceptions;
15.73 -import org.python.antlr.PythonTree;
15.74 -import org.python.antlr.ast.ClassDef;
15.75 -import org.python.antlr.ast.FunctionDef;
15.76 -import org.python.antlr.ast.Module;
15.77 -import org.python.antlr.ast.Name;
15.78 -import org.python.antlr.base.expr;
15.79 -
15.80 -/**
15.81 - *
15.82 - * @todo Store information about all symbols exported by a module.
15.83 - * I can use that to provide "unused import" help.
15.84 - * @todo Clean this stuff up: store data, functions, etc.
15.85 - * @todo Improve detection of builtins. Perhaps run from within Python,
15.86 - * something like this:
15.87 ->>> dir(__builtins__)
15.88 -['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', 'abs', 'all', 'any', 'apply', 'basestring', 'bool', 'buffer', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
15.89 - *
15.90 - * My code for scanning for functions has to be smarter:
15.91 -.. function:: ljust(s, width)
15.92 -rjust(s, width)
15.93 -center(s, width)
15.94 - * Here I need to pick up all 3 signatures!
15.95 - * @author Tor Norbye
15.96 - */
15.97 -public class PythonIndexer extends EmbeddingIndexer {
15.98 - public static final String NAME = "PythonIndexer";
15.99 - public static final int VERSION = 1;
15.100 - public static boolean PREINDEXING = Boolean.getBoolean("gsf.preindexing"); // NOI18N
15.101 - public static final String FIELD_MEMBER = "member"; //NOI18N
15.102 - public static final String FIELD_MODULE_NAME = "module"; //NOI18N
15.103 - public static final String FIELD_MODULE_ATTR_NAME = "modattrs"; //NOI18N
15.104 - public static final String FIELD_CLASS_ATTR_NAME = "clzattrs"; //NOI18N
15.105 - public static final String FIELD_EXTENDS_NAME = "extends"; //NOI18N
15.106 - public static final String FIELD_ITEM = "item"; //NOI18N
15.107 - public static final String FIELD_IN = "in"; //NOI18N
15.108 - public static final String FIELD_CLASS_NAME = "class"; //NOI18N
15.109 - public static final String FIELD_CASE_INSENSITIVE_CLASS_NAME = "class-ig"; //NOI18N
15.110 - private FileObject prevParent;
15.111 - private boolean prevResult;
15.112 -
15.113 - public static boolean isIndexable(Indexable indexable, Snapshot snapshot) {
15.114 - FileObject fo = snapshot.getSource().getFileObject();
15.115 - String extension = fo.getExt();
15.116 - if ("py".equals(extension)) { // NOI18N
15.117 - return true;
15.118 - }
15.119 -
15.120 - if ("rst".equals(extension)) { // NOI18N
15.121 - // Index restructured text if it looks like it contains Python library
15.122 - // definitions
15.123 - return true;
15.124 - }
15.125 -
15.126 - if ("egg".equals(extension)) { // NOI18N
15.127 - return true;
15.128 - }
15.129 -
15.130 - return false;
15.131 - }
15.132 -
15.133 -
15.134 - public boolean isIndexable(Snapshot file) {
15.135 - FileObject fo = file.getSource().getFileObject();
15.136 - String extension = fo.getExt();
15.137 - if ("py".equals(extension)) { // NOI18N
15.138 -
15.139 - // Skip "test" folders under lib... Lots of weird files there
15.140 - // and we don't want to pollute the index with them
15.141 - FileObject parent = fo.getParent();
15.142 -
15.143 - if (parent != null && parent.getName().equals("test")) { // NOI18N
15.144 - // Make sure it's really a lib folder, we want to include the
15.145 - // user's files
15.146 -
15.147 - // Avoid double-indexing files that have multiple versions - e.g. foo.js and foo-min.js
15.148 - // or foo.uncompressed
15.149 - FileObject parentFo = fo.getParent();
15.150 - if (prevParent == parentFo) {
15.151 - return prevResult;
15.152 - }
15.153 - prevResult = true;
15.154 - prevParent = parentFo;
15.155 - PythonPlatformManager manager = PythonPlatformManager.getInstance();
15.156 - Platforms:
15.157 - for (String name : manager.getPlatformList()) {
15.158 - PythonPlatform platform = manager.getPlatform(name);
15.159 - if (platform != null) {
15.160 - for (FileObject root : platform.getLibraryRoots()) {
15.161 - if (FileUtil.isParentOf(root, parentFo)) {
15.162 - prevResult = false;
15.163 - break Platforms;
15.164 - }
15.165 - }
15.166 - }
15.167 - }
15.168 - }
15.169 -
15.170 - return true;
15.171 - }
15.172 -
15.173 - if ("rst".equals(extension)) { // NOI18N
15.174 - // Index restructured text if it looks like it contains Python library
15.175 - // definitions
15.176 - return true;
15.177 - }
15.178 -
15.179 - if ("egg".equals(extension)) { // NOI18N
15.180 - return true;
15.181 - }
15.182 -
15.183 - return false;
15.184 - }
15.185 -
15.186 - @Override
15.187 - protected void index(Indexable indexable, Parser.Result result, Context context) {
15.188 - PythonParserResult parseResult = (PythonParserResult)result;
15.189 - if (parseResult == null) {
15.190 - return;
15.191 - }
15.192 -
15.193 - IndexingSupport support;
15.194 - try {
15.195 - support = IndexingSupport.getInstance(context);
15.196 - } catch (IOException ioe) {
15.197 - LOG.log(Level.WARNING, null, ioe);
15.198 - return;
15.199 - }
15.200 -
15.201 - support.removeDocuments(indexable);
15.202 -
15.203 - FileObject fileObject = result.getSnapshot().getSource().getFileObject();
15.204 - String extension = fileObject.getNameExt();
15.205 -
15.206 - if (extension.endsWith(".rst")) { // NOI18N
15.207 - scanRst(fileObject, indexable, support, null);
15.208 - } else if (extension.endsWith(".egg")) { // NOI18N
15.209 - scanEgg(fileObject, indexable, parseResult, support);
15.210 - } else {
15.211 - // Normal python file
15.212 - new IndexTask(parseResult, support).scan();
15.213 - }
15.214 - }
15.215 - private static final Logger LOG = Logger.getLogger(PythonIndexer.class.getName());
15.216 -
15.217 - public boolean acceptQueryPath(String url) {
15.218 - return !url.contains("jsstubs"); // NOI18N
15.219 - }
15.220 -
15.221 - public String getPersistentUrl(File file) {
15.222 - String url;
15.223 - try {
15.224 - url = file.toURI().toURL().toExternalForm();
15.225 -
15.226 - // Make relative URLs for urls in the libraries
15.227 - return PythonIndex.getPreindexUrl(url);
15.228 - } catch (MalformedURLException ex) {
15.229 - Exceptions.printStackTrace(ex);
15.230 - return file.getPath();
15.231 - }
15.232 - }
15.233 -
15.234 - public String getIndexVersion() {
15.235 - return "0.123"; // NOI18N
15.236 - }
15.237 -
15.238 - public String getIndexerName() {
15.239 - return "python"; // NOI18N
15.240 - }
15.241 -
15.242 - public FileObject getPreindexedDb() {
15.243 - return null;
15.244 - }
15.245 -
15.246 - private static void appendFlags(StringBuilder sb, char c, SymInfo sym, int flags) {
15.247 - sb.append(';');
15.248 - sb.append(c);
15.249 - sb.append(';');
15.250 -
15.251 - if (sym.isPrivate()) {
15.252 - flags |= IndexedElement.PRIVATE;
15.253 - }
15.254 - if (c == 'c') {
15.255 - flags |= IndexedElement.CONSTRUCTOR;
15.256 - }
15.257 -
15.258 - sb.append(IndexedElement.encode(flags));
15.259 - sb.append(';');
15.260 - }
15.261 - private static final int DEFAULT_DOC_SIZE = 40; // TODO Measure
15.262 -
15.263 - private static class IndexTask {
15.264 - private PythonParserResult result;
15.265 - private FileObject file;
15.266 - private IndexingSupport support;
15.267 - private List<IndexDocument> documents = new ArrayList<>();
15.268 - private String url;
15.269 - private String module;
15.270 - private SymbolTable symbolTable;
15.271 - private String overrideUrl;
15.272 -
15.273 - private IndexTask(PythonParserResult result, IndexingSupport support) {
15.274 - this.result = result;
15.275 - this.file = result.getSnapshot().getSource().getFileObject();
15.276 - this.support = support;
15.277 -
15.278 - module = PythonUtils.getModuleName(file);
15.279 - //PythonTree root = PythonAstUtils.getRoot(result);
15.280 - //if (root instanceof Module) {
15.281 - // Str moduleDoc = PythonAstUtils.getDocumentationNode(root);
15.282 - // if (moduleDoc != null) {
15.283 - // moduleAttributes = "d(" + moduleDoc.getCharStartIndex() + ")";
15.284 - // }
15.285 - //}
15.286 - }
15.287 -
15.288 - private IndexTask(PythonParserResult result, IndexingSupport support, String overrideUrl) {
15.289 - this(result, support);
15.290 - this.overrideUrl = overrideUrl;
15.291 - }
15.292 -
15.293 - public List<IndexDocument> scan() {
15.294 - url = file.toURL().toExternalForm();
15.295 - // Make relative URLs for urls in the libraries
15.296 - url = PythonIndex.getPreindexUrl(url);
15.297 -
15.298 - IndexDocument doc = createDocument();
15.299 - doc.addPair(FIELD_MODULE_NAME, module, true, true);
15.300 -
15.301 - String moduleAttrs = null;
15.302 - if (url.startsWith(PythonIndex.CLUSTER_URL) || url.startsWith(PythonIndex.PYTHONHOME_URL)) {
15.303 - moduleAttrs = "S"; // NOI18N
15.304 - } else if (PREINDEXING) {
15.305 - String prj = System.getProperty("gsf.preindexing.projectpath");
15.306 - if (prj != null && !url.contains(prj)) {
15.307 - System.err.println("WARNING -- not marking url " + url + " from " + file + " as a system library!");
15.308 - }
15.309 - }
15.310 - if (Deprecations.isDeprecatedModule(module)) {
15.311 - if (moduleAttrs == null) {
15.312 - moduleAttrs = "D"; // NOI18N
15.313 - } else {
15.314 - moduleAttrs += "D"; // NOI18N
15.315 - }
15.316 - }
15.317 - if (moduleAttrs != null) {
15.318 - doc.addPair(FIELD_MODULE_ATTR_NAME, moduleAttrs, false, true);
15.319 - }
15.320 -
15.321 - PythonTree root = PythonAstUtils.getRoot(result);
15.322 - if (root == null) {
15.323 - return documents;
15.324 - }
15.325 - if (!(root instanceof Module)) {
15.326 - // Unexpected... http://netbeans.org/bugzilla/show_bug.cgi?id=165756
15.327 - // Maybe some kind of top level error node?
15.328 - System.err.println("WARNING - top level AST node type was " + root + " of type " + root.getClass().getName());
15.329 - return documents;
15.330 - }
15.331 - symbolTable = result.getSymbolTable();
15.332 - ScopeInfo scopeInfo = symbolTable.getScopeInfo(root);
15.333 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
15.334 - String name = entry.getKey();
15.335 - SymInfo sym = entry.getValue();
15.336 -
15.337 - if (sym.isClass()) {
15.338 - StringBuilder sig = new StringBuilder();
15.339 - sig.append(name);
15.340 - appendFlags(sig, 'C', sym, 0);
15.341 - doc.addPair(FIELD_ITEM, sig.toString(), true, true);
15.342 -
15.343 - if (sym.node instanceof ClassDef) {
15.344 - assert sym.node instanceof ClassDef : sym.node;
15.345 - indexClass(name, sym, (ClassDef)sym.node);
15.346 - } else {
15.347 - // Could be a symbol defined both as a class and a function
15.348 - // (conditionally) such as _Environ in minicompat.py,
15.349 - // and another trigger in socket.py.
15.350 - }
15.351 - } else if (sym.isFunction()) {
15.352 - if (sym.node instanceof Name) {
15.353 - assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
15.354 - }
15.355 - assert sym.node instanceof FunctionDef : sym.node;
15.356 - FunctionDef def = (FunctionDef)sym.node;
15.357 - String sig = computeFunctionSig(name, def, sym);
15.358 - doc.addPair(FIELD_ITEM, sig, true, true);
15.359 - } else if (sym.isImported()) {
15.360 - if (!"*".equals(name)) { // NOI18N
15.361 - StringBuilder sig = new StringBuilder();
15.362 - sig.append(name);
15.363 - appendFlags(sig, 'I', sym, 0);
15.364 - doc.addPair(FIELD_ITEM, sig.toString(), true, true);
15.365 - }
15.366 - } else if (sym.isGeneratorExp()) {
15.367 - StringBuilder sig = new StringBuilder();
15.368 - sig.append(name);
15.369 - appendFlags(sig, 'G', sym, 0);
15.370 - doc.addPair(FIELD_ITEM, sig.toString(), true, true);
15.371 - } else if (sym.isData()) {
15.372 - StringBuilder sig = new StringBuilder();
15.373 - sig.append(name);
15.374 - appendFlags(sig, 'D', sym, 0);
15.375 - doc.addPair(FIELD_ITEM, sig.toString(), true, true);
15.376 - } else {
15.377 - // XXX what the heck is this??
15.378 - }
15.379 - }
15.380 -
15.381 - return documents;
15.382 - }
15.383 -
15.384 - private void indexClass(String className, SymInfo classSym, ClassDef clz) {
15.385 - IndexDocument classDocument = createDocument();
15.386 - classDocument.addPair(FIELD_IN, module, true, true);
15.387 -
15.388 - // Superclass
15.389 - List<expr> bases = clz.getInternalBases();
15.390 - if (bases != null) {
15.391 - for (expr base : bases) {
15.392 - String extendsName = PythonAstUtils.getExprName(base);
15.393 - if (extendsName != null) {
15.394 - classDocument.addPair(FIELD_EXTENDS_NAME, extendsName, true, true);
15.395 - }
15.396 - }
15.397 - }
15.398 -
15.399 - classDocument.addPair(FIELD_CLASS_NAME, className, true, true);
15.400 -
15.401 - if (classSym.isPrivate()) {
15.402 - // TODO - store Documented, Deprecated, DocOnly, etc.
15.403 - classDocument.addPair(FIELD_CLASS_ATTR_NAME, IndexedElement.encode(IndexedElement.PRIVATE), false, true);
15.404 - }
15.405 - classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, className.toLowerCase(), true, true);
15.406 -
15.407 - //Str doc = PythonAstUtils.getDocumentationNode(clz);
15.408 - //if (doc != null) {
15.409 - // StringBuilder sb = new StringBuilder();
15.410 - // sb.append("d("); // NOI18N
15.411 - // sb.append(doc.getCharStartIndex());
15.412 - // sb.append(")"); // NOI18N
15.413 - // classDocument.addPair(FIELD_CLASS_ATTRS, sb.toString(), false);
15.414 - //}
15.415 -
15.416 - ScopeInfo scopeInfo = symbolTable.getScopeInfo(clz);
15.417 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
15.418 - String name = entry.getKey();
15.419 - SymInfo sym = entry.getValue();
15.420 -
15.421 -// int flags = sym.flags;
15.422 -// assert !sym.isClass() : "found a class " + name + " of type " + sym.dumpFlags(scopeInfo) + " within class " + className + " in module " + module;
15.423 -// if (!(sym.isFunction() || sym.isMember() || sym.isData())) {
15.424 -// }
15.425 -// assert sym.isFunction() || sym.isMember() || sym.isData() : name + ";" + sym.toString();
15.426 -
15.427 - if (sym.isClass()) {
15.428 - // Triggers in httplib _socket_close inside FakeSocket
15.429 - StringBuilder sig = new StringBuilder();
15.430 - sig.append(name);
15.431 - appendFlags(sig, 'C', sym, 0);
15.432 - classDocument.addPair(FIELD_ITEM, sig.toString(), true, true);
15.433 -
15.434 - } else if (sym.isFunction() && sym.node instanceof FunctionDef) {
15.435 - if (sym.node instanceof Name) {
15.436 - assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
15.437 - }
15.438 - FunctionDef def = (FunctionDef)sym.node;
15.439 - String sig = computeFunctionSig(name, def, sym);
15.440 - classDocument.addPair(FIELD_MEMBER, sig, true, true);
15.441 - } else if (sym.isData()) {
15.442 - StringBuilder sig = new StringBuilder();
15.443 - sig.append(name);
15.444 - appendFlags(sig, 'D', sym, 0);
15.445 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
15.446 - } else if (sym.isMember()) {
15.447 - StringBuilder sig = new StringBuilder();
15.448 - sig.append(name);
15.449 - appendFlags(sig, 'A', sym, 0);
15.450 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
15.451 - } else if (!sym.isBound()) {
15.452 - continue;
15.453 - } else {
15.454 - // XXX what the heck is this??
15.455 - assert false : className + "::" + name + " : " + sym.dumpFlags(scopeInfo);
15.456 - }
15.457 - }
15.458 -
15.459 - if (scopeInfo.attributes.size() > 0) {
15.460 - for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
15.461 - String name = entry.getKey();
15.462 - SymInfo sym = entry.getValue();
15.463 -
15.464 - if (sym.isClass()) {
15.465 - // Triggers in httplib _socket_close inside FakeSocket
15.466 - StringBuilder sig = new StringBuilder();
15.467 - sig.append(name);
15.468 - appendFlags(sig, 'C', sym, 0);
15.469 - classDocument.addPair(FIELD_ITEM, sig.toString(), true, true);
15.470 -
15.471 - } else if (sym.isFunction() && sym.node instanceof FunctionDef) {
15.472 - if (sym.node instanceof Name) {
15.473 - assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
15.474 - }
15.475 - FunctionDef def = (FunctionDef)sym.node;
15.476 - String sig = computeFunctionSig(name, def, sym);
15.477 - classDocument.addPair(FIELD_MEMBER, sig, true, true);
15.478 - } else if (sym.isData()) {
15.479 - StringBuilder sig = new StringBuilder();
15.480 - sig.append(name);
15.481 - appendFlags(sig, 'D', sym, 0);
15.482 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
15.483 - } else if (sym.isMember()) {
15.484 - StringBuilder sig = new StringBuilder();
15.485 - sig.append(name);
15.486 - appendFlags(sig, 'A', sym, 0);
15.487 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
15.488 - } else if (!sym.isBound()) {
15.489 - continue;
15.490 - } else {
15.491 - // XXX what the heck is this??
15.492 - assert false : className + "::" + name + " : " + sym.dumpFlags(scopeInfo);
15.493 - }
15.494 - }
15.495 - }
15.496 - }
15.497 -
15.498 -
15.499 -// TODO - what about nested functions?
15.500 - private IndexDocument createDocument() {
15.501 - IndexDocument doc = support.createDocument(file);
15.502 - documents.add(doc);
15.503 -
15.504 - return doc;
15.505 - }
15.506 - }
15.507 -
15.508 - public static String computeClassSig(ClassDef def, SymInfo sym) {
15.509 - StringBuilder sig = new StringBuilder();
15.510 - sig.append(def.getInternalName());
15.511 - appendFlags(sig, 'C', sym, 0);
15.512 -
15.513 - return sig.toString();
15.514 - }
15.515 -
15.516 - public static String computeFunctionSig(String name, FunctionDef def, SymInfo sym) {
15.517 - StringBuilder sb = new StringBuilder();
15.518 - sb.append(name);
15.519 - char type;
15.520 - int flags = 0;
15.521 - if ("__init__".equals(name)) { // NOI18N
15.522 - type = 'c';
15.523 - } else {
15.524 - type = 'F';
15.525 -
15.526 - List<expr> decorators = def.getInternalDecorator_list();
15.527 - if (decorators != null && decorators.size() > 0) {
15.528 - for (expr decorator : decorators) {
15.529 - String decoratorName = PythonAstUtils.getExprName(decorator);
15.530 - if ("property".equals(decoratorName)) { // NOI18N
15.531 - type = 'A';
15.532 - } else if ("classmethod".equals(decoratorName)) { // NOI18N
15.533 - // Classmethods seem to be used mostly for constructors/inherited factories
15.534 - type = 'c';
15.535 - flags |= IndexedElement.CONSTRUCTOR | IndexedElement.STATIC;
15.536 - } else if ("staticmethod".equals(decoratorName)) { // NOI18N
15.537 - flags |= IndexedElement.STATIC;
15.538 - }
15.539 - }
15.540 - }
15.541 - }
15.542 - appendFlags(sb, type, sym, flags);
15.543 -
15.544 - List<String> params = PythonAstUtils.getParameters(def);
15.545 - boolean first = true;
15.546 - for (String param : params) {
15.547 - if (first) {
15.548 - first = false;
15.549 - } else {
15.550 - sb.append(',');
15.551 - }
15.552 - sb.append(param);
15.553 - }
15.554 - sb.append(';');
15.555 - String sig = sb.toString();
15.556 - return sig;
15.557 - }
15.558 -
15.559 - private String cleanupSignature(String signature) {
15.560 - // Clean up signatures - remove [optional] areas, deal
15.561 - // with arg=Default.Value parameters,
15.562 - // or "literal" or (lit,er,al) default values.
15.563 - // See unit tests for details.
15.564 - boolean lastWasComma = false;
15.565 - StringBuilder sb = new StringBuilder();
15.566 - Loop:
15.567 - for (int i = 0, n = signature.length(); i < n; i++) {
15.568 - char c = signature.charAt(i);
15.569 - switch (c) {
15.570 - case ' ':
15.571 - case '[':
15.572 - case ']':
15.573 - case '\'':
15.574 - case '"':
15.575 - case '.':
15.576 - continue Loop;
15.577 - case '=': {
15.578 - int level = 0;
15.579 - for (i++; i < n; i++) {
15.580 - c = signature.charAt(i);
15.581 - if (c == '(') {
15.582 - level++;
15.583 - } else if (c == ')') {
15.584 - if (level == 0) {
15.585 - break;
15.586 - }
15.587 - level--;
15.588 - }
15.589 - if (c == ',' && level == 0) {
15.590 - break;
15.591 - }
15.592 - }
15.593 - i--; // compensate for loop-increment
15.594 - continue Loop;
15.595 - }
15.596 - case ')':
15.597 - if (lastWasComma) {
15.598 - sb.setLength(sb.length() - 1);
15.599 - lastWasComma = false;
15.600 - }
15.601 - break;
15.602 - case ',':
15.603 - if (lastWasComma) {
15.604 - continue Loop;
15.605 - }
15.606 - lastWasComma = true;
15.607 - break;
15.608 - default:
15.609 - lastWasComma = false;
15.610 - }
15.611 - sb.append(c);
15.612 - }
15.613 -
15.614 - return sb.toString();
15.615 - }
15.616 -
15.617 - /**
15.618 - * Determine if the definition beginning on lines[lineno] is deprecated.
15.619 - */
15.620 - private boolean isDeprecated(String[] lines, int lineno) {
15.621 - int firstIndent = RstFormatter.getIndentation(lines[lineno], 0);
15.622 - for (int i = lineno + 1; i < lines.length; i++) {
15.623 - String line = lines[i];
15.624 - int indent = RstFormatter.getIndentation(line, 0);
15.625 - if (indent == -1) { // empty line
15.626 - continue;
15.627 - }
15.628 - if (line.contains(":deprecated:") || line.contains(".. deprecated::")) { // NOI18N
15.629 - return true;
15.630 - }
15.631 - // Note - we checked for ::deprecated BEFORE bailing on the next
15.632 - // same-indent line, because in some cases, these appear on the same
15.633 - // level as the deprecated element (for exampe, modules)
15.634 - if (indent <= firstIndent) {
15.635 - return false;
15.636 - }
15.637 -
15.638 - // For classes we can have embedded definitions of functions/data/methods --
15.639 - // a deprecated note for these should not be considered a deprecation of
15.640 - // the whole class! See the unit test for bz2.zip for example.
15.641 - if (line.startsWith(".. attribute::", indent) || // NOI18N
15.642 - line.startsWith(".. data::", indent) || // NOI18N
15.643 - line.startsWith(".. function::", indent) || // NOI18N
15.644 - line.startsWith(".. method::", indent)) { // NOI18N
15.645 - return false;
15.646 - }
15.647 - }
15.648 -
15.649 - return false;
15.650 - }
15.651 -
15.652 - private static class CachedIndexDocument {
15.653 - private List<CachedIndexDocumentEntry> entries = new ArrayList<>(DEFAULT_DOC_SIZE);
15.654 -
15.655 - private void addPair(String key, String value, boolean index) {
15.656 - entries.add(new CachedIndexDocumentEntry(key, value, index));
15.657 - }
15.658 - }
15.659 -
15.660 - private static class CachedIndexDocumentEntry {
15.661 - private String key;
15.662 - private String value;
15.663 - private boolean index;
15.664 -
15.665 - public CachedIndexDocumentEntry(String key, String value, boolean index) {
15.666 - this.key = key;
15.667 - this.value = value;
15.668 - this.index = index;
15.669 - }
15.670 - }
15.671 -
15.672 - private List<IndexDocument> scanRst(FileObject fo, Indexable indexable, IndexingSupport support, String overrideUrl) {
15.673 - List<CachedIndexDocument> documents = new ArrayList<>();
15.674 -
15.675 - List<IndexDocument> docs = new ArrayList<>();
15.676 -
15.677 - if (fo != null) {
15.678 - String module = fo.getNameExt();
15.679 - assert module.endsWith(".rst"); // NOI18N
15.680 - module = module.substring(0, module.length() - 4);
15.681 -
15.682 - // Skip files that are already in the standard Python libraries (as .py files).
15.683 - // For these, normal scanning applies
15.684 - // (I should consider checking that they are consistent with the official
15.685 - // documentation, at least during preindexing)
15.686 - if (PREINDEXING) {
15.687 - // XXX This doesn't work right for anything but the builtin Jython interpreter....
15.688 - // OTOH that's the only thing we're preindexing at this point
15.689 - FileObject lib = getLibDir();
15.690 - if (lib != null) {
15.691 - String path = module.replace('.', '/');
15.692 - FileObject py = lib.getFileObject(path); // Look for package dir
15.693 - if (py == null) {
15.694 - py = lib.getFileObject(path + ".py"); // NOI18N
15.695 - }
15.696 - if (py != null) {
15.697 - System.err.println("DELETE " + FileUtil.getFileDisplayName(fo) + " because there is a corresponding " + FileUtil.getFileDisplayName(py)); // NOI18N
15.698 - // No - it's in a zip archive now
15.699 - //try {
15.700 - // // Delete it!
15.701 - // fo.delete();
15.702 - //} catch (IOException ex) {
15.703 - // Exceptions.printStackTrace(ex);
15.704 - //}
15.705 - return Collections.emptyList();
15.706 - }
15.707 - }
15.708 - }
15.709 -
15.710 - String name = fo.getName();
15.711 -
15.712 - // Skip some really obsolete libraries -- IRIX only etc
15.713 - if (name.equals("gl") || name.equals("cd") || // NOI18N
15.714 - name.equals("al") || name.equals("fm") ||
15.715 - name.equals("fl") || name.equals("imgfile") || // NOI18N
15.716 - name.equals("jpeg") || // NOI18N
15.717 - name.equals("sunau") || name.equals("sunaudio")) { // NOI!8N
15.718 - return Collections.emptyList();
15.719 - }
15.720 -
15.721 - Pattern PATTERN = Pattern.compile("\\s*\\.\\.\\s+(.*)::\\s*(.+)\\s*"); // NOI18N
15.722 -
15.723 - BaseDocument doc = GsfUtilities.getDocument(fo, true);
15.724 - if (doc != null) {
15.725 - Map<String, CachedIndexDocument> classDocs = new HashMap<>();
15.726 - CachedIndexDocument document = null;
15.727 - try {
15.728 - String text = doc.getText(0, doc.getLength());
15.729 - String[] lines = text.split("\n");
15.730 - String currentClass = null;
15.731 -
15.732 - for (int lineno = 0, maxLines = lines.length; lineno < maxLines; lineno++) {
15.733 - String line = lines[lineno];
15.734 - if (!line.startsWith(".. ") && !line.contains(" .. ")) { // NOI18N
15.735 - continue;
15.736 - }
15.737 -
15.738 - Matcher m = PATTERN.matcher(line);
15.739 - if (m.matches()) {
15.740 - String key = m.group(1);
15.741 -
15.742 - if (key.equals("attribute") || // NOI18N
15.743 - key.equals("currentmodule") || // NOI18N
15.744 - key.equals("class") || // NOI18N
15.745 - key.equals("exception") || // NOI18N
15.746 - key.equals("function") || // NOI18N
15.747 - key.equals("method") || // NOI18N
15.748 - key.equals("data") || // NOI18N
15.749 - key.equals("module")) { // NOI18N
15.750 -
15.751 -
15.752 - if (key.equals("module") || key.equals("currentmodule")) { // NOI18N
15.753 - // TODO - determine package name
15.754 - module = m.group(2);
15.755 - document = new CachedIndexDocument();
15.756 - documents.add(document);
15.757 - document.addPair(FIELD_MODULE_NAME, module, true);
15.758 - String moduleAttrs = "S";
15.759 - if (isDeprecated(lines, lineno)) {
15.760 - moduleAttrs = "SD";
15.761 - }
15.762 - document.addPair(FIELD_MODULE_ATTR_NAME, moduleAttrs, false); // NOI18N
15.763 - } else {
15.764 - // Methods described in an rst without an actual module definition...
15.765 - if (document == null) {
15.766 - document = new CachedIndexDocument();
15.767 - documents.add(document);
15.768 - document.addPair(FIELD_MODULE_NAME, module, true);
15.769 - document.addPair(FIELD_MODULE_ATTR_NAME, "S", false); // NOI18N
15.770 - }
15.771 - if (key.equals("method") || key.equals("attribute")) { // NOI18N) { // NOI18N
15.772 - String signature = m.group(2);
15.773 -
15.774 - if ("string.template".equals(signature)) { // NOI18N
15.775 - // Wrong - ignore this one (ends up on the String class)
15.776 - continue;
15.777 - }
15.778 - if (signature.startsWith("somenamedtuple.")) {
15.779 - // Ditto
15.780 - continue;
15.781 - }
15.782 - // Error in mailbox.rst - Python 2.6
15.783 - if (".et_folder(folder)".equals(signature)) {
15.784 - signature = "get_folder(folder)";
15.785 - }
15.786 -
15.787 - int dot = signature.indexOf('.');
15.788 - if (dot != -1) {
15.789 - int paren = signature.indexOf('(');
15.790 - if (paren == -1 || paren > dot) {
15.791 - assert signature.matches("\\w+\\.\\w+.*") : signature;
15.792 - String dottedName = signature.substring(0, dot);
15.793 - CachedIndexDocument dottedDoc = classDocs.get(dottedName);
15.794 - if (dottedDoc != null) {
15.795 - currentClass = dottedName;
15.796 - } else /*if (currentClass == null)*/ {
15.797 - currentClass = dottedName;
15.798 - // New class without class:: declaration first.
15.799 - CachedIndexDocument classDocument = new CachedIndexDocument();
15.800 - documents.add(classDocument);
15.801 - classDocs.put(currentClass, classDocument);
15.802 - classDocument.addPair(FIELD_IN, module, true);
15.803 -
15.804 - classDocument.addPair(FIELD_CLASS_NAME, currentClass, true);
15.805 - classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, currentClass.toLowerCase(), true);
15.806 - }
15.807 - signature = signature.substring(dot + 1);
15.808 - }
15.809 - }
15.810 -
15.811 -
15.812 - CachedIndexDocument classDocument = classDocs.get(currentClass);
15.813 - assert classDocs != null;
15.814 -
15.815 - if (key.equals("method")) {
15.816 - signature = cleanupSignature(signature);
15.817 - if (signature.indexOf('(') == -1) {
15.818 - signature = signature + "()";
15.819 - }
15.820 -
15.821 - assert signature.indexOf('(') != -1 && signature.indexOf(')') != -1 &&
15.822 - signature.indexOf(')') > signature.indexOf('(') : signature;
15.823 - int lparen = signature.indexOf('(');
15.824 - int rparen = signature.indexOf(')', lparen + 1);
15.825 - if (lparen != -1 && rparen != -1) {
15.826 - String methodName = signature.substring(0, lparen);
15.827 - String args = signature.substring(lparen + 1, rparen);
15.828 - char type;
15.829 - if (methodName.equals("__init__")) { // NOI18N
15.830 - type = 'c';
15.831 - } else {
15.832 - type = 'F';
15.833 - }
15.834 - StringBuilder sig = new StringBuilder();
15.835 - sig.append(methodName);
15.836 -
15.837 - int symFlags = 0;
15.838 - if (SymInfo.isPrivateName(methodName)) {
15.839 - symFlags |= ScopeConstants.PRIVATE;
15.840 - }
15.841 - // TODO - look up deprecated etc.
15.842 - SymInfo fakeSym = new SymInfo(symFlags);
15.843 -
15.844 - int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
15.845 - if (isDeprecated(lines, lineno)) {
15.846 - flags |= IndexedElement.DEPRECATED;
15.847 - }
15.848 -
15.849 - appendFlags(sig, type, fakeSym, flags);
15.850 - sig.append(args);
15.851 - sig.append(';');
15.852 -
15.853 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
15.854 - }
15.855 - } else {
15.856 - assert key.equals("attribute");
15.857 -
15.858 - StringBuilder sig = new StringBuilder();
15.859 - sig.append(signature);
15.860 - int symFlags = 0;
15.861 - if (SymInfo.isPrivateName(signature)) {
15.862 - symFlags |= ScopeConstants.PRIVATE;
15.863 - }
15.864 - // TODO - look up deprecated etc.
15.865 - SymInfo fakeSym = new SymInfo(symFlags);
15.866 -
15.867 - int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
15.868 - if (isDeprecated(lines, lineno)) {
15.869 - flags |= IndexedElement.DEPRECATED;
15.870 - }
15.871 -
15.872 -
15.873 - appendFlags(sig, 'A', fakeSym, flags);
15.874 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
15.875 - }
15.876 - } else if (key.equals("class") || key.equals("exception")) { // NOI18N
15.877 - assert module != null;
15.878 - String cls = m.group(2);
15.879 -
15.880 - int paren = cls.indexOf('(');
15.881 - String constructor = null;
15.882 - if (paren != -1) {
15.883 - // Some documents specify a constructor here
15.884 - constructor = cleanupSignature(cls);
15.885 - cls = cls.substring(0, paren);
15.886 - }
15.887 - currentClass = cls;
15.888 -
15.889 - CachedIndexDocument classDocument = new CachedIndexDocument();
15.890 - classDocs.put(currentClass, classDocument);
15.891 - documents.add(classDocument);
15.892 - classDocument.addPair(FIELD_IN, module, true);
15.893 -
15.894 - if (key.equals("exception") && !"Exception".equals(cls)) { // NOI18N
15.895 - classDocument.addPair(FIELD_EXTENDS_NAME, "Exception", true); // NOI18N
15.896 - }
15.897 -
15.898 - classDocument.addPair(FIELD_CLASS_NAME, cls, true);
15.899 - int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY | IndexedElement.CONSTRUCTOR;
15.900 - if (isDeprecated(lines, lineno)) {
15.901 - flags |= IndexedElement.DEPRECATED;
15.902 - }
15.903 - if (flags != 0) {
15.904 - // TODO - store Documented, Deprecated, DocOnly, etc.
15.905 - classDocument.addPair(FIELD_CLASS_ATTR_NAME, IndexedElement.encode(flags), false);
15.906 - }
15.907 - classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, cls.toLowerCase(), true);
15.908 -
15.909 - // TODO - determine extends
15.910 - //document.addPair(FIELD_EXTENDS_NAME, superClass, true);
15.911 -
15.912 - if (constructor != null) {
15.913 - assert constructor.indexOf('(') != -1 && constructor.indexOf(')') != -1 &&
15.914 - constructor.indexOf(')') > constructor.indexOf('(') : constructor;
15.915 -
15.916 - String signature = constructor;
15.917 - int lparen = signature.indexOf('(');
15.918 - int rparen = signature.indexOf(')', lparen + 1);
15.919 - if (lparen != -1 && rparen != -1) {
15.920 - //String methodName = signature.substring(0, lparen);
15.921 - String methodName = "__init__"; // The constructor is always __init__ !
15.922 - String args = signature.substring(lparen + 1, rparen);
15.923 - StringBuilder sig = new StringBuilder();
15.924 - sig.append(methodName);
15.925 - int symFlags = 0;
15.926 - if (SymInfo.isPrivateName(methodName)) {
15.927 - symFlags |= ScopeConstants.PRIVATE;
15.928 - }
15.929 - // TODO - look up deprecated etc.
15.930 - SymInfo fakeSym = new SymInfo(symFlags);
15.931 -
15.932 - flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY | IndexedElement.CONSTRUCTOR;
15.933 - if (isDeprecated(lines, lineno)) {
15.934 - flags |= IndexedElement.DEPRECATED;
15.935 - }
15.936 -
15.937 - appendFlags(sig, 'c', fakeSym, flags);
15.938 - sig.append(args);
15.939 - sig.append(';');
15.940 -
15.941 - classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
15.942 - }
15.943 -
15.944 - }
15.945 - } else if (key.equals("function") || (key.equals("data") && m.group(2).contains("("))) { // NOI18N
15.946 - // constants.rst for example registers a data item for "quit" which is really a function
15.947 -
15.948 - String signature = m.group(2);
15.949 - indexRstFunction(signature, lines, lineno, document);
15.950 -
15.951 - // See if we have any additional lines with signatures
15.952 - for (int lookahead = lineno + 1; lookahead < maxLines; lookahead++) {
15.953 - String l = lines[lookahead];
15.954 - String trimmed = l.trim();
15.955 - if (trimmed.length() == 0 || trimmed.startsWith(":")) { // NOI18N
15.956 - break;
15.957 - }
15.958 - lineno++;
15.959 -
15.960 - indexRstFunction(trimmed, lines, lookahead, document);
15.961 - }
15.962 -
15.963 - } else if (key.equals("data")) { // NOI18N
15.964 - String data = m.group(2);
15.965 -
15.966 - StringBuilder sig = new StringBuilder();
15.967 - sig.append(data);
15.968 - int symFlags = 0;
15.969 - if (SymInfo.isPrivateName(data)) {
15.970 - symFlags |= ScopeConstants.PRIVATE;
15.971 - }
15.972 - // TODO - look up deprecated etc.
15.973 - SymInfo fakeSym = new SymInfo(symFlags);
15.974 -
15.975 - int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
15.976 - if (isDeprecated(lines, lineno)) {
15.977 - flags |= IndexedElement.DEPRECATED;
15.978 - }
15.979 -
15.980 - appendFlags(sig, 'D', fakeSym, flags);
15.981 -
15.982 - document.addPair(FIELD_ITEM, sig.toString(), true);
15.983 - } else {
15.984 - // TODO Handle deprecated attribute!
15.985 -
15.986 - // currentmodule::
15.987 - // deprecated::
15.988 - // doctest::
15.989 - // envvar::
15.990 - // epigraph::
15.991 - // highlight::
15.992 - // highlightlang::
15.993 - // index::
15.994 - // literalinclude::
15.995 - // moduleauthor::
15.996 - // note::
15.997 - // opcode::
15.998 - // productionlist::
15.999 - // rubric::
15.1000 - // sectionauthor::
15.1001 - // seealso::
15.1002 - // testcode::
15.1003 - // testsetup::
15.1004 - // toctree::
15.1005 - // versionadded::
15.1006 - // versionchanged::
15.1007 - // warning::
15.1008 - }
15.1009 - }
15.1010 - }
15.1011 - } else if (line.startsWith(".. _bltin-file-objects:") || line.startsWith(".. _string-methods:")) { // NOI18N
15.1012 - if (currentClass != null) {
15.1013 - currentClass = null;
15.1014 - }
15.1015 - }
15.1016 - }
15.1017 -
15.1018 - for (String clz : classDocs.keySet()) {
15.1019 - StringBuilder sig = new StringBuilder();
15.1020 - sig.append(clz);
15.1021 - int symFlags = 0;
15.1022 - if (SymInfo.isPrivateName(clz)) {
15.1023 - symFlags |= ScopeConstants.PRIVATE;
15.1024 - }
15.1025 - // TODO - look up deprecated etc.
15.1026 - SymInfo fakeSym = new SymInfo(symFlags);
15.1027 - appendFlags(sig, 'C', fakeSym, IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY);
15.1028 -
15.1029 - document.addPair(FIELD_ITEM, sig.toString(), true);
15.1030 - }
15.1031 -
15.1032 - } catch (BadLocationException ex) {
15.1033 - Exceptions.printStackTrace(ex);
15.1034 - }
15.1035 -
15.1036 - // Post processing: Add missing attributes not found in the .rst files
15.1037 - // but introspected using dir() in a python console
15.1038 - if (document != null) {
15.1039 - if ("operator".equals(module)) { // Fill in missing operators!
15.1040 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1041 - new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
15.1042 - document, classDocs, "int", documents, module, false, true);
15.1043 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1044 - new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
15.1045 - document, classDocs, "long", documents, module, false, true);
15.1046 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1047 - new String[] { "__abs__", "__add__", "__div__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__pos__", "__pow__", "__sub__", "__truediv__" },
15.1048 - document, classDocs, "float", documents, module, false, true);
15.1049 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1050 - new String[] { "__abs__", "__add__", "__div__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__pos__", "__pow__", "__sub__", "__truediv__" },
15.1051 - document, classDocs, "complex", documents, module, false, true);
15.1052 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1053 - new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
15.1054 - document, classDocs, "bool", documents, module, false, true);
15.1055 -
15.1056 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1057 - new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "index" },
15.1058 - document, classDocs, "str", documents, module, false, true);
15.1059 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1060 - new String[] { "__add__", "__contains__", "__delitem__", "__delslice__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__iadd__", "__imul__", "__le__", "__lt__", "__mul__", "__ne__", "__setitem__", "__setslice__", "index" },
15.1061 - document, classDocs, "list", documents, module, false, true);
15.1062 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1063 - new String[] { "__contains__", "__delitem__", "__eq__", "__ge__", "__getitem__", "__gt__", "__le__", "__lt__", "__ne__", "__setitem__" },
15.1064 - document, classDocs, "dict", documents, module, false, true);
15.1065 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1066 - new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mul__", "__ne__", "index" },
15.1067 - document, classDocs, "tuple", documents, module, false, true);
15.1068 - addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1069 - new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "index" },
15.1070 - document, classDocs, "unicode", documents, module, false, true);
15.1071 -// } else if ("stdtypes".equals(module)) {
15.1072 -// // Found no definitions for these puppies
15.1073 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1074 -// new String[] { "__class__", "__cmp__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__hex__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__oct__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "denominator", "imag", "numerator", "real" },
15.1075 -// document, classDocs, "int", documents, module, true, false);
15.1076 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1077 -// new String[] { "__class__", "__cmp__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__hex__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__oct__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "denominator", "imag", "numerator", "real" },
15.1078 -// document, classDocs, "long", documents, module, true, false);
15.1079 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1080 -// new String[] { "__class__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getformat__", "__getnewargs__", "__hash__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__radd__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rmod__", "__rmul__", "__rpow__", "__rsub__", "__rtruediv__", "__setattr__", "__setformat__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "imag", "is_integer", "real" },
15.1081 -// document, classDocs, "float", documents, module, true, false);
15.1082 -//
15.1083 -//
15.1084 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1085 -// new String[] { "__class__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__radd__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rmod__", "__rmul__", "__rpow__", "__rsub__", "__rtruediv__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "conjugate", "imag", "real" },
15.1086 -// document, classDocs, "complex", documents, module, true, false);
15.1087 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1088 -// new String[] { "__class__", "__cmp__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__hex__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__oct__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "denominator", "imag", "numerator", "real" },
15.1089 -// document, classDocs, "bool", documents, module, true, false);
15.1090 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1091 -// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__len__", "__new__", "__repr__", "__rmod__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "_formatter_field_name_split", "_formatter_parser" },
15.1092 -// document, classDocs, "str", documents, module, true, false);
15.1093 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1094 -// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__hash__", "__init__", "__iter__", "__len__", "__new__", "__repr__", "__reversed__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "append", "count", "extend", "insert", "pop", "remove", "reverse", "sort" },
15.1095 -// document, classDocs, "list", documents, module, true, false);
15.1096 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1097 -// new String[] { "__class__", "__cmp__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__hash__", "__iter__", "__len__", "__new__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__" },
15.1098 -// document, classDocs, "dict", documents, module, true, false);
15.1099 -//
15.1100 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1101 -// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__iter__", "__len__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "count" },
15.1102 -// document, classDocs, "tuple", documents, module, true, false);
15.1103 -// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
15.1104 -// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__len__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__rmod__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "_formatter_field_name_split", "_formatter_parser", "capitalize", "center", "count", "decode", "encode", "endswith", "expandtabs", "find", "format", "isalnum", "isalpha", "isdecimal", "isdigit", "islower", "isnumeric", "isspace", "istitle", "isupper", "join", "ljust", "lower", "lstrip", "partition", "replace", "rfind", "rindex", "rjust", "rpartition", "rsplit", "rstrip", "split", "splitlines", "startswith", "strip", "swapcase", "title", "translate", "upper", "zfill" },
15.1105 -// document, classDocs, "unicode", documents, module, true, false);
15.1106 -//
15.1107 - }
15.1108 - }
15.1109 -
15.1110 - // And convert to a proper GSF search document. I didn't do this directly
15.1111 - // because I want to modify the documents after adding documents and pairs.
15.1112 - for (CachedIndexDocument cid : documents) {
15.1113 - List<CachedIndexDocumentEntry> entries = cid.entries;
15.1114 - IndexDocument indexedDoc = support.createDocument(indexable);
15.1115 -// IndexDocument indexedDoc = support.createDocument(entries.size(), overrideUrl);
15.1116 - docs.add(indexedDoc);
15.1117 - for (CachedIndexDocumentEntry entry : entries) {
15.1118 - indexedDoc.addPair(entry.key, entry.value, true, true); // XXX indexable and stored ???
15.1119 - }
15.1120 - }
15.1121 - }
15.1122 - }
15.1123 -
15.1124 - return docs;
15.1125 - }
15.1126 -
15.1127 - /** Add the given list of names, found in the given document with a given key, and add it
15.1128 - * to the specified class (possibly found in the classDocs list - if not, add one to the
15.1129 - * documents list)
15.1130 - */
15.1131 - private void addMissing(String key, String newKey, String[] names, CachedIndexDocument doc,
15.1132 - Map<String, CachedIndexDocument> classDocs, String clz, List<CachedIndexDocument> documents, String module,
15.1133 - boolean addUnknown, boolean search) {
15.1134 -
15.1135 - CachedIndexDocument classDocument = classDocs.get(clz);
15.1136 - if (classDocument == null) {
15.1137 - // New class without class:: declaration first.
15.1138 - classDocument = new CachedIndexDocument();
15.1139 - documents.add(classDocument);
15.1140 - classDocs.put(clz, classDocument);
15.1141 - classDocument.addPair(FIELD_IN, module, true);
15.1142 -
15.1143 - classDocument.addPair(FIELD_CLASS_NAME, clz, true);
15.1144 - classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, clz.toLowerCase(), true);
15.1145 - }
15.1146 -
15.1147 - assert classDocument != doc;
15.1148 -
15.1149 - List<String> namesFound = new ArrayList<>();
15.1150 - List<String> namesMissing = new ArrayList<>();
15.1151 - boolean noneFound = true;
15.1152 -
15.1153 - // Look for each of the given functions
15.1154 - Search:
15.1155 - for (String name : names) {
15.1156 - boolean found = false;
15.1157 - if (search) {
15.1158 - int nameLength = name.length();
15.1159 -
15.1160 - // DEBUGGING: Look to make sure I don't already have it in the class doc!
15.1161 - for (CachedIndexDocumentEntry entry : classDocument.entries) {
15.1162 - if (newKey.equals(entry.key)) {
15.1163 - if (entry.value.startsWith(name) &&
15.1164 - (entry.value.length() <= nameLength || entry.value.charAt(nameLength) == ';')) {
15.1165 - // Uh oh - what do I do here?
15.1166 - System.err.println("WARNING: I already have a definition for name " + name + " in class " + clz);
15.1167 - continue Search;
15.1168 - }
15.1169 - }
15.1170 - }
15.1171 -
15.1172 - for (CachedIndexDocumentEntry entry : doc.entries) {
15.1173 - if (key.equals(entry.key)) {
15.1174 - if (entry.value.startsWith(name) &&
15.1175 - (entry.value.length() <= nameLength || entry.value.charAt(nameLength) == ';')) {
15.1176 - // Found it!
15.1177 - classDocument.addPair(newKey, entry.value, entry.index);
15.1178 - found = true;
15.1179 - namesFound.add(name);
15.1180 - break;
15.1181 - }
15.1182 - }
15.1183 - }
15.1184 - }
15.1185 -
15.1186 - if (!found) {
15.1187 - if (addUnknown) {
15.1188 - // TODO - see if I can find a way to extract the signature too!
15.1189 - String args = "";
15.1190 - String signature = name + "()"; //
15.1191 -
15.1192 - assert signature.indexOf('(') != -1 && signature.indexOf(')') != -1 &&
15.1193 - signature.indexOf(')') > signature.indexOf('(') : signature;
15.1194 - char type;
15.1195 - if (name.equals("__init__")) { // NOI18N
15.1196 - type = 'c';
15.1197 - } else {
15.1198 - type = 'F';
15.1199 - }
15.1200 - StringBuilder sig = new StringBuilder();
15.1201 - sig.append(name);
15.1202 -
15.1203 - int symFlags = 0;
15.1204 - if (SymInfo.isPrivateName(name)) {
15.1205 - symFlags |= ScopeConstants.PRIVATE;
15.1206 - }
15.1207 - // TODO - look up deprecated etc.
15.1208 - SymInfo fakeSym = new SymInfo(symFlags);
15.1209 -
15.1210 - int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
15.1211 - appendFlags(sig, type, fakeSym, flags);
15.1212 - sig.append(args);
15.1213 - sig.append(';');
15.1214 -
15.1215 - classDocument.addPair(newKey, sig.toString(), true);
15.1216 - } else {
15.1217 - namesMissing.add(name);
15.1218 - }
15.1219 - } else {
15.1220 - noneFound = false;
15.1221 - }
15.1222 - }
15.1223 -
15.1224 - if (PREINDEXING) {
15.1225 - if (namesFound.size() > 0) {
15.1226 - StringBuilder sb = new StringBuilder();
15.1227 - sb.append("FOUND for ");
15.1228 - sb.append(clz);
15.1229 - sb.append(" in ");
15.1230 - sb.append(module);
15.1231 - sb.append(": ");
15.1232 - appendList(sb, namesFound);
15.1233 - System.err.println(sb.toString());
15.1234 - }
15.1235 -
15.1236 - if (noneFound && search) {
15.1237 - System.err.println("ERROR: NONE of the passed in names for " + clz + " were found!");
15.1238 - }
15.1239 -
15.1240 - if (namesMissing.size() > 0) {
15.1241 - StringBuilder sb = new StringBuilder();
15.1242 - sb.append("WARNING: Missing these names from ");
15.1243 - sb.append(module);
15.1244 - sb.append(" for use by class ");
15.1245 - sb.append(clz);
15.1246 - sb.append(" : ");
15.1247 - appendList(sb, namesMissing);
15.1248 - System.err.println(sb.toString());
15.1249 - }
15.1250 - }
15.1251 - }
15.1252 -
15.1253 - private static void appendList(StringBuilder sb, List<String> list) {
15.1254 - sb.append("{ ");
15.1255 - boolean first = true;
15.1256 - for (String m : list) {
15.1257 - if (first) {
15.1258 - first = false;
15.1259 - } else {
15.1260 - sb.append(", ");
15.1261 - }
15.1262 - sb.append('"');
15.1263 - sb.append(m);
15.1264 - sb.append('"');
15.1265 - }
15.1266 - sb.append(" }");
15.1267 - }
15.1268 -
15.1269 - private void indexRstFunction(String signature, String[] lines, int lineno, CachedIndexDocument document) {
15.1270 - int dot = signature.indexOf('.');
15.1271 - if (dot != -1) {
15.1272 - int paren = signature.indexOf('(');
15.1273 - if (paren == -1 || paren > dot) {
15.1274 - assert signature.matches("\\w+\\.\\w+.*") : signature; // NOI18N
15.1275 - signature = signature.substring(dot + 1);
15.1276 - }
15.1277 - }
15.1278 - signature = cleanupSignature(signature);
15.1279 - if (signature.indexOf('(') == -1) {
15.1280 - signature = signature + "()"; // NOI18N
15.1281 - } else if (signature.indexOf(')') == -1) {
15.1282 - //signature = signature + ")";
15.1283 - assert signature.indexOf(')') != -1;
15.1284 - }
15.1285 - int lparen = signature.indexOf('(');
15.1286 - int rparen = signature.indexOf(')', lparen + 1);
15.1287 - if (lparen != -1 && rparen != -1) {
15.1288 - String methodName = signature.substring(0, lparen);
15.1289 - String args = signature.substring(lparen + 1, rparen);
15.1290 - StringBuilder sig = new StringBuilder();
15.1291 - sig.append(methodName);
15.1292 - int symFlags = 0;
15.1293 - if (SymInfo.isPrivateName(methodName)) {
15.1294 - symFlags |= ScopeConstants.PRIVATE;
15.1295 - }
15.1296 - // TODO - look up deprecated etc.
15.1297 - SymInfo fakeSym = new SymInfo(symFlags);
15.1298 - int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
15.1299 - if (isDeprecated(lines, lineno)) {
15.1300 - flags |= IndexedElement.DEPRECATED;
15.1301 - }
15.1302 - appendFlags(sig, 'F', fakeSym, flags);
15.1303 - sig.append(args);
15.1304 - sig.append(';');
15.1305 -
15.1306 - document.addPair(FIELD_ITEM, sig.toString(), true);
15.1307 - }
15.1308 - }
15.1309 -
15.1310 - private List<IndexDocument> scanEgg(FileObject fo, Indexable indexable, ParserResult result, IndexingSupport support) {
15.1311 - List<IndexDocument> documents = new ArrayList<>();
15.1312 -
15.1313 - if (fo == null) {
15.1314 - return documents;
15.1315 - }
15.1316 -
15.1317 - try {
15.1318 - String s = fo.toURL().toExternalForm() + "!"; // NOI18N
15.1319 - URL u = new URL("jar:" + s); // NOI18N
15.1320 - FileObject root = URLMapper.findFileObject(u);
15.1321 - String rootUrl = PythonIndex.getPreindexUrl(u.toExternalForm());
15.1322 - indexScriptDocRecursively(support, documents, root, rootUrl);
15.1323 - } catch (MalformedURLException ex) {
15.1324 - Exceptions.printStackTrace(ex);
15.1325 - }
15.1326 -
15.1327 - return documents;
15.1328 - }
15.1329 -
15.1330 - /**
15.1331 - * Method which recursively indexes directory trees, such as the yui/ folder
15.1332 - * for example
15.1333 - */
15.1334 - private void indexScriptDocRecursively(IndexingSupport support, List<IndexDocument> documents, final FileObject fo, String url) {
15.1335 - if (fo.isFolder()) {
15.1336 - for (FileObject c : fo.getChildren()) {
15.1337 - indexScriptDocRecursively(support, documents, c, url + "/" + c.getNameExt()); // NOI18N
15.1338 - }
15.1339 - return;
15.1340 - }
15.1341 -
15.1342 - String ext = fo.getExt();
15.1343 -
15.1344 -// if ("py".equals(ext)) { // NOI18N
15.1345 -// DefaultParseListener listener = new DefaultParseListener();
15.1346 -// List<ParserFile> files = Collections.<ParserFile>singletonList(new DefaultParserFile(fo, null, false));
15.1347 -// SourceFileReader reader = new SourceFileReader() {
15.1348 -// public CharSequence read(ParserFile file) throws IOException {
15.1349 -// BaseDocument doc = GsfUtilities.getDocument(fo, true);
15.1350 -// if (doc != null) {
15.1351 -// try {
15.1352 -// return doc.getText(0, doc.getLength());
15.1353 -// } catch (BadLocationException ex) {
15.1354 -// Exceptions.printStackTrace(ex);
15.1355 -// }
15.1356 -// }
15.1357 -//
15.1358 -// return "";
15.1359 -// }
15.1360 -//
15.1361 -// public int getCaretOffset(ParserFile file) {
15.1362 -// return -1;
15.1363 -// }
15.1364 -// };
15.1365 -// Job job = new Job(files, listener, reader, null);
15.1366 -// new PythonParser().parseFiles(job);
15.1367 -// ParserResult parserResult = listener.getParserResult();
15.1368 -// if (parserResult != null && parserResult.isValid()) {
15.1369 -// documents.addAll(new IndexTask((PythonParserResult)parserResult, support, url).scan());
15.1370 -// }
15.1371 -// } else if ("rst".equals(ext)) { // NOI18N
15.1372 -// documents.addAll(scanRst(fo, support, url));
15.1373 -// }
15.1374 - }
15.1375 -
15.1376 - private FileObject getLibDir() {
15.1377 - // TODO - fetch from projects!!!!
15.1378 - PythonPlatformManager manager = PythonPlatformManager.getInstance();
15.1379 - PythonPlatform platform = manager.getPlatform(manager.getDefaultPlatform());
15.1380 - if (platform != null) {
15.1381 - String cmd = platform.getInterpreterCommand();
15.1382 - File file = new File(cmd);
15.1383 - if (file.exists()) {
15.1384 - file = file.getAbsoluteFile();
15.1385 - File home = file.getParentFile().getParentFile();
15.1386 - if (home != null) {
15.1387 - // Look for Lib - Jython style
15.1388 - File lib = new File(home, "Lib"); // NOI18N
15.1389 - boolean exists = lib.exists();
15.1390 - if (!exists) { // Unix style
15.1391 - lib = new File(home, "lib" + File.separator + "python"); // NOI18N
15.1392 - exists = lib.exists();
15.1393 - }
15.1394 - if (exists) {
15.1395 - return FileUtil.toFileObject(lib);
15.1396 - }
15.1397 - }
15.1398 - }
15.1399 - }
15.1400 -
15.1401 - return null;
15.1402 - }
15.1403 -}
16.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonIndexerFactory.java Fri Sep 18 16:20:24 2015 -0500
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,47 +0,0 @@
16.4 -/*
16.5 - * To change this license header, choose License Headers in Project Properties.
16.6 - * To change this template file, choose Tools | Templates
16.7 - * and open the template in the editor.
16.8 - */
16.9 -package org.netbeans.modules.python.editor;
16.10 -
16.11 -import org.netbeans.modules.parsing.api.Snapshot;
16.12 -import org.netbeans.modules.parsing.spi.indexing.Context;
16.13 -import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer;
16.14 -import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexerFactory;
16.15 -import org.netbeans.modules.parsing.spi.indexing.Indexable;
16.16 -
16.17 -/**
16.18 - *
16.19 - * @author Ralph Benjamin Ruijs
16.20 - */
16.21 -public class PythonIndexerFactory extends EmbeddingIndexerFactory {
16.22 -
16.23 - @Override
16.24 - public EmbeddingIndexer createIndexer(Indexable indexable, Snapshot snapshot) {
16.25 - if(PythonIndexer.isIndexable(indexable, snapshot)) {
16.26 - return new PythonIndexer();
16.27 - }
16.28 - return null;
16.29 - }
16.30 -
16.31 - @Override
16.32 - public void filesDeleted(Iterable<? extends Indexable> indexables, Context context) {
16.33 -// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
16.34 - }
16.35 -
16.36 - @Override
16.37 - public void filesDirty(Iterable<? extends Indexable> arg0, Context arg1) {
16.38 -// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
16.39 - }
16.40 -
16.41 - @Override
16.42 - public String getIndexerName() {
16.43 - return PythonIndexer.NAME;
16.44 - }
16.45 -
16.46 - @Override
16.47 - public int getIndexVersion() {
16.48 - return PythonIndexer.VERSION;
16.49 - }
16.50 -}
17.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonInstantRename.java Fri Sep 18 16:20:24 2015 -0500
17.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonInstantRename.java Mon Sep 21 13:01:16 2015 +0200
17.3 @@ -30,6 +30,9 @@
17.4 */
17.5 package org.netbeans.modules.python.editor;
17.6
17.7 +import org.netbeans.modules.python.source.AstPath;
17.8 +import org.netbeans.modules.python.source.PythonParserResult;
17.9 +import org.netbeans.modules.python.source.PythonAstUtils;
17.10 import java.util.Collections;
17.11 import java.util.Set;
17.12 import javax.swing.text.Document;
17.13 @@ -39,9 +42,9 @@
17.14 import org.netbeans.modules.csl.api.InstantRenamer;
17.15 import org.netbeans.modules.csl.api.OffsetRange;
17.16 import org.netbeans.modules.csl.spi.ParserResult;
17.17 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
17.18 -import org.netbeans.modules.python.editor.lexer.PythonCommentTokenId;
17.19 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
17.20 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
17.21 +import org.netbeans.modules.python.source.lexer.PythonCommentTokenId;
17.22 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
17.23 import org.python.antlr.PythonTree;
17.24 import org.python.antlr.ast.Attribute;
17.25 import org.python.antlr.ast.Call;
18.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonKeystrokeHandler.java Fri Sep 18 16:20:24 2015 -0500
18.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonKeystrokeHandler.java Mon Sep 21 13:01:16 2015 +0200
18.3 @@ -30,14 +30,17 @@
18.4 */
18.5 package org.netbeans.modules.python.editor;
18.6
18.7 +import org.netbeans.modules.python.source.AstPath;
18.8 +import org.netbeans.modules.python.source.PythonParserResult;
18.9 +import org.netbeans.modules.python.source.PythonAstUtils;
18.10 import java.util.ArrayList;
18.11 import java.util.List;
18.12 import javax.swing.text.BadLocationException;
18.13 import javax.swing.text.Caret;
18.14 import javax.swing.text.Document;
18.15 import javax.swing.text.JTextComponent;
18.16 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
18.17 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
18.18 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
18.19 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
18.20 import org.netbeans.api.lexer.Token;
18.21 import org.netbeans.api.lexer.TokenHierarchy;
18.22 import org.netbeans.api.lexer.TokenId;
19.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonLanguage.java Fri Sep 18 16:20:24 2015 -0500
19.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonLanguage.java Mon Sep 21 13:01:16 2015 +0200
19.3 @@ -30,9 +30,13 @@
19.4 */
19.5 package org.netbeans.modules.python.editor;
19.6
19.7 +import org.netbeans.modules.python.source.PythonStructureScanner;
19.8 +import org.netbeans.modules.python.source.PythonIndexerFactory;
19.9 +import org.netbeans.modules.python.source.PythonIndexSearcher;
19.10 +import org.netbeans.modules.python.source.PythonParser;
19.11 +import org.netbeans.modules.python.source.PythonFormatter;
19.12 import java.io.File;
19.13 import org.netbeans.api.java.classpath.ClassPath;
19.14 -import org.netbeans.modules.python.editor.hints.PythonHintsProvider;
19.15 import org.netbeans.api.lexer.Language;
19.16 import org.netbeans.modules.csl.api.CodeCompletionHandler;
19.17 import org.netbeans.modules.csl.api.DeclarationFinder;
19.18 @@ -50,7 +54,7 @@
19.19 import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexerFactory;
19.20 import org.netbeans.modules.parsing.spi.indexing.PathRecognizerRegistration;
19.21 import org.netbeans.modules.python.api.PythonMIMEResolver;
19.22 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
19.23 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
19.24 import org.openide.filesystems.FileObject;
19.25 import org.openide.filesystems.FileUtil;
19.26 import org.openide.modules.InstalledFileLocator;
19.27 @@ -144,15 +148,15 @@
19.28 return new PythonIndexerFactory();
19.29 }
19.30
19.31 - @Override
19.32 - public boolean hasHintsProvider() {
19.33 - return true;
19.34 - }
19.35 -
19.36 - @Override
19.37 - public HintsProvider getHintsProvider() {
19.38 - return new PythonHintsProvider();
19.39 - }
19.40 +// @Override
19.41 +// public boolean hasHintsProvider() {
19.42 +// return true;
19.43 +// }
19.44 +//
19.45 +// @Override
19.46 +// public HintsProvider getHintsProvider() {
19.47 +// return new PythonHintsProvider();
19.48 +// }
19.49
19.50 @Override
19.51 public DeclarationFinder getDeclarationFinder() {
20.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonOccurrencesMarker.java Fri Sep 18 16:20:24 2015 -0500
20.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonOccurrencesMarker.java Mon Sep 21 13:01:16 2015 +0200
20.3 @@ -30,6 +30,9 @@
20.4 */
20.5 package org.netbeans.modules.python.editor;
20.6
20.7 +import org.netbeans.modules.python.source.AstPath;
20.8 +import org.netbeans.modules.python.source.PythonAstUtils;
20.9 +import org.netbeans.modules.python.source.PythonParserResult;
20.10 import java.util.ArrayList;
20.11 import java.util.HashMap;
20.12 import java.util.HashSet;
20.13 @@ -50,9 +53,9 @@
20.14 import org.netbeans.modules.parsing.spi.Parser.Result;
20.15 import org.netbeans.modules.parsing.spi.Scheduler;
20.16 import org.netbeans.modules.parsing.spi.SchedulerEvent;
20.17 -import org.netbeans.modules.python.editor.lexer.PythonCommentTokenId;
20.18 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
20.19 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
20.20 +import org.netbeans.modules.python.source.lexer.PythonCommentTokenId;
20.21 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
20.22 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
20.23 import org.openide.util.Exceptions;
20.24 import org.python.antlr.PythonTree;
20.25 import org.python.antlr.Visitor;
21.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonParser.java Fri Sep 18 16:20:24 2015 -0500
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,760 +0,0 @@
21.4 -/*
21.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
21.6 - *
21.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
21.8 - *
21.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
21.10 - * Other names may be trademarks of their respective owners.
21.11 - *
21.12 - * The contents of this file are subject to the terms of either the GNU
21.13 - * General Public License Version 2 only ("GPL") or the Common
21.14 - * Development and Distribution License("CDDL") (collectively, the
21.15 - * "License"). You may not use this file except in compliance with the
21.16 - * License. You can obtain a copy of the License at
21.17 - * http://www.netbeans.org/cddl-gplv2.html
21.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
21.19 - * specific language governing permissions and limitations under the
21.20 - * License. When distributing the software, include this License Header
21.21 - * Notice in each file and include the License file at
21.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
21.23 - * particular file as subject to the "Classpath" exception as provided
21.24 - * by Oracle in the GPL Version 2 section of the License file that
21.25 - * accompanied this code. If applicable, add the following below the
21.26 - * License Header, with the fields enclosed by brackets [] replaced by
21.27 - * your own identifying information:
21.28 - * "Portions Copyrighted [year] [name of copyright owner]"
21.29 - *
21.30 - * Contributor(s):
21.31 - *
21.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
21.33 - */
21.34 -package org.netbeans.modules.python.editor;
21.35 -
21.36 -import java.io.InputStream;
21.37 -import java.io.InputStreamReader;
21.38 -import java.util.ArrayList;
21.39 -import java.util.List;
21.40 -import java.util.logging.Level;
21.41 -import java.util.logging.Logger;
21.42 -import javax.swing.event.ChangeListener;
21.43 -import javax.swing.text.BadLocationException;
21.44 -import org.netbeans.modules.csl.api.Severity;
21.45 -import org.netbeans.modules.csl.spi.DefaultError;
21.46 -import org.netbeans.modules.csl.api.Error;
21.47 -import org.netbeans.modules.csl.api.OffsetRange;
21.48 -import org.netbeans.modules.csl.spi.GsfUtilities;
21.49 -import org.netbeans.modules.parsing.api.Snapshot;
21.50 -import org.netbeans.modules.parsing.api.Task;
21.51 -import org.netbeans.modules.parsing.spi.Parser;
21.52 -import org.netbeans.modules.parsing.spi.SourceModificationEvent;
21.53 -import org.netbeans.modules.python.api.PythonFileEncodingQuery;
21.54 -import org.openide.filesystems.FileObject;
21.55 -import org.python.antlr.runtime.ANTLRStringStream;
21.56 -import org.python.antlr.runtime.BaseRecognizer;
21.57 -import org.python.antlr.runtime.BitSet;
21.58 -import org.python.antlr.runtime.CommonToken;
21.59 -import org.python.antlr.runtime.CommonTokenStream;
21.60 -import org.python.antlr.runtime.IntStream;
21.61 -import org.python.antlr.runtime.Lexer;
21.62 -import org.python.antlr.runtime.MismatchedTokenException;
21.63 -import org.python.antlr.runtime.RecognitionException;
21.64 -
21.65 -import org.openide.filesystems.FileUtil;
21.66 -import org.openide.util.Exceptions;
21.67 -import org.python.antlr.ListErrorHandler;
21.68 -import org.python.antlr.ParseException;
21.69 -import org.python.antlr.PythonLexer;
21.70 -import org.python.antlr.PythonTokenSource;
21.71 -import org.python.antlr.PythonTree;
21.72 -import org.python.antlr.PythonTreeAdaptor;
21.73 -import org.python.antlr.base.expr;
21.74 -import org.python.antlr.base.mod;
21.75 -import org.python.antlr.base.slice;
21.76 -import org.python.antlr.base.stmt;
21.77 -import org.python.antlr.runtime.ANTLRReaderStream;
21.78 -import org.python.antlr.runtime.CharStream;
21.79 -
21.80 -/**
21.81 - * Parser for Python. Wraps Jython.
21.82 - *
21.83 - * @author Frank Wierzbicki
21.84 - * @author Tor Norbye
21.85 - */
21.86 -public class PythonParser extends Parser {
21.87 - /** For unit tests such that they can make sure we didn't have a parser abort */
21.88 - static Throwable runtimeException;
21.89 -
21.90 - static {
21.91 - org.python.core.PySystemState.initialize();
21.92 - }
21.93 -
21.94 - private Result lastResult;
21.95 - private final PythonFileEncodingQuery fileEncodingQuery = new PythonFileEncodingQuery();
21.96 - private String headerCached = null;
21.97 - private String encodingCache = null;
21.98 -
21.99 - public mod file_input(CharStream charStream, String fileName) throws RecognitionException {
21.100 - ListErrorHandler eh = new ListErrorHandler();
21.101 - mod tree = null;
21.102 - PythonLexer lexer = new PythonLexer(charStream);
21.103 - lexer.setErrorHandler(eh);
21.104 - CommonTokenStream tokens = new CommonTokenStream(lexer);
21.105 - tokens.discardOffChannelTokens(true);
21.106 - PythonTokenSource indentedSource = new PythonTokenSource(tokens, fileName);
21.107 - tokens = new CommonTokenStream(indentedSource);
21.108 - org.python.antlr.PythonParser parser = new org.python.antlr.PythonParser(tokens);
21.109 - parser.setTreeAdaptor(new PythonTreeAdaptor());
21.110 - parser.setErrorHandler(eh);
21.111 - org.python.antlr.PythonParser.file_input_return r = parser.file_input();
21.112 - tree = (mod)r.getTree();
21.113 - return tree;
21.114 - }
21.115 -
21.116 - @Override
21.117 - public void addChangeListener(ChangeListener changeListener) {}
21.118 -
21.119 - @Override
21.120 - public void removeChangeListener(ChangeListener changeListener) {}
21.121 -
21.122 - public PythonTree parse(InputStream istream, String fileName) throws Exception {
21.123 - InputStreamReader reader = new InputStreamReader(istream, "ISO-8859-1");
21.124 - return file_input(new ANTLRReaderStream(reader), fileName);
21.125 - }
21.126 -
21.127 - @Override
21.128 - public final Result getResult(Task task) throws org.netbeans.modules.parsing.spi.ParseException {
21.129 - return lastResult;
21.130 - }
21.131 -
21.132 - private static final Logger LOG = Logger.getLogger(PythonParser.class.getName());
21.133 -
21.134 - @Override
21.135 - public void parse(Snapshot snapshot, Task task, SourceModificationEvent event) throws org.netbeans.modules.parsing.spi.ParseException {
21.136 - Context context = new Context();
21.137 - context.snapshot = snapshot;
21.138 - context.event = event;
21.139 - context.task = task;
21.140 - context.caretOffset = GsfUtilities.getLastKnownCaretOffset(snapshot, event);
21.141 - context.source = snapshot.getText().toString();
21.142 - context.file = snapshot.getSource().getFileObject();
21.143 - if(context.file == null) {
21.144 - return; // TODO: parse the source, not the file
21.145 - }
21.146 - /* Let's not sanitize ;-) Would be great if we could have a more robust parser
21.147 - if (context.caretOffset != -1) {
21.148 - context.sanitized = Sanitize.EDITED_DOT;
21.149 - }
21.150 - */
21.151 - lastResult = parse(context, context.sanitized);
21.152 - }
21.153 - public PythonParserResult parse(final Context context, Sanitize sanitizing) {
21.154 - boolean sanitizedSource = false;
21.155 - String sourceCode = context.source;
21.156 - if (!((sanitizing == Sanitize.NONE) || (sanitizing == Sanitize.NEVER))) {
21.157 - boolean ok = sanitizeSource(context, sanitizing);
21.158 -
21.159 - if (ok) {
21.160 - assert context.sanitizedSource != null;
21.161 - sanitizedSource = true;
21.162 - sourceCode = context.sanitizedSource;
21.163 - } else {
21.164 - // Try next trick
21.165 - return sanitize(context, sanitizing);
21.166 - }
21.167 - }
21.168 - final String source = sourceCode;
21.169 -
21.170 - if (sanitizing == Sanitize.NONE) {
21.171 - context.errorOffset = -1;
21.172 - }
21.173 -
21.174 - final List<Error> errors = new ArrayList<>();
21.175 - final FileObject file = context.file;
21.176 - try {
21.177 - String fileName = file.getNameExt();
21.178 - // TODO - sniff file headers etc. Frank's comment:
21.179 - // Longer term for Python compatibility, having NetBeans sniff the top two lines
21.180 - // for an encoding would be the right thing to do from a pure Python
21.181 - // compatibility standard (see http://www.python.org/dev/peps/pep-0263/) I
21.182 - // have pep-0263 code in Jython that I could probably extract for this
21.183 - // purpose down the road.
21.184 - //String charset = "ISO8859_1"; // NOI18N
21.185 - //String charset = "UTF-8"; // NOI18N
21.186 - //String charset = "iso8859_1"; // NOI18N
21.187 - // TODO: improve this check.
21.188 - int cache_len = sourceCode.length() >= 64 ? 64 : sourceCode.length();
21.189 - if (headerCached == null || cache_len != headerCached.length() || !headerCached.equals(sourceCode.substring(0, cache_len))) {
21.190 - headerCached = sourceCode.substring(0, cache_len);
21.191 - encodingCache = fileEncodingQuery.getPythonFileEncoding(sourceCode.split("\n", 2));
21.192 - }
21.193 - String charset = encodingCache;
21.194 -
21.195 - final boolean ignoreErrors = sanitizedSource;
21.196 - ListErrorHandler errorHandler = new ListErrorHandler() {
21.197 - @Override
21.198 - public void error(String message, PythonTree t) {
21.199 - errors.add(new DefaultError(null, message, null, file, t.getCharStartIndex(), t.getCharStopIndex(), Severity.ERROR));
21.200 - super.error(message, t);
21.201 - }
21.202 -
21.203 - @Override
21.204 - public expr errorExpr(PythonTree t) {
21.205 - return super.errorExpr(t);
21.206 - }
21.207 -
21.208 - @Override
21.209 - public mod errorMod(PythonTree t) {
21.210 - return super.errorMod(t);
21.211 - }
21.212 -
21.213 - @Override
21.214 - public slice errorSlice(PythonTree t) {
21.215 - return super.errorSlice(t);
21.216 - }
21.217 -
21.218 - @Override
21.219 - public stmt errorStmt(PythonTree t) {
21.220 - return super.errorStmt(t);
21.221 - }
21.222 -
21.223 - @Override
21.224 - public boolean mismatch(BaseRecognizer br, IntStream input, int ttype, BitSet follow) {
21.225 - return super.mismatch(br, input, ttype, follow);
21.226 - }
21.227 -
21.228 - @Override
21.229 - public Object recoverFromMismatchedToken(BaseRecognizer br, IntStream input, int ttype, BitSet follow) {
21.230 - MismatchedTokenException mt = new MismatchedTokenException(ttype, input);
21.231 - String message = br.getErrorMessage(mt, br.getTokenNames());
21.232 - if (mt.line >= 1) {
21.233 - int lineOffset = findLineOffset(context.source, mt.line-1);
21.234 - if (mt.charPositionInLine > 0) {
21.235 - lineOffset += mt.charPositionInLine;
21.236 - }
21.237 - int start = lineOffset;//t.getCharStartIndex();
21.238 - int stop = lineOffset;//t.getCharStopIndex();
21.239 - errors.add(new DefaultError(null, message, null, file, start, stop, Severity.ERROR));
21.240 - }
21.241 - return super.recoverFromMismatchedToken(br, input, ttype, follow);
21.242 - }
21.243 -
21.244 - @Override
21.245 - public void recover(Lexer lex, RecognitionException re) {
21.246 - super.recover(lex, re);
21.247 - }
21.248 -
21.249 - @Override
21.250 - public void recover(BaseRecognizer br, IntStream input, RecognitionException re) {
21.251 - super.recover(br, input, re);
21.252 - }
21.253 -
21.254 - @Override
21.255 - public void reportError(BaseRecognizer br, RecognitionException re) {
21.256 - if (!ignoreErrors) {
21.257 - String message = br.getErrorMessage(re, br.getTokenNames());
21.258 - if (message == null || message.length() == 0) {
21.259 - message = re.getMessage();
21.260 - }
21.261 - if (message == null) {
21.262 - //message = re.getUnexpectedType();
21.263 - message = re.toString();
21.264 - }
21.265 - int start = re.index;
21.266 -
21.267 - // Try to find the line offset. re.index doesn't do the trick.
21.268 - start = PythonUtils.getOffsetByLineCol(source, re.line - 1, 0); // -1: 0-based
21.269 - int end = start;
21.270 - if (re.charPositionInLine > 0) {
21.271 - try {
21.272 - end = GsfUtilities.getRowLastNonWhite(source, start) + 1;
21.273 - start += re.charPositionInLine;
21.274 - if (end < start) {
21.275 - end = start;
21.276 - }
21.277 - } catch (BadLocationException ex) {
21.278 - Exceptions.printStackTrace(ex);
21.279 - end = start;
21.280 - }
21.281 - if (end == 0) {
21.282 - end = start;
21.283 - }
21.284 - }
21.285 -
21.286 - // Some errors have better offsets if we look at the token stream
21.287 - if (re instanceof MismatchedTokenException) {
21.288 - MismatchedTokenException m = (MismatchedTokenException)re;
21.289 - if (m.token != null) {
21.290 - if (m.token instanceof org.python.antlr.runtime.CommonToken) {
21.291 - CommonToken token = (org.python.antlr.runtime.CommonToken)m.token;
21.292 - start = token.getStartIndex();
21.293 - end = token.getStopIndex();
21.294 - }
21.295 - }
21.296 - }
21.297 -
21.298 - if (start > source.length()) {
21.299 - start = source.length();
21.300 - end = start;
21.301 - }
21.302 -
21.303 - errors.add(new DefaultError(null, message, null, file, start, end, Severity.ERROR));
21.304 -
21.305 - // In order to avoid a StackOverflowError, the BaseRecognizer must be recreated.
21.306 - // We must keep the names of the tokens to avoid a NullPointerException.
21.307 - // See bz252630
21.308 - final String[] tokenNames = br.getTokenNames();
21.309 - br = new BaseRecognizer() {
21.310 -
21.311 - @Override
21.312 - public String getSourceName() {
21.313 - return file.getName();
21.314 - }
21.315 -
21.316 - @Override
21.317 - public String[] getTokenNames() {
21.318 - return tokenNames;
21.319 - }
21.320 - };
21.321 -
21.322 - super.reportError(br, re);
21.323 - }
21.324 - }
21.325 - };
21.326 -
21.327 - PythonLexer lexer = new PythonLexer(new ANTLRStringStream(sourceCode));
21.328 - lexer.setErrorHandler(errorHandler);
21.329 - CommonTokenStream tokens = new CommonTokenStream(lexer);
21.330 - tokens.discardOffChannelTokens(true);
21.331 - PythonTokenSource indentedSource = new PythonTokenSource(tokens, fileName);
21.332 - CommonTokenStream indentedTokens = new CommonTokenStream(indentedSource);
21.333 - // Import line ending with a dot raise a NullPointerException in
21.334 - // org.python.antlr.GrammarActions.makeDottedText called from parser.file_input
21.335 - // sanitizeImportTokens will remove the dot token from the list of tokens in
21.336 - // indentedTokens to avoid the bug and add an error at this file.
21.337 - // See https://netbeans.org/bugzilla/show_bug.cgi?id=252356
21.338 - sanitizeImportTokens(indentedTokens, errors, file);
21.339 - org.python.antlr.PythonParser parser;
21.340 - if (charset != null) {
21.341 - parser = new org.python.antlr.PythonParser(indentedTokens, charset);
21.342 - } else {
21.343 - parser = new org.python.antlr.PythonParser(indentedTokens);
21.344 - }
21.345 - parser.setTreeAdaptor(new PythonTreeAdaptor());
21.346 - parser.setErrorHandler(errorHandler);
21.347 - org.python.antlr.PythonParser.file_input_return r = parser.file_input();
21.348 - PythonTree t = (PythonTree)r.getTree();
21.349 - PythonParserResult result = new PythonParserResult(t, context.snapshot);
21.350 - result.setErrors(errors);
21.351 -
21.352 - result.setSanitized(context.sanitized, context.sanitizedRange, context.sanitizedContents);
21.353 - result.setSource(sourceCode);
21.354 -
21.355 - return result;
21.356 - } catch (ParseException pe) {
21.357 - if (sanitizing == Sanitize.NONE) {
21.358 - PythonParserResult sanitizedResult = sanitize(context, sanitizing);
21.359 - if (sanitizedResult.isValid()) {
21.360 - return sanitizedResult;
21.361 - } else {
21.362 - int offset = pe.index;
21.363 - assert offset >= 0;
21.364 - String desc = pe.getLocalizedMessage();
21.365 - if (desc == null) {
21.366 - desc = pe.getMessage();
21.367 - }
21.368 - DefaultError error = new DefaultError(null /*key*/, desc, null, file, offset, offset, Severity.ERROR);
21.369 - PythonParserResult parserResult = new PythonParserResult(null, context.snapshot);
21.370 - parserResult.addError(error);
21.371 - for (Error e : errors) {
21.372 - parserResult.addError(e);
21.373 - }
21.374 -
21.375 - return parserResult;
21.376 - }
21.377 - } else {
21.378 - return sanitize(context, sanitizing);
21.379 - }
21.380 - } catch (NullPointerException e) {
21.381 - String fileName = "";
21.382 - if (file != null) {
21.383 - fileName = FileUtil.getFileDisplayName(file);
21.384 - }
21.385 - e = Exceptions.attachMessage(e, "Was parsing " + fileName);
21.386 - Exceptions.printStackTrace(e);
21.387 - return new PythonParserResult(null, context.snapshot);
21.388 - } catch (Throwable t) {
21.389 - runtimeException = t;
21.390 - StackTraceElement[] stackTrace = t.getStackTrace();
21.391 - if (stackTrace != null && stackTrace.length > 0 && stackTrace[0].getClassName().startsWith("org.python.antlr")) {//.runtime.tree.RewriteRuleElementStream")) {
21.392 - // This is issue 150921
21.393 - // Don't bug user about it -- we already know
21.394 - Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Encountered issue #150921", t);
21.395 - } else {
21.396 - t = Exceptions.attachMessage(t, "Was parsing " + FileUtil.getFileDisplayName(file));
21.397 - Exceptions.printStackTrace(t);
21.398 - }
21.399 - return new PythonParserResult(null, context.snapshot);
21.400 - }
21.401 - }
21.402 -
21.403 - private void sanitizeImportTokens(CommonTokenStream indentedTokens, List errors, FileObject file) {
21.404 - List tokens = indentedTokens.getTokens();
21.405 - List<CommonToken> tokensToRemove = new ArrayList<>();
21.406 - int i = 0;
21.407 - while (i < tokens.size()) {
21.408 - CommonToken importToken = (CommonToken)tokens.get(i);
21.409 - if ("import".equals(importToken.getText()) || "from".equals(importToken.getText())) {
21.410 - // sanitizeDotTokens return the index of the token that starts the next line
21.411 - i = sanitizeDotTokens(tokens, tokensToRemove, importToken, i + 1, errors, file);
21.412 - } else {
21.413 - i++;
21.414 - }
21.415 - }
21.416 -
21.417 - for (CommonToken token : tokensToRemove) {
21.418 - tokens.remove(token);
21.419 - }
21.420 - }
21.421 -
21.422 - private int sanitizeDotTokens(List tokens, List tokensToRemove, CommonToken importToken,
21.423 - int startIndex, List errors, FileObject file) {
21.424 - for (int j = startIndex; j < tokens.size() - 1; j++) {
21.425 - CommonToken dotToken = (CommonToken)tokens.get(j);
21.426 - CommonToken nextToken = (CommonToken)tokens.get(j + 1);
21.427 - if (".".equals(dotToken.getText())) {
21.428 - if (nextToken.getText().startsWith("\n")) {
21.429 - tokensToRemove.add(dotToken);
21.430 - String rawTokenText;
21.431 - if (nextToken.getText().startsWith("\n")) {
21.432 - rawTokenText = "\\n";
21.433 - } else {
21.434 - rawTokenText = " ";
21.435 - }
21.436 - errors.add(
21.437 - new DefaultError(null, "Mismatch input '.' expecting NAME\nMissing NAME at '" + rawTokenText + "'",
21.438 - null, file, importToken.getStartIndex(), dotToken.getStopIndex(), Severity.ERROR));
21.439 - }
21.440 - } else if ("\n".equals(nextToken.getText())) { // End of line, must continue looping from external loop
21.441 - return j + 1;
21.442 - }
21.443 - }
21.444 -
21.445 - return startIndex;
21.446 - }
21.447 -
21.448 - private static String asString(CharSequence sequence) {
21.449 - if (sequence instanceof String) {
21.450 - return (String)sequence;
21.451 - } else {
21.452 - return sequence.toString();
21.453 - }
21.454 - }
21.455 -
21.456 -
21.457 - @SuppressWarnings("fallthrough")
21.458 - private PythonParserResult sanitize(final Context context, final Sanitize sanitizing) {
21.459 -
21.460 - switch (sanitizing) {
21.461 - case NEVER:
21.462 - return new PythonParserResult(null, context.snapshot);
21.463 -
21.464 - case NONE:
21.465 - if (context.caretOffset != -1) {
21.466 - return parse(context, Sanitize.EDITED_DOT);
21.467 - }
21.468 -
21.469 - case EDITED_DOT:
21.470 - // We've tried removing whitespace around the edit location
21.471 - // Fall through to try parsing with removing stuff around error location
21.472 - // (Don't bother doing this if errorOffset==caretOffset since that would try the same
21.473 - // source as EDITED_DOT which has no better chance of succeeding...)
21.474 - if (context.errorOffset != -1 && context.errorOffset != context.caretOffset) {
21.475 - return parse(context, Sanitize.ERROR_DOT);
21.476 - }
21.477 -
21.478 - // Fall through to try the next trick
21.479 - case ERROR_DOT:
21.480 -
21.481 - // We've tried removing dots - now try removing the whole line at the error position
21.482 - if (context.errorOffset != -1) {
21.483 - return parse(context, Sanitize.ERROR_LINE);
21.484 - }
21.485 -
21.486 - // Fall through to try the next trick
21.487 - case ERROR_LINE:
21.488 -
21.489 - // Messing with the error line didn't work - we could try "around" the error line
21.490 - // but I'm not attempting that now.
21.491 - // Finally try removing the whole line around the user editing position
21.492 - // (which could be far from where the error is showing up - but if you're typing
21.493 - // say a new "def" statement in a class, this will show up as an error on a mismatched
21.494 - // "end" statement rather than here
21.495 - if (context.caretOffset != -1) {
21.496 - return parse(context, Sanitize.EDITED_LINE);
21.497 - }
21.498 -
21.499 - // Fall through for default handling
21.500 - case EDITED_LINE:
21.501 - default:
21.502 - // We're out of tricks - just return the failed parse result
21.503 - return new PythonParserResult(null, context.snapshot);
21.504 - }
21.505 - }
21.506 -
21.507 - /**
21.508 - * Try cleaning up the source buffer around the current offset to increase
21.509 - * likelihood of parse success. Initially this method had a lot of
21.510 - * logic to determine whether a parse was likely to fail (e.g. invoking
21.511 - * the isEndMissing method from bracket completion etc.).
21.512 - * However, I am now trying a parse with the real source first, and then
21.513 - * only if that fails do I try parsing with sanitized source. Therefore,
21.514 - * this method has to be less conservative in ripping out code since it
21.515 - * will only be used when the regular source is failing.
21.516 - *
21.517 - * @todo Automatically close current statement by inserting ";"
21.518 - * @todo Handle sanitizing "new ^" from parse errors
21.519 - * @todo Replace "end" insertion fix with "}" insertion
21.520 - */
21.521 - private boolean sanitizeSource(Context context, Sanitize sanitizing) {
21.522 - int offset = context.caretOffset;
21.523 -
21.524 - // Let caretOffset represent the offset of the portion of the buffer we'll be operating on
21.525 - if ((sanitizing == Sanitize.ERROR_DOT) || (sanitizing == Sanitize.ERROR_LINE)) {
21.526 - offset = context.errorOffset;
21.527 - }
21.528 -
21.529 - // Don't attempt cleaning up the source if we don't have the buffer position we need
21.530 - if (offset == -1) {
21.531 - return false;
21.532 - }
21.533 -
21.534 - // The user might be editing around the given caretOffset.
21.535 - // See if it looks modified
21.536 - // Insert an end statement? Insert a } marker?
21.537 - String doc = context.source;
21.538 - if (offset > doc.length()) {
21.539 - return false;
21.540 - }
21.541 -
21.542 - try {
21.543 - // Sometimes the offset shows up on the next line
21.544 - if (GsfUtilities.isRowEmpty(doc, offset) || GsfUtilities.isRowWhite(doc, offset)) {
21.545 - offset = GsfUtilities.getRowStart(doc, offset) - 1;
21.546 - if (offset < 0) {
21.547 - offset = 0;
21.548 - }
21.549 - }
21.550 -
21.551 - if (!(GsfUtilities.isRowEmpty(doc, offset) || GsfUtilities.isRowWhite(doc, offset))) {
21.552 - if ((sanitizing == Sanitize.EDITED_LINE) || (sanitizing == Sanitize.ERROR_LINE)) {
21.553 - // See if I should try to remove the current line, since it has text on it.
21.554 - int lineEnd = GsfUtilities.getRowLastNonWhite(doc, offset);
21.555 -
21.556 - if (lineEnd != -1) {
21.557 - lineEnd++; // lineEnd is exclusive, not inclusive
21.558 - StringBuilder sb = new StringBuilder(doc.length());
21.559 - int lineStart = GsfUtilities.getRowStart(doc, offset);
21.560 - if (lineEnd >= lineStart + 2) {
21.561 - sb.append(doc.substring(0, lineStart));
21.562 - sb.append("//");
21.563 - int rest = lineStart + 2;
21.564 - if (rest < doc.length()) {
21.565 - sb.append(doc.substring(rest, doc.length()));
21.566 - }
21.567 - } else {
21.568 - // A line with just one character - can't replace with a comment
21.569 - // Just replace the char with a space
21.570 - sb.append(doc.substring(0, lineStart));
21.571 - sb.append(" ");
21.572 - int rest = lineStart + 1;
21.573 - if (rest < doc.length()) {
21.574 - sb.append(doc.substring(rest, doc.length()));
21.575 - }
21.576 -
21.577 - }
21.578 -
21.579 - assert sb.length() == doc.length();
21.580 -
21.581 - context.sanitizedRange = new OffsetRange(lineStart, lineEnd);
21.582 - context.sanitizedSource = sb.toString();
21.583 - context.sanitizedContents = doc.substring(lineStart, lineEnd);
21.584 - return true;
21.585 - }
21.586 - } else {
21.587 - assert sanitizing == Sanitize.ERROR_DOT || sanitizing == Sanitize.EDITED_DOT;
21.588 - // Try nuking dots/colons from this line
21.589 - // See if I should try to remove the current line, since it has text on it.
21.590 - int lineStart = GsfUtilities.getRowStart(doc, offset);
21.591 - int lineEnd = offset - 1;
21.592 - while (lineEnd >= lineStart && lineEnd < doc.length()) {
21.593 - if (!Character.isWhitespace(doc.charAt(lineEnd))) {
21.594 - break;
21.595 - }
21.596 - lineEnd--;
21.597 - }
21.598 - if (lineEnd > lineStart) {
21.599 - StringBuilder sb = new StringBuilder(doc.length());
21.600 - String line = doc.substring(lineStart, lineEnd + 1);
21.601 - int removeChars = 0;
21.602 - int removeEnd = lineEnd + 1;
21.603 - boolean isLineEnd = GsfUtilities.getRowLastNonWhite(context.source, lineEnd) <= lineEnd;
21.604 -
21.605 - if (line.endsWith(".")) { // NOI18N
21.606 - removeChars = 1;
21.607 - } else if (line.endsWith("(")) { // NOI18N
21.608 - if (isLineEnd) {
21.609 - removeChars = 1;
21.610 - }
21.611 - } else if (line.endsWith(",")) { // NOI18N removeChars = 1;
21.612 - if (!isLineEnd) {
21.613 - removeChars = 1;
21.614 - }
21.615 - } else if (line.endsWith(", ")) { // NOI18N
21.616 - if (!isLineEnd) {
21.617 - removeChars = 2;
21.618 - }
21.619 - } else if (line.endsWith(",)")) { // NOI18N
21.620 - // Handle lone comma in parameter list - e.g.
21.621 - // type "foo(a," -> you end up with "foo(a,|)" which doesn't parse - but
21.622 - // the line ends with ")", not "," !
21.623 - // Just remove the comma
21.624 - removeChars = 1;
21.625 - removeEnd--;
21.626 - } else if (line.endsWith(", )")) { // NOI18N
21.627 - // Just remove the comma
21.628 - removeChars = 1;
21.629 - removeEnd -= 2;
21.630 - } else if (line.endsWith(" def") && isLineEnd) { // NOI18N
21.631 - removeChars = 3;
21.632 - } else {
21.633 -// // Make sure the line doesn't end with one of the JavaScript keywords
21.634 -// // (new, do, etc) - we can't handle that!
21.635 -// for (String keyword : PythonUtils.PYTHON_KEYWORDS) { // reserved words are okay
21.636 -// if (line.endsWith(keyword)) {
21.637 -// if ("print".equals(keyword)) { // NOI18N
21.638 -// // Only remove the keyword if it's the end of the line. Otherwise,
21.639 -// // it could have just been typed in front of something (e.g. inserted a print) and we don't
21.640 -// // want to confuse the parser with "va foo" instead of "var foo"
21.641 -// if (!isLineEnd) {
21.642 -// continue;
21.643 -// }
21.644 -// }
21.645 -// removeChars = 1;
21.646 -// break;
21.647 -// }
21.648 -// }
21.649 - }
21.650 -
21.651 - if (removeChars == 0) {
21.652 - return false;
21.653 - }
21.654 -
21.655 - int removeStart = removeEnd - removeChars;
21.656 -
21.657 - sb.append(doc.substring(0, removeStart));
21.658 -
21.659 - for (int i = 0; i < removeChars; i++) {
21.660 - sb.append(' ');
21.661 - }
21.662 -
21.663 - if (removeEnd < doc.length()) {
21.664 - sb.append(doc.substring(removeEnd, doc.length()));
21.665 - }
21.666 - assert sb.length() == doc.length();
21.667 -
21.668 - context.sanitizedRange = new OffsetRange(removeStart, removeEnd);
21.669 - context.sanitizedSource = sb.toString();
21.670 - context.sanitizedContents = doc.substring(removeStart, removeEnd);
21.671 - return true;
21.672 - }
21.673 - }
21.674 - }
21.675 - } catch (BadLocationException ble) {
21.676 - Exceptions.printStackTrace(ble);
21.677 - }
21.678 -
21.679 - return false;
21.680 - }
21.681 -
21.682 - private static int findLineOffset(String source, int line) {
21.683 - int offset = -1;
21.684 - for (int i = 0; i < line; i++) {
21.685 - offset = source.indexOf("\n", offset+1);
21.686 - if (offset == -1) {
21.687 - return source.length();
21.688 - }
21.689 - }
21.690 -
21.691 - return Math.min(source.length(), offset+1);
21.692 - }
21.693 -
21.694 - /** Attempts to sanitize the input buffer */
21.695 - public static enum Sanitize {
21.696 - /** Only parse the current file accurately, don't try heuristics */
21.697 - NEVER,
21.698 - /** Perform no sanitization */
21.699 - NONE,
21.700 - /** Try to remove the trailing . or :: at the caret line */
21.701 - EDITED_DOT,
21.702 - /** Try to remove the trailing . or :: at the error position, or the prior
21.703 - * line, or the caret line */
21.704 - ERROR_DOT,
21.705 - /** Try to cut out the error line */
21.706 - ERROR_LINE,
21.707 - /** Try to cut out the current edited line, if known */
21.708 - EDITED_LINE,
21.709 - }
21.710 -
21.711 - /** Sanitize context */
21.712 - public static class Context {
21.713 - private FileObject file;
21.714 -// private ParseListener listener;
21.715 - private int errorOffset;
21.716 - private String source;
21.717 - private String sanitizedSource;
21.718 - private OffsetRange sanitizedRange = OffsetRange.NONE;
21.719 - private String sanitizedContents;
21.720 - private int caretOffset;
21.721 - private Sanitize sanitized = Sanitize.NONE;
21.722 -// private TranslatedSource translatedSource;
21.723 -// private Parser.Job job;
21.724 - private Snapshot snapshot;
21.725 - private Task task;
21.726 - private SourceModificationEvent event;
21.727 -//
21.728 -// public Context(ParserFile parserFile, ParseListener listener, String source, int caretOffset, TranslatedSource translatedSource, Parser.Job job) {
21.729 -// this.file = parserFile;
21.730 -// this.listener = listener;
21.731 -// this.source = source;
21.732 -// this.caretOffset = caretOffset;
21.733 -// this.translatedSource = translatedSource;
21.734 -// this.job = job;
21.735 -//
21.736 -//
21.737 -// if (caretOffset != -1) {
21.738 -// sanitized = Sanitize.EDITED_DOT;
21.739 -// }
21.740 -// }
21.741 -//
21.742 -// @Override
21.743 -// public String toString() {
21.744 -// return "PythonParser.Context(" + file.toString() + ")"; // NOI18N
21.745 -// }
21.746 -//
21.747 -// public OffsetRange getSanitizedRange() {
21.748 -// return sanitizedRange;
21.749 -// }
21.750 -//
21.751 -// public Sanitize getSanitized() {
21.752 -// return sanitized;
21.753 -// }
21.754 -//
21.755 -// public String getSanitizedSource() {
21.756 -// return sanitizedSource;
21.757 -// }
21.758 -//
21.759 -// public int getErrorOffset() {
21.760 -// return errorOffset;
21.761 -// }
21.762 - }
21.763 -}
22.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonParserResult.java Fri Sep 18 16:20:24 2015 -0500
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,153 +0,0 @@
22.4 -/*
22.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
22.6 - *
22.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
22.8 - *
22.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
22.10 - * Other names may be trademarks of their respective owners.
22.11 - *
22.12 - * The contents of this file are subject to the terms of either the GNU
22.13 - * General Public License Version 2 only ("GPL") or the Common
22.14 - * Development and Distribution License("CDDL") (collectively, the
22.15 - * "License"). You may not use this file except in compliance with the
22.16 - * License. You can obtain a copy of the License at
22.17 - * http://www.netbeans.org/cddl-gplv2.html
22.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
22.19 - * specific language governing permissions and limitations under the
22.20 - * License. When distributing the software, include this License Header
22.21 - * Notice in each file and include the License file at
22.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
22.23 - * particular file as subject to the "Classpath" exception as provided
22.24 - * by Oracle in the GPL Version 2 section of the License file that
22.25 - * accompanied this code. If applicable, add the following below the
22.26 - * License Header, with the fields enclosed by brackets [] replaced by
22.27 - * your own identifying information:
22.28 - * "Portions Copyrighted [year] [name of copyright owner]"
22.29 - *
22.30 - * Contributor(s):
22.31 - *
22.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
22.33 - */
22.34 -package org.netbeans.modules.python.editor;
22.35 -
22.36 -import java.util.Collections;
22.37 -import java.util.LinkedList;
22.38 -import java.util.List;
22.39 -import org.netbeans.api.annotations.common.NonNull;
22.40 -import org.netbeans.modules.csl.api.Error;
22.41 -import org.netbeans.modules.csl.api.OffsetRange;
22.42 -import org.netbeans.modules.csl.spi.ParserResult;
22.43 -import org.netbeans.modules.parsing.api.Snapshot;
22.44 -import org.netbeans.modules.python.editor.PythonParser.Sanitize;
22.45 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
22.46 -import org.python.antlr.PythonTree;
22.47 -
22.48 -/**
22.49 - * A ParserResult for Python. The AST Jython's AST.
22.50 - *
22.51 - * @todo Cache AstPath for caret position here!
22.52 - * @author Tor Norbye
22.53 - */
22.54 -public class PythonParserResult extends ParserResult {
22.55 - private PythonTree root;
22.56 - private List<Error> errors;
22.57 - private OffsetRange sanitizedRange = OffsetRange.NONE;
22.58 - private String source;
22.59 - private String sanitizedContents;
22.60 - private PythonParser.Sanitize sanitized;
22.61 - private PythonStructureScanner.AnalysisResult analysisResult;
22.62 - private SymbolTable symbolTable;
22.63 - private int codeTemplateOffset = -1;
22.64 -
22.65 - public PythonParserResult(PythonTree tree, @NonNull Snapshot snapshot) {
22.66 - super(snapshot);
22.67 - this.root = tree;
22.68 - this.errors = new LinkedList<>();
22.69 - }
22.70 -
22.71 - public PythonTree getRoot() {
22.72 - return root;
22.73 - }
22.74 -
22.75 - @Override
22.76 - public List<? extends Error> getDiagnostics() {
22.77 - return errors;
22.78 - }
22.79 -
22.80 - @Override
22.81 - protected void invalidate() {
22.82 - }
22.83 -
22.84 - public void setErrors(List<? extends Error> errors) {
22.85 - this.errors.clear();
22.86 - this.errors.addAll(errors);
22.87 - }
22.88 -
22.89 - /**
22.90 - * Set the range of source that was sanitized, if any.
22.91 - */
22.92 - void setSanitized(PythonParser.Sanitize sanitized, OffsetRange sanitizedRange, String sanitizedContents) {
22.93 - this.sanitized = sanitized;
22.94 - this.sanitizedRange = sanitizedRange;
22.95 - this.sanitizedContents = sanitizedContents;
22.96 - if (sanitizedContents == null || sanitizedRange == OffsetRange.NONE) {
22.97 - this.sanitized = Sanitize.NONE;
22.98 - }
22.99 - }
22.100 -
22.101 - public PythonParser.Sanitize getSanitized() {
22.102 - return sanitized;
22.103 - }
22.104 -
22.105 - /**
22.106 - * Return whether the source code for the parse result was "cleaned"
22.107 - * or "sanitized" (modified to reduce chance of parser errors) or not.
22.108 - * This method returns OffsetRange.NONE if the source was not sanitized,
22.109 - * otherwise returns the actual sanitized range.
22.110 - */
22.111 - public OffsetRange getSanitizedRange() {
22.112 - return sanitizedRange;
22.113 - }
22.114 -
22.115 - public SymbolTable getSymbolTable() {
22.116 - if (symbolTable == null) {
22.117 - symbolTable = new SymbolTable(root, getSnapshot().getSource().getFileObject());
22.118 - }
22.119 -
22.120 - return symbolTable;
22.121 - }
22.122 -
22.123 - public String getSanitizedContents() {
22.124 - return sanitizedContents;
22.125 - }
22.126 -
22.127 - public String getSource() {
22.128 - return source;
22.129 - }
22.130 -
22.131 - public void setSource(String source) {
22.132 - this.source = source;
22.133 - }
22.134 -
22.135 - /**
22.136 - * @return the codeTemplateOffset
22.137 - */
22.138 - public int getCodeTemplateOffset() {
22.139 - return codeTemplateOffset;
22.140 - }
22.141 -
22.142 - /**
22.143 - * @param codeTemplateOffset the codeTemplateOffset to set
22.144 - */
22.145 - public void setCodeTemplateOffset(int codeTemplateOffset) {
22.146 - this.codeTemplateOffset = codeTemplateOffset;
22.147 - }
22.148 -
22.149 - public void addError(Error e) {
22.150 - errors.add(e);
22.151 - }
22.152 -
22.153 - public boolean isValid() {
22.154 - return errors.isEmpty();
22.155 - }
22.156 -}
23.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonSemanticHighlighter.java Fri Sep 18 16:20:24 2015 -0500
23.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonSemanticHighlighter.java Mon Sep 21 13:01:16 2015 +0200
23.3 @@ -30,6 +30,8 @@
23.4 */
23.5 package org.netbeans.modules.python.editor;
23.6
23.7 +import org.netbeans.modules.python.source.PythonParserResult;
23.8 +import org.netbeans.modules.python.source.PythonAstUtils;
23.9 import java.util.EnumSet;
23.10 import java.util.HashMap;
23.11 import java.util.Map;
23.12 @@ -37,12 +39,10 @@
23.13 import org.netbeans.modules.csl.api.ColoringAttributes;
23.14 import org.netbeans.modules.csl.api.OffsetRange;
23.15 import org.netbeans.modules.csl.api.SemanticAnalyzer;
23.16 -import org.netbeans.modules.csl.spi.ParserResult;
23.17 -import org.netbeans.modules.parsing.spi.Parser.Result;
23.18 import org.netbeans.modules.parsing.spi.Scheduler;
23.19 import org.netbeans.modules.parsing.spi.SchedulerEvent;
23.20 -import org.netbeans.modules.python.editor.scopes.ScopeInfo;
23.21 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
23.22 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
23.23 +import org.netbeans.modules.python.source.scopes.SymbolTable;
23.24 import org.openide.util.Exceptions;
23.25 import org.python.antlr.PythonTree;
23.26 import org.python.antlr.Visitor;
24.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonStructureItem.java Fri Sep 18 16:20:24 2015 -0500
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,195 +0,0 @@
24.4 -/*
24.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
24.6 - *
24.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
24.8 - *
24.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
24.10 - * Other names may be trademarks of their respective owners.
24.11 - *
24.12 - * The contents of this file are subject to the terms of either the GNU
24.13 - * General Public License Version 2 only ("GPL") or the Common
24.14 - * Development and Distribution License("CDDL") (collectively, the
24.15 - * "License"). You may not use this file except in compliance with the
24.16 - * License. You can obtain a copy of the License at
24.17 - * http://www.netbeans.org/cddl-gplv2.html
24.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
24.19 - * specific language governing permissions and limitations under the
24.20 - * License. When distributing the software, include this License Header
24.21 - * Notice in each file and include the License file at
24.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
24.23 - * particular file as subject to the "Classpath" exception as provided
24.24 - * by Oracle in the GPL Version 2 section of the License file that
24.25 - * accompanied this code. If applicable, add the following below the
24.26 - * License Header, with the fields enclosed by brackets [] replaced by
24.27 - * your own identifying information:
24.28 - * "Portions Copyrighted [year] [name of copyright owner]"
24.29 - *
24.30 - * Contributor(s):
24.31 - *
24.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
24.33 - */
24.34 -package org.netbeans.modules.python.editor;
24.35 -
24.36 -import java.util.ArrayList;
24.37 -import java.util.Collections;
24.38 -import java.util.List;
24.39 -import javax.swing.ImageIcon;
24.40 -import org.netbeans.modules.csl.api.ElementHandle;
24.41 -import org.netbeans.modules.csl.api.ElementKind;
24.42 -import org.netbeans.modules.csl.api.HtmlFormatter;
24.43 -import org.netbeans.modules.csl.api.Modifier;
24.44 -import org.netbeans.modules.csl.api.StructureItem;
24.45 -import org.netbeans.modules.python.editor.elements.AstElement;
24.46 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
24.47 -import org.openide.util.ImageUtilities;
24.48 -import org.python.antlr.PythonTree;
24.49 -import org.python.antlr.ast.ClassDef;
24.50 -import org.python.antlr.ast.FunctionDef;
24.51 -
24.52 -public final class PythonStructureItem extends AstElement implements StructureItem {
24.53 - private List<PythonStructureItem> children;
24.54 - private PythonStructureItem parent;
24.55 -
24.56 - public PythonStructureItem(SymbolTable scopes, ClassDef def) {
24.57 - this(scopes, def, def.getInternalName(), ElementKind.CLASS);
24.58 - }
24.59 -
24.60 - public PythonStructureItem(SymbolTable scopes, FunctionDef def) {
24.61 - this(scopes, def, def.getInternalName(), ElementKind.METHOD);
24.62 - if ("__init__".equals(name)) { // NOI18N
24.63 - kind = ElementKind.CONSTRUCTOR;
24.64 - }
24.65 - }
24.66 -
24.67 - public PythonStructureItem(SymbolTable scopes, PythonTree node, String name, ElementKind kind) {
24.68 - super(scopes, node, name, kind);
24.69 - this.node = node;
24.70 - this.name = name;
24.71 - this.kind = kind;
24.72 - }
24.73 -
24.74 - void add(PythonStructureItem child) {
24.75 - if (children == null) {
24.76 - children = new ArrayList<>();
24.77 - }
24.78 - children.add(child);
24.79 - child.parent = this;
24.80 - }
24.81 -
24.82 - @Override
24.83 - public String getSortText() {
24.84 - return name;
24.85 - }
24.86 -
24.87 - @Override
24.88 - public String getHtml(HtmlFormatter formatter) {
24.89 - formatter.appendText(name);
24.90 - if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
24.91 - FunctionDef def = (FunctionDef)node;
24.92 - List<String> params = PythonAstUtils.getParameters(def);
24.93 - if (params.size() > 0) {
24.94 - boolean isFirst = true;
24.95 - formatter.appendHtml("(");
24.96 - formatter.parameters(true);
24.97 - for (String param : params) {
24.98 - if (isFirst) {
24.99 - isFirst = false;
24.100 - } else {
24.101 - formatter.appendText(",");
24.102 - }
24.103 - formatter.appendText(param);
24.104 - }
24.105 - formatter.parameters(false);
24.106 - formatter.appendHtml(")");
24.107 - }
24.108 - }
24.109 - return formatter.getText();
24.110 - }
24.111 -
24.112 - @Override
24.113 - public ElementHandle getElementHandle() {
24.114 - return null;
24.115 - }
24.116 -
24.117 - @Override
24.118 - public boolean isLeaf() {
24.119 - return children == null;
24.120 - }
24.121 -
24.122 - @Override
24.123 - public List<? extends StructureItem> getNestedItems() {
24.124 - return children == null ? Collections.<StructureItem>emptyList() : children;
24.125 - }
24.126 -
24.127 - @Override
24.128 - public long getPosition() {
24.129 - return node.getCharStartIndex();
24.130 - }
24.131 -
24.132 - @Override
24.133 - public long getEndPosition() {
24.134 - return node.getCharStopIndex();
24.135 - }
24.136 -
24.137 - @Override
24.138 - public ImageIcon getCustomIcon() {
24.139 - if (kind == ElementKind.CLASS && getModifiers().contains(Modifier.PRIVATE)) {
24.140 - // GSF doesn't automatically handle icons on private classes, so I have to
24.141 - // work around that here
24.142 - return ImageUtilities.loadImageIcon("org/netbeans/modules/python/editor/resources/private-class.png", false); //NOI18N
24.143 - }
24.144 -
24.145 - return null;
24.146 - }
24.147 -
24.148 - @Override
24.149 - public Object getSignature() {
24.150 - if ((kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) && parent != null &&
24.151 - parent.kind == ElementKind.CLASS) {
24.152 - return parent.name + "." + name;
24.153 - }
24.154 - return super.getSignature();
24.155 - }
24.156 -
24.157 - @Override
24.158 - public boolean equals(Object obj) {
24.159 - if (obj == null) {
24.160 - return false;
24.161 - }
24.162 - if (getClass() != obj.getClass()) {
24.163 - return false;
24.164 - }
24.165 - final PythonStructureItem other = (PythonStructureItem)obj;
24.166 - if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
24.167 - return false;
24.168 - }
24.169 - if (this.kind != other.kind) {
24.170 - return false;
24.171 - }
24.172 - if (this.getModifiers() != other.getModifiers() && (this.modifiers == null || !this.modifiers.equals(other.modifiers))) {
24.173 - return false;
24.174 - }
24.175 -
24.176 - if ((kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) && node != null && other.node != null) {
24.177 - FunctionDef def = (FunctionDef)node;
24.178 - List<String> params = PythonAstUtils.getParameters(def);
24.179 - List<String> otherParams = PythonAstUtils.getParameters((FunctionDef)other.node);
24.180 - if (!params.equals((otherParams))) {
24.181 - return false;
24.182 - }
24.183 - }
24.184 -
24.185 -// if (this.getNestedItems().size() != other.getNestedItems().size()) {
24.186 -// return false;
24.187 -// }
24.188 -//
24.189 - return true;
24.190 - }
24.191 -
24.192 - @Override
24.193 - public int hashCode() {
24.194 - int hash = 7;
24.195 - hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0);
24.196 - return hash;
24.197 - }
24.198 -}
25.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonStructureScanner.java Fri Sep 18 16:20:24 2015 -0500
25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3 @@ -1,274 +0,0 @@
25.4 -/*
25.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
25.6 - *
25.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
25.8 - *
25.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
25.10 - * Other names may be trademarks of their respective owners.
25.11 - *
25.12 - * The contents of this file are subject to the terms of either the GNU
25.13 - * General Public License Version 2 only ("GPL") or the Common
25.14 - * Development and Distribution License("CDDL") (collectively, the
25.15 - * "License"). You may not use this file except in compliance with the
25.16 - * License. You can obtain a copy of the License at
25.17 - * http://www.netbeans.org/cddl-gplv2.html
25.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
25.19 - * specific language governing permissions and limitations under the
25.20 - * License. When distributing the software, include this License Header
25.21 - * Notice in each file and include the License file at
25.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
25.23 - * particular file as subject to the "Classpath" exception as provided
25.24 - * by Oracle in the GPL Version 2 section of the License file that
25.25 - * accompanied this code. If applicable, add the following below the
25.26 - * License Header, with the fields enclosed by brackets [] replaced by
25.27 - * your own identifying information:
25.28 - * "Portions Copyrighted [year] [name of copyright owner]"
25.29 - *
25.30 - * Contributor(s):
25.31 - *
25.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
25.33 - */
25.34 -package org.netbeans.modules.python.editor;
25.35 -
25.36 -import java.util.ArrayList;
25.37 -import java.util.Collections;
25.38 -import java.util.HashMap;
25.39 -import java.util.List;
25.40 -import java.util.Map;
25.41 -import javax.swing.text.BadLocationException;
25.42 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
25.43 -import org.netbeans.editor.BaseDocument;
25.44 -import org.netbeans.editor.Utilities;
25.45 -import org.netbeans.modules.csl.api.ElementKind;
25.46 -import org.netbeans.modules.csl.api.OffsetRange;
25.47 -import org.netbeans.modules.csl.api.StructureItem;
25.48 -import org.netbeans.modules.csl.api.StructureScanner;
25.49 -import org.netbeans.modules.csl.api.StructureScanner.Configuration;
25.50 -import org.netbeans.modules.csl.spi.GsfUtilities;
25.51 -import org.netbeans.modules.csl.spi.ParserResult;
25.52 -import org.netbeans.modules.python.editor.scopes.ScopeInfo;
25.53 -import org.netbeans.modules.python.editor.scopes.SymInfo;
25.54 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
25.55 -import org.openide.util.Exceptions;
25.56 -import org.python.antlr.PythonTree;
25.57 -import org.python.antlr.Visitor;
25.58 -import org.python.antlr.ast.ClassDef;
25.59 -import org.python.antlr.ast.FunctionDef;
25.60 -import org.python.antlr.ast.Str;
25.61 -
25.62 -/**
25.63 - * This class analyzes the structure of a Python parse tree
25.64 - * and infers structure (navigation items, folds, etc.)
25.65 - *
25.66 - * @author Tor Norbye
25.67 - */
25.68 -public class PythonStructureScanner implements StructureScanner {
25.69 -
25.70 - public static AnalysisResult analyze(PythonParserResult info) {
25.71 - AnalysisResult analysisResult = new AnalysisResult();
25.72 -
25.73 - PythonTree root = PythonAstUtils.getRoot(info);
25.74 - if (root != null) {
25.75 - SymbolTable scopes = PythonAstUtils.getParseResult(info).getSymbolTable();
25.76 - StructureVisitor visitor = new StructureVisitor(scopes);
25.77 - try {
25.78 - visitor.visit(root);
25.79 - analysisResult.setElements(visitor.getRoots());
25.80 - } catch (Exception ex) {
25.81 - Exceptions.printStackTrace(ex);
25.82 - }
25.83 - }
25.84 -
25.85 - return analysisResult;
25.86 - }
25.87 -
25.88 - @Override
25.89 - public List<? extends StructureItem> scan(ParserResult info) {
25.90 - PythonParserResult parseResult = PythonAstUtils.getParseResult(info);
25.91 - if (parseResult == null) {
25.92 - return Collections.emptyList();
25.93 - }
25.94 -
25.95 - return getStructure(parseResult).getElements();
25.96 - }
25.97 -
25.98 - public PythonStructureScanner.AnalysisResult getStructure(PythonParserResult result) {
25.99 - // TODO Cache ! (Used to be in PythonParserResult
25.100 - AnalysisResult analysisResult = PythonStructureScanner.analyze(result);
25.101 - return analysisResult;
25.102 - }
25.103 -
25.104 - @Override
25.105 - public Map<String, List<OffsetRange>> folds(ParserResult info) {
25.106 - PythonParserResult result = PythonAstUtils.getParseResult(info);
25.107 - PythonTree root = PythonAstUtils.getRoot(result);
25.108 - if (root == null) {
25.109 - return Collections.emptyMap();
25.110 - }
25.111 -
25.112 - //TranslatedSource source = result.getTranslatedSource();
25.113 - //
25.114 - //AnalysisResult ar = result.getStructure();
25.115 - //
25.116 - //List<?extends AstElement> elements = ar.getElements();
25.117 - //List<StructureItem> itemList = new ArrayList<StructureItem>(elements.size());
25.118 -
25.119 - BaseDocument doc = GsfUtilities.getDocument(result.getSnapshot().getSource().getFileObject(), false);
25.120 - if (doc != null) {
25.121 - try {
25.122 - doc.readLock(); // For Utilities.getRowEnd() access
25.123 - FoldVisitor visitor = new FoldVisitor((PythonParserResult) info, doc);
25.124 - visitor.visit(root);
25.125 - List<OffsetRange> codeBlocks = visitor.getCodeBlocks();
25.126 -
25.127 - Map<String, List<OffsetRange>> folds = new HashMap<>();
25.128 - folds.put("codeblocks", codeBlocks); // NOI18N
25.129 -
25.130 - return folds;
25.131 - } catch (Exception ex) {
25.132 - Exceptions.printStackTrace(ex);
25.133 - } finally {
25.134 - doc.readUnlock();
25.135 - }
25.136 - }
25.137 - return Collections.emptyMap();
25.138 - }
25.139 -
25.140 - @Override
25.141 - public Configuration getConfiguration() {
25.142 - return new Configuration(true, true, -1);
25.143 - }
25.144 -
25.145 - private static class FoldVisitor extends Visitor {
25.146 - private List<OffsetRange> codeBlocks = new ArrayList<>();
25.147 - private PythonParserResult info;
25.148 - private BaseDocument doc;
25.149 -
25.150 - private FoldVisitor(PythonParserResult info, BaseDocument doc) {
25.151 - this.info = info;
25.152 - this.doc = doc;
25.153 - }
25.154 -
25.155 - private void addFoldRange(PythonTree node) {
25.156 - OffsetRange astRange = PythonAstUtils.getRange(node);
25.157 -
25.158 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
25.159 - if (lexRange != OffsetRange.NONE) {
25.160 - try {
25.161 - int startRowEnd = Utilities.getRowEnd(doc, lexRange.getStart());
25.162 - if (startRowEnd < lexRange.getEnd()) {
25.163 - codeBlocks.add(new OffsetRange(startRowEnd, lexRange.getEnd()));
25.164 - }
25.165 - } catch (BadLocationException ex) {
25.166 - Exceptions.printStackTrace(ex);
25.167 - }
25.168 - }
25.169 - }
25.170 -
25.171 - @Override
25.172 - public Object visitClassDef(ClassDef node) throws Exception {
25.173 - addFoldRange(node);
25.174 -
25.175 - return super.visitClassDef(node);
25.176 - }
25.177 -
25.178 - @Override
25.179 - public Object visitFunctionDef(FunctionDef node) throws Exception {
25.180 - addFoldRange(node);
25.181 -
25.182 - return super.visitFunctionDef(node);
25.183 - }
25.184 -
25.185 - @Override
25.186 - public Object visitStr(Str node) throws Exception {
25.187 - addFoldRange(node);
25.188 - return super.visitStr(node);
25.189 - }
25.190 -
25.191 - public List<OffsetRange> getCodeBlocks() {
25.192 - return codeBlocks;
25.193 - }
25.194 - }
25.195 -
25.196 - private static class StructureVisitor extends Visitor {
25.197 - List<PythonStructureItem> roots = new ArrayList<>();
25.198 - List<PythonStructureItem> stack = new ArrayList<>();
25.199 - SymbolTable scopes;
25.200 -
25.201 - StructureVisitor(SymbolTable scopes) {
25.202 - this.scopes = scopes;
25.203 - }
25.204 -
25.205 - private List<PythonStructureItem> getRoots() {
25.206 - return roots;
25.207 - }
25.208 -
25.209 - @Override
25.210 - public Object visitClassDef(ClassDef def) throws Exception {
25.211 - PythonStructureItem item = new PythonStructureItem(scopes, def);
25.212 - add(item);
25.213 -
25.214 - ScopeInfo scope = scopes.getScopeInfo(def);
25.215 - if (scope != null && scope.attributes.size() > 0) {
25.216 - for (Map.Entry<String, SymInfo> entry : scope.attributes.entrySet()) {
25.217 - // TODO - sort these puppies? Right now their natural order will be
25.218 - // random (hashkey dependent) instead of by source position or by name
25.219 - SymInfo sym = entry.getValue();
25.220 - if (sym.node != null) {
25.221 - String name = entry.getKey();
25.222 - PythonStructureItem attribute = new PythonStructureItem(scopes, sym.node, name, ElementKind.ATTRIBUTE);
25.223 - item.add(attribute);
25.224 - }
25.225 - }
25.226 - }
25.227 -
25.228 - stack.add(item);
25.229 - Object result = super.visitClassDef(def);
25.230 - stack.remove(stack.size() - 1);
25.231 -
25.232 - return result;
25.233 - }
25.234 -
25.235 - @Override
25.236 - public Object visitFunctionDef(FunctionDef def) throws Exception {
25.237 - PythonStructureItem item = new PythonStructureItem(scopes, def);
25.238 -
25.239 - add(item);
25.240 - stack.add(item);
25.241 - Object result = super.visitFunctionDef(def);
25.242 - stack.remove(stack.size() - 1);
25.243 -
25.244 - return result;
25.245 - }
25.246 -
25.247 - private void add(PythonStructureItem child) {
25.248 - PythonStructureItem parent = stack.size() > 0 ? stack.get(stack.size() - 1) : null;
25.249 - if (parent == null) {
25.250 - roots.add(child);
25.251 - } else {
25.252 - parent.add(child);
25.253 - }
25.254 - }
25.255 - }
25.256 -
25.257 - public static class AnalysisResult {
25.258 - //private List<?extends AstElement> elements;
25.259 - private List<PythonStructureItem> elements;
25.260 -
25.261 - private AnalysisResult() {
25.262 - }
25.263 -
25.264 - //private void setElements(List<?extends AstElement> elements) {
25.265 - private void setElements(List<PythonStructureItem> elements) {
25.266 - this.elements = elements;
25.267 - }
25.268 -
25.269 - //public List<?extends AstElement> getElements() {
25.270 - public List<PythonStructureItem> getElements() {
25.271 - if (elements == null) {
25.272 - return Collections.emptyList();
25.273 - }
25.274 - return elements;
25.275 - }
25.276 - }
25.277 -}
26.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonTypeAnalyzer.java Fri Sep 18 16:20:24 2015 -0500
26.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonTypeAnalyzer.java Mon Sep 21 13:01:16 2015 +0200
26.3 @@ -30,6 +30,9 @@
26.4 */
26.5 package org.netbeans.modules.python.editor;
26.6
26.7 +import org.netbeans.modules.python.source.PythonIndex;
26.8 +import org.netbeans.modules.python.source.PythonAstUtils;
26.9 +import org.netbeans.modules.python.source.PythonParserResult;
26.10 import java.util.Collections;
26.11 import java.util.HashMap;
26.12 import java.util.LinkedList;
26.13 @@ -39,9 +42,9 @@
26.14 import org.netbeans.api.lexer.TokenSequence;
26.15 import org.netbeans.editor.BaseDocument;
26.16 import org.netbeans.modules.csl.api.OffsetRange;
26.17 -import org.netbeans.modules.python.editor.lexer.PythonCommentTokenId;
26.18 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
26.19 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
26.20 +import org.netbeans.modules.python.source.lexer.PythonCommentTokenId;
26.21 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
26.22 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
26.23 import org.openide.filesystems.FileObject;
26.24 import org.openide.util.Exceptions;
26.25 import org.python.antlr.PythonTree;
27.1 --- a/python.editor/src/org/netbeans/modules/python/editor/PythonUtils.java Fri Sep 18 16:20:24 2015 -0500
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,536 +0,0 @@
27.4 -/*
27.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
27.6 - *
27.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
27.8 - *
27.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
27.10 - * Other names may be trademarks of their respective owners.
27.11 - *
27.12 - * The contents of this file are subject to the terms of either the GNU
27.13 - * General Public License Version 2 only ("GPL") or the Common
27.14 - * Development and Distribution License("CDDL") (collectively, the
27.15 - * "License"). You may not use this file except in compliance with the
27.16 - * License. You can obtain a copy of the License at
27.17 - * http://www.netbeans.org/cddl-gplv2.html
27.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
27.19 - * specific language governing permissions and limitations under the
27.20 - * License. When distributing the software, include this License Header
27.21 - * Notice in each file and include the License file at
27.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
27.23 - * particular file as subject to the "Classpath" exception as provided
27.24 - * by Oracle in the GPL Version 2 section of the License file that
27.25 - * accompanied this code. If applicable, add the following below the
27.26 - * License Header, with the fields enclosed by brackets [] replaced by
27.27 - * your own identifying information:
27.28 - * "Portions Copyrighted [year] [name of copyright owner]"
27.29 - *
27.30 - * Contributor(s):
27.31 - *
27.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
27.33 - */
27.34 -package org.netbeans.modules.python.editor;
27.35 -
27.36 -import java.util.Comparator;
27.37 -import java.util.List;
27.38 -import javax.swing.text.Document;
27.39 -import org.netbeans.api.annotations.common.NonNull;
27.40 -import org.netbeans.api.project.FileOwnerQuery;
27.41 -import org.netbeans.api.project.Project;
27.42 -import org.netbeans.api.project.ProjectUtils;
27.43 -import org.netbeans.api.project.SourceGroup;
27.44 -import org.netbeans.api.project.Sources;
27.45 -import org.netbeans.lib.editor.codetemplates.api.CodeTemplate;
27.46 -import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
27.47 -import org.netbeans.modules.python.api.PythonMIMEResolver;
27.48 -import org.netbeans.modules.python.api.PythonPlatform;
27.49 -import org.netbeans.modules.python.api.PythonPlatformManager;
27.50 -import org.openide.filesystems.FileObject;
27.51 -import org.openide.filesystems.FileUtil;
27.52 -import org.openide.util.NbBundle;
27.53 -import org.python.antlr.PythonTree;
27.54 -import org.python.antlr.ast.Attribute;
27.55 -import org.python.antlr.ast.Name;
27.56 -
27.57 -/**
27.58 - *
27.59 - * @author Tor Norbye
27.60 - */
27.61 -public class PythonUtils {
27.62 - public static boolean canContainPython(FileObject f) {
27.63 - String mimeType = f.getMIMEType();
27.64 - return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(mimeType);
27.65 - // TODO: "text/x-yaml".equals(mimeType) || // NOI18N
27.66 - // RubyInstallation.RHTML_MIME_TYPE.equals(mimeType);
27.67 - }
27.68 -
27.69 - public static boolean isPythonFile(FileObject f) {
27.70 - return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(f.getMIMEType());
27.71 - }
27.72 -
27.73 - public static boolean isRstFile(FileObject f) {
27.74 - return "rst".equals(f.getExt()); // NOI18N
27.75 - }
27.76 -
27.77 - public static boolean isPythonDocument(Document doc) {
27.78 - String mimeType = (String)doc.getProperty("mimeType"); // NOI18N
27.79 -
27.80 - return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(mimeType);
27.81 - }
27.82 - public static final String DOT__INIT__ = ".__init__"; // NOI18N
27.83 -
27.84 - // From PythonProjectType
27.85 - public static final String SOURCES_TYPE_PYTHON = "python"; // NOI18N
27.86 -
27.87 - // Cache
27.88 - private static FileObject prevParent;
27.89 - private static String prevRootUrl;
27.90 -
27.91 - /**
27.92 - * Produce the module name (including packages) for a given python source file.
27.93 - *
27.94 - * @param fo The source file (can be null, if file is not))
27.95 - * @param file The parser file (can be null, if fo is not).
27.96 - * @param fileName The filename (basename only)
27.97 - * @param projectRelativeName If non null, the path from the project root down to this file
27.98 - * @return A string for the full package module name
27.99 - */
27.100 - public static String getModuleName(@NonNull FileObject fo) {
27.101 -
27.102 - // TODO - use PythonPlatform's library roots!
27.103 -
27.104 - String module = fo.getName();
27.105 -
27.106 - // First see if we're on the load path for the platform, and if so,
27.107 - // use that as the base
27.108 - // TODO - look up platform for the current search context instead of all platforms!!
27.109 - if (fo.getParent() != prevParent) {
27.110 - prevRootUrl = null;
27.111 - prevParent = fo.getParent();
27.112 - }
27.113 -
27.114 - String url = fo.toURL().toExternalForm();
27.115 - if (prevRootUrl == null) {
27.116 - boolean found = false;
27.117 - PythonPlatformManager manager = PythonPlatformManager.getInstance();
27.118 -
27.119 - PlatformSearch:
27.120 - for (String name : manager.getPlatformList()) {
27.121 - PythonPlatform platform = manager.getPlatform(name);
27.122 - if (platform != null) {
27.123 - List<FileObject> unique = platform.getUniqueLibraryRoots();
27.124 - for (FileObject root : unique) {
27.125 - if (FileUtil.isParentOf(root, fo)) {
27.126 - for (FileObject r : platform.getLibraryRoots()) {
27.127 - if (FileUtil.isParentOf(r, fo)) {
27.128 - // See if the folder itself contains
27.129 - // an __init__.py file - if it does,
27.130 - // then include the directory itself
27.131 - // in the package name.
27.132 - if (r.getFileObject("__init__.py") != null) { // NOI18N
27.133 - r = r.getParent();
27.134 - }
27.135 -
27.136 - prevRootUrl = r.toURL().toExternalForm();
27.137 - found = true;
27.138 - break PlatformSearch;
27.139 - }
27.140 - }
27.141 - break PlatformSearch;
27.142 - }
27.143 - }
27.144 - }
27.145 - }
27.146 -
27.147 - if (!found) {
27.148 - Project project = FileOwnerQuery.getOwner(fo);
27.149 - if (project != null) {
27.150 - Sources source = ProjectUtils.getSources(project);
27.151 - // Look up the source path
27.152 - SourceGroup[] sourceGroups = source.getSourceGroups(SOURCES_TYPE_PYTHON);
27.153 - for (SourceGroup group : sourceGroups) {
27.154 - FileObject folder = group.getRootFolder();
27.155 - if (FileUtil.isParentOf(folder, fo)) {
27.156 - // See if the folder itself contains
27.157 - // an __init__.py file - if it does,
27.158 - // then include the directory itself
27.159 - // in the package name.
27.160 - if (folder.getFileObject("__init__.py") != null) { // NOI18N
27.161 - folder = folder.getParent();
27.162 - }
27.163 -
27.164 - prevRootUrl = folder.toURL().toExternalForm();
27.165 - break;
27.166 - }
27.167 - }
27.168 - }
27.169 - }
27.170 - }
27.171 -
27.172 - if (prevRootUrl != null) {
27.173 - module = url.substring(prevRootUrl.length());
27.174 - if (module.startsWith("/")) {
27.175 - module = module.substring(1);
27.176 - }
27.177 - }
27.178 -
27.179 - // Strip off .y extension
27.180 - if (module.endsWith(".py")) { // NOI18N
27.181 - module = module.substring(0, module.length() - 3);
27.182 - }
27.183 -
27.184 - if (module.indexOf('/') != -1) {
27.185 - module = module.replace('/', '.');
27.186 - }
27.187 -
27.188 - if (module.endsWith(DOT__INIT__)) {
27.189 - module = module.substring(0, module.length() - DOT__INIT__.length());
27.190 - }
27.191 -
27.192 - return module;
27.193 - }
27.194 -
27.195 - // According to https://hg.python.org/cpython/file/3.5/Lib/keyword.py
27.196 - // and https://hg.python.org/cpython/file/2.7/Lib/keyword.py
27.197 - static final String[] PYTHON_KEYWORDS = new String[]{
27.198 - "False", // NOI18N
27.199 - "None", // NOI18N
27.200 - "True", // NOI18N
27.201 - "and", // NOI18N
27.202 - "as", // NOI18N
27.203 - "assert", // NOI18N
27.204 - "break", // NOI18N
27.205 - "class", // NOI18N
27.206 - "continue", // NOI18N
27.207 - "def", // NOI18N
27.208 - "del", // NOI18N
27.209 - "elif", // NOI18N
27.210 - "else", // NOI18N
27.211 - "except", // NOI18N
27.212 - "finally", // NOI18N
27.213 - "for", // NOI18N
27.214 - "from", // NOI18N
27.215 - "global", // NOI18N
27.216 - "if", // NOI18N
27.217 - "import", // NOI18N
27.218 - "in", // NOI18N
27.219 - "is", // NOI18N
27.220 - "lambda", // NOI18N
27.221 - "nonlocal", // NOI18N
27.222 - "not", // NOI18N
27.223 - "or", // NOI18N
27.224 - "pass", // NOI18N
27.225 - "raise", // NOI18N
27.226 - "return", // NOI18N
27.227 - "try", // NOI18N
27.228 - "while", // NOI18N
27.229 - "with", // NOI18N
27.230 - "yield", // NOI18N
27.231 - "async", // NOI18N, Python 3.5 only
27.232 - "await", // NOI18N, Python 3.5 only
27.233 - "exec", // NOI18N, Python 2 only
27.234 - "print", // NOI18N, Pytohn 2 only, function in python 3
27.235 - };
27.236 -
27.237 - public static boolean isPythonKeyword(String name) {
27.238 - for (String s : PYTHON_KEYWORDS) {
27.239 - if (s.equals(name)) {
27.240 - return true;
27.241 - }
27.242 - }
27.243 -
27.244 - return false;
27.245 - }
27.246 -
27.247 - /**
27.248 - * Return true iff the name is a class name
27.249 - * @param name The name
27.250 - * @param emptyDefault Whether empty or _ names should be considered a class name or not
27.251 - * @return True iff the name looks like a class name
27.252 - */
27.253 - public static boolean isClassName(String name, boolean emptyDefault) {
27.254 - if (name == null || name.length() == 0) {
27.255 - return emptyDefault;
27.256 - }
27.257 - if (name.startsWith("_") && name.length() > 1) {
27.258 - return Character.isUpperCase(name.charAt(1));
27.259 - }
27.260 -
27.261 - return Character.isUpperCase(name.charAt(0));
27.262 - }
27.263 -
27.264 - /**
27.265 - * Return true iff the name is a method name
27.266 - * @param name The name
27.267 - * @param emptyDefault Whether empty or _ names should be considered a class name or not
27.268 - * @return True iff the name looks like a method name
27.269 - */
27.270 - public static boolean isMethodName(String name, boolean emptyDefault) {
27.271 - if (name == null || name.length() == 0) {
27.272 - return emptyDefault;
27.273 - }
27.274 - if (name.startsWith("__") && name.length() > 2) {
27.275 - return Character.isLowerCase(name.charAt(2));
27.276 - }
27.277 - if (name.startsWith("_") && name.length() > 1) {
27.278 - return Character.isLowerCase(name.charAt(1));
27.279 - }
27.280 -
27.281 - return Character.isLowerCase(name.charAt(0));
27.282 - }
27.283 -
27.284 - public static String getCodeTemplate(CodeTemplateManager ctm, String abbrev, String textPrefix, String wrongTextPrefix) {
27.285 - String templateText = null;
27.286 - for (CodeTemplate t : ctm.getCodeTemplates()) {
27.287 - if (abbrev.equals(t.getAbbreviation())) {
27.288 - templateText = t.getParametrizedText();
27.289 - break;
27.290 - }
27.291 - }
27.292 - if (templateText == null) {
27.293 - for (CodeTemplate t : ctm.getCodeTemplates()) {
27.294 - String text = t.getParametrizedText();
27.295 - if (text.startsWith(textPrefix) && (wrongTextPrefix == null || !text.startsWith(wrongTextPrefix))) {
27.296 - templateText = text;
27.297 - break;
27.298 - }
27.299 - }
27.300 - }
27.301 -
27.302 - return templateText;
27.303 - }
27.304 -
27.305 - public static boolean isValidPythonClassName(String name) {
27.306 - if (isPythonKeyword(name)) {
27.307 - return false;
27.308 - }
27.309 -
27.310 - if (name.trim().length() == 0) {
27.311 - return false;
27.312 - }
27.313 -
27.314 - if (!Character.isUpperCase(name.charAt(0))) {
27.315 - return false;
27.316 - }
27.317 -
27.318 - for (int i = 1; i < name.length(); i++) {
27.319 - char c = name.charAt(i);
27.320 - if (!Character.isJavaIdentifierPart(c)) {
27.321 - return false;
27.322 - }
27.323 -
27.324 - }
27.325 -
27.326 - return true;
27.327 - }
27.328 -
27.329 - /** Is this name a valid operator name? */
27.330 - public static boolean isOperator(String name) {
27.331 - // TODO - update to Python
27.332 - if (name.length() == 0) {
27.333 - return false;
27.334 - }
27.335 -
27.336 - switch (name.charAt(0)) {
27.337 - case '+':
27.338 - return name.equals("+") || name.equals("+@");
27.339 - case '-':
27.340 - return name.equals("-") || name.equals("-@");
27.341 - case '*':
27.342 - return name.equals("*") || name.equals("**");
27.343 - case '<':
27.344 - return name.equals("<") || name.equals("<<") || name.equals("<=") || name.equals("<=>");
27.345 - case '>':
27.346 - return name.equals(">") || name.equals(">>") || name.equals(">=");
27.347 - case '=':
27.348 - return name.equals("=") || name.equals("==") || name.equals("===") || name.equals("=~");
27.349 - case '!':
27.350 - return name.equals("!=") || name.equals("!~");
27.351 - case '&':
27.352 - return name.equals("&") || name.equals("&&");
27.353 - case '|':
27.354 - return name.equals("|") || name.equals("||");
27.355 - case '[':
27.356 - return name.equals("[]") || name.equals("[]=");
27.357 - case '%':
27.358 - return name.equals("%");
27.359 - case '/':
27.360 - return name.equals("/");
27.361 - case '~':
27.362 - return name.equals("~");
27.363 - case '^':
27.364 - return name.equals("^");
27.365 - case '`':
27.366 - return name.equals("`");
27.367 - default:
27.368 - return false;
27.369 - }
27.370 - }
27.371 -
27.372 - public static boolean isValidPythonMethodName(String name) {
27.373 - if (isPythonKeyword(name)) {
27.374 - return false;
27.375 - }
27.376 -
27.377 - if (name.trim().length() == 0) {
27.378 - return false;
27.379 - }
27.380 -
27.381 - // TODO - allow operators
27.382 - if (isOperator(name)) {
27.383 - return true;
27.384 - }
27.385 -
27.386 - if (Character.isUpperCase(name.charAt(0)) || Character.isWhitespace(name.charAt(0))) {
27.387 - return false;
27.388 - }
27.389 -
27.390 - for (int i = 0; i < name.length(); i++) {
27.391 - char c = name.charAt(i);
27.392 - if (!(Character.isLetterOrDigit(c) || c == '_')) {
27.393 - return false;
27.394 - }
27.395 -
27.396 - }
27.397 -
27.398 - return true;
27.399 - }
27.400 -
27.401 - public static boolean isValidPythonIdentifier(String name) {
27.402 - if (isPythonKeyword(name)) {
27.403 - return false;
27.404 - }
27.405 -
27.406 - if (name.trim().length() == 0) {
27.407 - return false;
27.408 - }
27.409 -
27.410 - for (int i = 0; i < name.length(); i++) {
27.411 - // Identifier char isn't really accurate - I can have a function named "[]" etc.
27.412 - // so just look for -obvious- mistakes
27.413 - if (Character.isWhitespace(name.charAt(i))) {
27.414 - return false;
27.415 - }
27.416 -
27.417 - // TODO - make this more accurate, like the method validifier
27.418 - }
27.419 -
27.420 - return true;
27.421 - }
27.422 -
27.423 - /**
27.424 - * Ruby identifiers should consist of [a-zA-Z0-9_]
27.425 - * http://www.headius.com/rubyspec/index.php/Variables
27.426 - * <p>
27.427 - * This method also accepts the field/global chars
27.428 - * since it's unlikely
27.429 - */
27.430 - public static boolean isSafeIdentifierName(String name, int fromIndex) {
27.431 - int i = fromIndex;
27.432 - for (; i < name.length(); i++) {
27.433 - char c = name.charAt(i);
27.434 - if (!(c == '$' || c == '@' || c == ':')) {
27.435 - break;
27.436 - }
27.437 - }
27.438 - for (; i < name.length(); i++) {
27.439 - char c = name.charAt(i);
27.440 - if (!((c >= 'a' && c <= 'z') || (c == '_') ||
27.441 - (c >= 'A' && c <= 'Z') ||
27.442 - (c >= '0' && c <= '9') ||
27.443 - (c == '?') || (c == '=') || (c == '!'))) { // Method suffixes; only allowed on the last line
27.444 -
27.445 - if (isOperator(name)) {
27.446 - return true;
27.447 - }
27.448 -
27.449 - return false;
27.450 - }
27.451 - }
27.452 -
27.453 - return true;
27.454 - }
27.455 -
27.456 - /**
27.457 - * Return null if the given identifier name is valid, otherwise a localized
27.458 - * error message explaining the problem.
27.459 - */
27.460 - public static String getIdentifierWarning(String name, int fromIndex) {
27.461 - if (isSafeIdentifierName(name, fromIndex)) {
27.462 - return null;
27.463 - } else {
27.464 - return NbBundle.getMessage(PythonUtils.class, "UnsafeIdentifierName");
27.465 - }
27.466 - }
27.467 -
27.468 - /** @todo Move into GsfUtilities after 6.5 */
27.469 - public static int getOffsetByLineCol(String source, int line, int col) {
27.470 - int offset = 0;
27.471 - for (int i = 0; i < line; i++) {
27.472 - offset = source.indexOf('\n', offset);
27.473 - if (offset == -1) {
27.474 - offset = source.length();
27.475 - break;
27.476 - }
27.477 - offset++;
27.478 - }
27.479 - if (col > 0) { // -1: invalid
27.480 - offset += col;
27.481 - }
27.482 -
27.483 - return offset;
27.484 - }
27.485 - public static Comparator NAME_NODE_COMPARATOR = new Comparator<Name>() {
27.486 - @Override
27.487 - public int compare(Name n1, Name n2) {
27.488 - return n1.getInternalId().compareTo(n2.getInternalId());
27.489 - }
27.490 - };
27.491 - public static Comparator ATTRIBUTE_NAME_NODE_COMPARATOR = new Comparator<Object>() {
27.492 - @SuppressWarnings("unchecked")
27.493 - @Override
27.494 - public int compare(Object n1, Object n2) {
27.495 - String s1 = "";
27.496 - String s2 = "";
27.497 -
27.498 - if (n1 instanceof Name) {
27.499 - s1 = ((Name)n1).getInternalId();
27.500 - } else if (n1 instanceof Attribute) {
27.501 - Attribute a = (Attribute)n1;
27.502 - String v = PythonAstUtils.getName(a.getInternalValue());
27.503 - if (v != null) {
27.504 - s1 = a.getInternalAttr() + "." + v;
27.505 - } else {
27.506 - s1 = a.getInternalAttr();
27.507 - }
27.508 - }
27.509 -
27.510 - if (n2 instanceof Name) {
27.511 - s2 = ((Name)n2).getInternalId();
27.512 - } else if (n2 instanceof Attribute) {
27.513 - Attribute a = (Attribute)n2;
27.514 - String v = PythonAstUtils.getName(a.getInternalValue());
27.515 - if (v != null) {
27.516 - s2 = a.getInternalAttr() + "." + v;
27.517 - } else {
27.518 - s2 = a.getInternalAttr();
27.519 - }
27.520 - }
27.521 -
27.522 - return s1.compareTo(s2);
27.523 - }
27.524 - };
27.525 - public static Comparator NODE_POS_COMPARATOR = new Comparator<PythonTree>() {
27.526 - @Override
27.527 - public int compare(PythonTree p1, PythonTree p2) {
27.528 - int ret = p1.getCharStartIndex() - p2.getCharStartIndex();
27.529 - if (ret != 0) {
27.530 - return ret;
27.531 - }
27.532 - ret = p2.getCharStopIndex() - p1.getCharStopIndex();
27.533 - if (ret != 0) {
27.534 - return ret;
27.535 - }
27.536 - return p2.getAntlrType() - p1.getAntlrType();
27.537 - }
27.538 - };
27.539 -}
28.1 --- a/python.editor/src/org/netbeans/modules/python/editor/QuerySupportFactory.java Fri Sep 18 16:20:24 2015 -0500
28.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/QuerySupportFactory.java Mon Sep 21 13:01:16 2015 +0200
28.3 @@ -41,6 +41,7 @@
28.4 */
28.5 package org.netbeans.modules.python.editor;
28.6
28.7 +import org.netbeans.modules.python.source.PythonIndexer;
28.8 import java.io.IOException;
28.9 import java.util.Collection;
28.10 import java.util.Collections;
28.11 @@ -54,21 +55,5 @@
28.12 */
28.13 public class QuerySupportFactory {
28.14
28.15 - public static QuerySupport get(final Collection<FileObject> roots) {
28.16 - try {
28.17 - return QuerySupport.forRoots(PythonIndexer.NAME,
28.18 - PythonIndexer.VERSION,
28.19 - roots.toArray(new FileObject[roots.size()]));
28.20 - } catch (IOException ex) {
28.21 - Exceptions.printStackTrace(ex);
28.22 - }
28.23 - return null;
28.24 - }
28.25
28.26 - public static QuerySupport get(final FileObject source) {
28.27 - return get(QuerySupport.findRoots(source,
28.28 - null,
28.29 - null,
28.30 - Collections.<String>emptySet()));
28.31 - }
28.32 }
29.1 --- a/python.editor/src/org/netbeans/modules/python/editor/RstFormatter.java Fri Sep 18 16:20:24 2015 -0500
29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3 @@ -1,1342 +0,0 @@
29.4 -/*
29.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
29.6 - *
29.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
29.8 - *
29.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
29.10 - * Other names may be trademarks of their respective owners.
29.11 - *
29.12 - * The contents of this file are subject to the terms of either the GNU
29.13 - * General Public License Version 2 only ("GPL") or the Common
29.14 - * Development and Distribution License("CDDL") (collectively, the
29.15 - * "License"). You may not use this file except in compliance with the
29.16 - * License. You can obtain a copy of the License at
29.17 - * http://www.netbeans.org/cddl-gplv2.html
29.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
29.19 - * specific language governing permissions and limitations under the
29.20 - * License. When distributing the software, include this License Header
29.21 - * Notice in each file and include the License file at
29.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
29.23 - * particular file as subject to the "Classpath" exception as provided
29.24 - * by Oracle in the GPL Version 2 section of the License file that
29.25 - * accompanied this code. If applicable, add the following below the
29.26 - * License Header, with the fields enclosed by brackets [] replaced by
29.27 - * your own identifying information:
29.28 - * "Portions Copyrighted [year] [name of copyright owner]"
29.29 - *
29.30 - * If you wish your version of this file to be governed by only the CDDL
29.31 - * or only the GPL Version 2, indicate your decision by adding
29.32 - * "[Contributor] elects to include this software in this distribution
29.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
29.34 - * single choice of license, a recipient has the option to distribute
29.35 - * your version of this file under either the CDDL, the GPL Version 2 or
29.36 - * to extend the choice of license to its licensees as provided above.
29.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
29.38 - * Version 2 license, then the option applies only if the new code is
29.39 - * made subject to such option by the copyright holder.
29.40 - *
29.41 - * Contributor(s):
29.42 - *
29.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
29.44 - */
29.45 -package org.netbeans.modules.python.editor;
29.46 -
29.47 -import java.awt.Color;
29.48 -import java.io.CharConversionException;
29.49 -import java.util.ArrayList;
29.50 -import java.util.Collections;
29.51 -import java.util.List;
29.52 -import javax.swing.text.AttributeSet;
29.53 -import javax.swing.text.BadLocationException;
29.54 -import javax.swing.text.StyleConstants;
29.55 -import org.netbeans.api.editor.mimelookup.MimeLookup;
29.56 -import org.netbeans.api.editor.mimelookup.MimePath;
29.57 -import org.netbeans.api.editor.settings.FontColorSettings;
29.58 -import org.netbeans.api.lexer.Language;
29.59 -import org.netbeans.api.lexer.Token;
29.60 -import org.netbeans.api.lexer.TokenHierarchy;
29.61 -import org.netbeans.api.lexer.TokenSequence;
29.62 -import org.netbeans.editor.BaseDocument;
29.63 -import org.netbeans.modules.csl.api.ElementHandle;
29.64 -import org.netbeans.modules.csl.api.ElementKind;
29.65 -import org.netbeans.modules.csl.spi.GsfUtilities;
29.66 -import org.netbeans.modules.csl.spi.ParserResult;
29.67 -import org.netbeans.modules.python.api.PythonMIMEResolver;
29.68 -import org.netbeans.modules.python.editor.elements.Element;
29.69 -import org.netbeans.modules.python.editor.elements.IndexedElement;
29.70 -import org.netbeans.modules.python.editor.elements.IndexedMethod;
29.71 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
29.72 -import org.openide.filesystems.FileObject;
29.73 -import org.openide.util.Exceptions;
29.74 -import org.openide.util.Lookup;
29.75 -import org.openide.xml.XMLUtil;
29.76 -import org.python.antlr.PythonTree;
29.77 -
29.78 -/**
29.79 - * Support for reStructured text. Parse .rst files and rst content in
29.80 - * Python doc strings and format it as HTML. Also provide functions
29.81 - * to locate a code element in RST files.
29.82 - * @see http://www.python.org/dev/peps/pep-0287/
29.83 - * @see http://docutils.sourceforge.net/docs/user/rst/quickstart.html
29.84 - *
29.85 - * @todo Render verbatim blocks
29.86 - * @todo Syntax highlight verbatim blocks?
29.87 - * @todo Render *bold* and `identifier` stuff
29.88 - * @todo For class definitions which nest the method documentation,
29.89 - * try to remove all items, or perhaps just make it shorter
29.90 - * @todo Render note:: into something cleaner etc.
29.91 - *
29.92 - * @author Tor Norbye
29.93 - */
29.94 -public class RstFormatter {
29.95 - private static final String BRBR = "\n<br><br>\n"; // NOI18N
29.96 - private StringBuilder sb = new StringBuilder();
29.97 - private boolean lastWasEmpty = false;
29.98 - private int beginPos;
29.99 - private boolean inVerbatim;
29.100 - private boolean inIndex;
29.101 - private boolean inTable;
29.102 - private boolean inDiv;
29.103 - private int lastIndent;
29.104 - private boolean maybeVerbatim;
29.105 - private boolean inDocTest;
29.106 - private List<String> code;
29.107 -
29.108 - public RstFormatter() {
29.109 - }
29.110 -
29.111 - private void flush() {
29.112 - if (inTable) {
29.113 - sb.append("</pre>\n"); // NOI18N
29.114 - inTable = false;
29.115 - inVerbatim = false;
29.116 - } else if (inVerbatim) {
29.117 - // Process code and format as Python
29.118 - String html = getPythonHtml(code, true);
29.119 - if (html != null) {
29.120 - // <pre> tag is added as part of the rubyhtml (since it
29.121 - // needs to pick up the background color from the syntax
29.122 - // coloring settings)
29.123 - sb.append(html);
29.124 - } else {
29.125 - sb.append("<pre style=\"margin: 5px 5px; background: #ffffdd; border-size: 1px; padding: 5px\">"); // NOI18N
29.126 - sb.append("\n"); // NOI18N
29.127 - // Some kind of error; normal append
29.128 - for (String s : code) {
29.129 - appendEscaped(s);
29.130 - sb.append("<br>"); // NOI18N
29.131 - }
29.132 - sb.append("</pre>\n"); // NOI18N
29.133 - }
29.134 - inVerbatim = false;
29.135 - code = null;
29.136 - } else if (inDiv) {
29.137 - sb.append("</div>\n"); // NOI18N
29.138 - inDiv = false;
29.139 - }
29.140 - }
29.141 -
29.142 - private void appendEscaped(char c) {
29.143 - if ('<' == c) {
29.144 - sb.append("<"); // NOI18N
29.145 - } else if ('&' == c) {
29.146 - sb.append("&"); // NOI18N
29.147 - } else {
29.148 - sb.append(c);
29.149 - }
29.150 - }
29.151 -
29.152 - private void appendEscaped(CharSequence s) {
29.153 - for (int i = 0, n = s.length(); i < n; i++) {
29.154 - char c = s.charAt(i);
29.155 - if ('<' == c) {
29.156 - sb.append("<"); // NOI18N
29.157 - } else if ('&' == c) {
29.158 - sb.append("&"); // NOI18N
29.159 - } else {
29.160 - sb.append(c);
29.161 - }
29.162 - }
29.163 - }
29.164 -
29.165 - private int appendColonCmd(String line, int i, String marker, boolean url) throws CharConversionException {
29.166 - String MARKER = ":" + marker + ":`"; // NOI18N
29.167 - if (line.startsWith(MARKER, i)) {
29.168 - int end = line.indexOf("`", i + MARKER.length()); // NOI18N
29.169 - if (end != -1) {
29.170 - String token = line.substring(i + MARKER.length(), end);
29.171 - if (url) {
29.172 - sb.append("<a href=\""); // NOI18N
29.173 - if ("pep".equals(marker)) { // NOI18N
29.174 - sb.append("http://www.python.org/dev/peps/pep-"); // NOI18N
29.175 - for (int j = 0; j < 4 - token.length(); j++) {
29.176 - sb.append("0");
29.177 - }
29.178 - sb.append(token);
29.179 - sb.append("/"); // NOI18N
29.180 - sb.append("\">PEP "); // NOI18N
29.181 - sb.append(token);
29.182 - sb.append("</a>");
29.183 - return end;
29.184 - } else {
29.185 - sb.append(marker);
29.186 - sb.append(":"); // NOI18N
29.187 - appendEscaped(token);
29.188 - }
29.189 - sb.append("\">"); // NOI18N
29.190 - } else if (marker.equals("keyword")) { // NOI18N
29.191 - sb.append("<code style=\""); // NOI18N
29.192 -
29.193 - MimePath mimePath = MimePath.parse(PythonMIMEResolver.PYTHON_MIME_TYPE);
29.194 - Lookup lookup = MimeLookup.getLookup(mimePath);
29.195 - FontColorSettings fcs = lookup.lookup(FontColorSettings.class);
29.196 -
29.197 - AttributeSet attribs = fcs.getTokenFontColors("keyword"); // NOI18N
29.198 - Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
29.199 - if (fg != null) {
29.200 - sb.append("color:"); // NOI18N
29.201 - sb.append(getHtmlColor(fg));
29.202 - sb.append(";"); // NOI18N
29.203 - }
29.204 - Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
29.205 - // Only set the background for dark colors
29.206 - if (bg != null && bg.getRed() < 128) {
29.207 - sb.append("background:"); // NOI18N
29.208 - sb.append(getHtmlColor(bg));
29.209 - }
29.210 -
29.211 - sb.append("\">"); // NOI18N
29.212 - } else {
29.213 - sb.append("<code>"); // NOI18N
29.214 - }
29.215 - appendEscaped(token);
29.216 - if (url) {
29.217 - sb.append("</a>"); // NOI18N
29.218 - } else {
29.219 - sb.append("</code>"); // NOI18N
29.220 - }
29.221 - //return end+1; // instead of end+2: get to end of ``, minus loop increment
29.222 - return end; // instead of end+2: get to end of ``, minus loop increment
29.223 - }
29.224 - }
29.225 -
29.226 - return -1;
29.227 - }
29.228 -
29.229 - private void appendRstLine(String line) throws CharConversionException {
29.230 - int n = line.length();
29.231 - char prev = 0;
29.232 - Loop:
29.233 - for (int i = 0; i < n; i++) {
29.234 - char c = line.charAt(i);
29.235 - if (c == '`') {
29.236 - if (i < n - 2 && line.charAt(i + 1) == '`') {
29.237 - // See if it's an ``identifier``
29.238 - int end = line.indexOf("``", i + 2);
29.239 - if (end != -1) {
29.240 - sb.append("<code>"); // NOI18N
29.241 - appendEscaped(line.substring(i + 2, end));
29.242 - sb.append("</code>"); // NOI18N
29.243 - i = end + 1; // instead of end+2: get to end of ``, minus loop increment
29.244 - continue;
29.245 - }
29.246 - } else {
29.247 - // Single identifier
29.248 - for (int j = i + 1; j < n; j++) {
29.249 - char d = line.charAt(j);
29.250 - if (d == '`') {
29.251 - sb.append("<code>"); // NOI18N
29.252 - appendEscaped(line.substring(i + 1, j));
29.253 - sb.append("</code>"); // NOI18N
29.254 - i = j;
29.255 - continue Loop;
29.256 - } else if (!Character.isJavaIdentifierPart(d)) {
29.257 - break;
29.258 - }
29.259 - }
29.260 - }
29.261 - } else if (c == ':') {
29.262 - int nextI = appendColonCmd(line, i, "class", true); // NOI18N
29.263 - if (nextI == -1) {
29.264 - nextI = appendColonCmd(line, i, "exc", true); // NOI18N
29.265 - if (nextI == -1) {
29.266 - nextI = appendColonCmd(line, i, "var", false); // NOI18N
29.267 - if (nextI == -1) {
29.268 - nextI = appendColonCmd(line, i, "meth", true); // NOI18N
29.269 - if (nextI == -1) {
29.270 - nextI = appendColonCmd(line, i, "func", true); // NOI18N
29.271 - if (nextI == -1) {
29.272 - nextI = appendColonCmd(line, i, "data", false); // NOI18N
29.273 - if (nextI == -1) {
29.274 - nextI = appendColonCmd(line, i, "attr", false); // NOI18N
29.275 - if (nextI == -1) {
29.276 - nextI = appendColonCmd(line, i, "envvar", false); // NOI18N
29.277 - if (nextI == -1) {
29.278 - nextI = appendColonCmd(line, i, "mod", true); // NOI18N
29.279 - if (nextI == -1) {
29.280 - nextI = appendColonCmd(line, i, "pep", true); // NOI18N
29.281 - if (nextI == -1) {
29.282 - nextI = appendColonCmd(line, i, "ref", false); // NOI18N
29.283 - if (nextI == -1) {
29.284 - nextI = appendColonCmd(line, i, "mod", true); // NOI18N
29.285 - if (nextI == -1) {
29.286 - nextI = appendColonCmd(line, i, "keyword", false); // NOI18N
29.287 - if (nextI == -1) {
29.288 - if (line.startsWith(":noindex:", i)) { // NOI18N
29.289 - nextI = i + 9;
29.290 - } else if (line.startsWith(":synopsis:", i)) { // NOI18N
29.291 - nextI = i + 10;
29.292 - } else if (line.startsWith(":deprecated:", i)) {
29.293 - sb.append("Deprecated. ");
29.294 - nextI = i + 12;
29.295 - } else if (line.startsWith(":platform:", i)) {
29.296 - sb.append("Platform: ");
29.297 - nextI = i + 10;
29.298 - }
29.299 - }
29.300 - }
29.301 - }
29.302 - }
29.303 - }
29.304 - }
29.305 - }
29.306 - }
29.307 - }
29.308 - }
29.309 - }
29.310 - }
29.311 - }
29.312 - if (nextI != -1) {
29.313 - i = nextI;
29.314 - continue;
29.315 - }
29.316 - } else if (c == '*') {
29.317 - // Bold?
29.318 - if (i < n - 1 && Character.isJavaIdentifierPart(line.charAt(i + 1)) && !Character.isJavaIdentifierPart(prev)) { // TODO Use PythonUtils
29.319 - // Peek ahead to see if we have [not-identifier-char]*[identifierchars]*[not-identifier-chars]
29.320 - for (int j = i + 1; j < n; j++) {
29.321 - char d = line.charAt(j);
29.322 - if (d == '*') {
29.323 - if (j == n - 1 || !Character.isJavaIdentifierPart(line.charAt(j + 1))) {
29.324 - // Yess, make bold
29.325 - sb.append("<b>"); // NOI18N
29.326 - appendEscaped(line.substring(i + 1, j));
29.327 - sb.append("</b>"); // NOI18N
29.328 - i = j;
29.329 - continue Loop;
29.330 - }
29.331 - } else if (!Character.isJavaIdentifierPart(d)) {
29.332 - break;
29.333 - }
29.334 - }
29.335 - }
29.336 - } // TODO: :addedin, :deprecated, etc
29.337 -
29.338 - appendEscaped(c);
29.339 - prev = c;
29.340 - }
29.341 - }
29.342 -
29.343 - public void append(String line) {
29.344 - try {
29.345 - String trim = line.trim();
29.346 - if (trim.length() == 0) {
29.347 - inDocTest = false;
29.348 - if (inIndex) {
29.349 - // Completely swallow all indexing entries
29.350 - return;
29.351 - } else if (inTable) {
29.352 - sb.append("</pre>\n"); // NOI18N
29.353 - inVerbatim = false;
29.354 - inTable = false;
29.355 - } else if (inVerbatim) {
29.356 - sb.append("\n"); // NOI18N
29.357 - } else if (!lastWasEmpty && sb.length() > beginPos) {
29.358 - sb.append(BRBR); // NOI18N
29.359 - }
29.360 - lastWasEmpty = true;
29.361 - } else {
29.362 - if (!lastWasEmpty && trim.startsWith("- ")) { // NOI18N
29.363 - // lists - make sure they're on a new line
29.364 - sb.append("<br>"); // NOI18N
29.365 - }
29.366 -
29.367 - lastWasEmpty = false;
29.368 -
29.369 - if (maybeVerbatim) {
29.370 - int indent = getIndentation(line, 0);
29.371 - if (indent > lastIndent) {
29.372 - // Truncate last whitespace separator before <pre> if any
29.373 - if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
29.374 - sb.setLength(sb.length() - BRBR.length());
29.375 - }
29.376 - inVerbatim = true;
29.377 - code = new ArrayList<>();
29.378 - code.add(line);
29.379 - maybeVerbatim = false;
29.380 - return;
29.381 - }
29.382 - maybeVerbatim = false;
29.383 - } else if (inVerbatim || inTable) {
29.384 - int indent = getIndentation(line, 0);
29.385 - if (indent <= lastIndent) {
29.386 -//// // Truncate trailing whitespace
29.387 -//// while (sb.length() > 0 && sb.charAt(sb.length()-1) == '\n') {
29.388 -//// sb.setLength(sb.length()-1);
29.389 -//// }
29.390 -//// sb.append("</pre>"); // NOI18N
29.391 -// inVerbatim = false;
29.392 -// inTable = false;
29.393 - flush();
29.394 - lastWasEmpty = true;
29.395 - } else if (inVerbatim) {
29.396 - // We need to buffer up the text such that we can lex it as a unit
29.397 - // (and determine when done with the section if it's code or regular text)
29.398 - code.add(line);
29.399 - return;
29.400 - } else {
29.401 - appendEscaped(line);
29.402 - sb.append("\n"); // NOI18N
29.403 - return;
29.404 - }
29.405 - } else if (inDiv) {
29.406 - int indent = getIndentation(line, 0);
29.407 - if (indent <= lastIndent) {
29.408 - // Truncate last whitespace separator before <pre> if any
29.409 - if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
29.410 - sb.setLength(sb.length() - BRBR.length());
29.411 - }
29.412 - sb.append("</div>\n"); // NOI18N
29.413 - inDiv = false;
29.414 - lastWasEmpty = true;
29.415 - } else {
29.416 - appendRstLine(line);
29.417 - sb.append("\n"); // NOI18N
29.418 - return;
29.419 - }
29.420 - } else if (inIndex) {
29.421 - int indent = getIndentation(line, 0);
29.422 - if (indent <= lastIndent) {
29.423 - inIndex = false;
29.424 - lastWasEmpty = true;
29.425 - } else {
29.426 - return;
29.427 - }
29.428 -
29.429 - }
29.430 -
29.431 - if (trim.startsWith(".. method:: ")) { // NOI18N
29.432 - String sig = trim.substring(12).trim();
29.433 - sb.append("<a href=\"meth:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
29.434 - return;
29.435 - } else if (trim.startsWith(".. function:: ")) { // NOI18N
29.436 - String sig = trim.substring(14).trim();
29.437 - sb.append("<a href=\"func:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
29.438 - return;
29.439 - } else if (trim.startsWith(".. class:: ")) { // NOI18N
29.440 - String sig = trim.substring(11).trim();
29.441 - sb.append("<a href=\"class:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
29.442 - return;
29.443 - } else if (trim.startsWith(".. attribute:: ")) { // NOI18N
29.444 - String sig = trim.substring(15).trim();
29.445 - sb.append("<a href=\"attr:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
29.446 - return;
29.447 - } else if (trim.startsWith(".. data:: ")) { // NOI18N
29.448 - String sig = trim.substring(10).trim();
29.449 - sb.append("<a href=\"data:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
29.450 - return;
29.451 - } else if (trim.startsWith(".. module:: ")) { // NOI18N
29.452 - String sig = trim.substring(12).trim();
29.453 - sb.append("<a href=\"module:" + sig.replace("\"", """) + "\">" + sig + "</a>"); // NOI18N
29.454 - sb.append("<br>\n");
29.455 - return;
29.456 - } else if (trim.startsWith(".. productionlist:")) {
29.457 - lastIndent = getIndentation(line, 0);
29.458 - inVerbatim = true;
29.459 - code = new ArrayList<>();
29.460 - code.add(line);
29.461 - maybeVerbatim = false;
29.462 - return;
29.463 - }
29.464 -
29.465 - if (trim.startsWith(">>>") || inDocTest) { // NOI18N
29.466 - if (!trim.startsWith(">>>")) { // NOI18N
29.467 - sb.append("<code>"); // NOI18N
29.468 - appendEscaped(line); // NOI18N
29.469 - // Wait until there is an empty line before we mark doctest done!
29.470 - // inDocTest = false;
29.471 - sb.append("</code><br>"); // NOI18N
29.472 - } else {
29.473 - sb.append("<code>"); // NOI18N
29.474 - appendEscaped(">>>"); // NOI18N
29.475 - String html = getPythonHtml(Collections.singletonList(trim.substring(3)), false);
29.476 - sb.append(html);
29.477 - sb.append("</code>"); // NOI18N
29.478 - inDocTest = true;
29.479 - }
29.480 - return;
29.481 - }
29.482 - inDocTest = false;
29.483 -
29.484 - if (trim.startsWith(".. note::") || trim.startsWith(".. warning::") || trim.startsWith(".. seealso:")) { // NOI18N
29.485 - // Truncate last whitespace separator before <pre> if any
29.486 - if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
29.487 - sb.setLength(sb.length() - BRBR.length());
29.488 - }
29.489 - sb.append("<div style=\"margin: 5px 5px; "); // NOI18N
29.490 - if (!trim.contains("seealso")) { // NOI18N
29.491 - sb.append("background: #ffdddd; "); // NOI18N
29.492 - } else {
29.493 - sb.append("background: #ddffdd; "); // NOI18N
29.494 - }
29.495 - sb.append("border-size: 1px; padding: 5px\">"); // NOI18N
29.496 - if (trim.contains("note:")) {
29.497 - sb.append("<b>NOTE</b>: "); // NOI18N
29.498 - } else if (trim.contains("warning")) {
29.499 - sb.append("<b>WARNING</b>: "); // NOI18N
29.500 - } else {
29.501 - sb.append("<b>See Also</b>: "); // NOI18N
29.502 - }
29.503 - sb.append("\n"); // NOI18N
29.504 - inDiv = true;
29.505 - lastIndent = getIndentation(line, 0);
29.506 - maybeVerbatim = false;
29.507 - return;
29.508 - } else if (trim.startsWith(".. versionadded::") || trim.startsWith(".. versionchanged::") || trim.startsWith(".. deprecated::")) { // NOI18N
29.509 - // Truncate last whitespace separator before <pre> if any
29.510 - if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
29.511 - sb.setLength(sb.length() - BRBR.length());
29.512 - }
29.513 - sb.append("<div style=\"margin: 5px 5px; background: #dddddd; border-size: 1px; padding: 5px\">"); // NOI18N
29.514 - if (trim.contains("added:")) {
29.515 - sb.append("<b>Version Added</b>: "); // NOI18N
29.516 - } else if (trim.contains("changed")) {
29.517 - sb.append("<b>Version Changed</b>: "); // NOI18N
29.518 - } else {
29.519 - assert trim.contains("deprecated"); // NOI18N
29.520 - sb.append("<b>Deprecated</b>: "); // NOI18N
29.521 - }
29.522 - sb.append(trim.substring(trim.indexOf("::") + 2));
29.523 - sb.append("\n"); // NOI18N
29.524 - inDiv = true;
29.525 - lastIndent = getIndentation(line, 0);
29.526 - maybeVerbatim = false;
29.527 - return;
29.528 - } else if (trim.startsWith(".. index:")) { // NOI18N
29.529 - inIndex = true;
29.530 - lastIndent = getIndentation(line, 0);
29.531 - return;
29.532 - } else if (trim.startsWith(".. _") && trim.endsWith(":")) {
29.533 - // skip lines like .. _pyzipfile-objects:
29.534 - return;
29.535 - } else if (trim.startsWith(".. moduleauthor::") || trim.startsWith(".. sectionauthor::")) { // NOI18N
29.536 - if (trim.startsWith(".. mod")) {
29.537 - sb.append("<br>Module Author:</b>");
29.538 - } else {
29.539 - sb.append("<br>Section Author:</b>");
29.540 - }
29.541 - appendEscaped(trim.substring(trim.indexOf("::") + 2)); //
29.542 - sb.append("\n");
29.543 - return;
29.544 - } else if (trim.endsWith("::")) { // NOI18N
29.545 - maybeVerbatim = true;
29.546 - lastIndent = getIndentation(line, 0);
29.547 - } else if (trim.startsWith("+-----")) { // NOI18N
29.548 - // A table
29.549 - sb.append("<pre>"); // NOI18N
29.550 - appendEscaped(line);
29.551 - sb.append("\n"); // NOI18N
29.552 - inTable = true;
29.553 - lastIndent = getIndentation(line, 0) - 1;
29.554 - return;
29.555 - } else if (line.startsWith("======") || line.startsWith("------") || line.startsWith("******") || line.startsWith("^^^^^^^^")) { // NOI18N
29.556 - // PREVIOUS line could be a title.
29.557 - // Note -- we're comparing on "line" and not "trim" here because in indented contexts,
29.558 - // === sometimes represents parts of tables -- see the turtle.rst file for examples.
29.559 -
29.560 - int n = sb.length();
29.561 - if (n > 0 && sb.charAt(n - 1) == '\n') {
29.562 - n--;
29.563 - }
29.564 - int index = n - 1;
29.565 - for (; index >= 0; index--) {
29.566 - char c = sb.charAt(index);
29.567 - if (c == '\n') {
29.568 - index++;
29.569 - break;
29.570 - }
29.571 - }
29.572 - if (index == -1) {
29.573 - index = 0;
29.574 - }
29.575 - // Index now points to the beginning of the previous line
29.576 - boolean empty = true;
29.577 -// boolean okay = true;
29.578 - int start = index;
29.579 - for (; index < n; index++) {
29.580 - char c = sb.charAt(index);
29.581 - if (c == '\n') {
29.582 - break;
29.583 - }
29.584 - empty = false;
29.585 -// if (c == '<') {
29.586 -// okay = false;
29.587 -// }
29.588 - }
29.589 - if (!empty/* && okay*/) {
29.590 - String tag = "h2"; // NOI18N
29.591 - if (line.startsWith("-") || line.startsWith("^")) { // NOI18N
29.592 - tag = "h3"; // NOI18N
29.593 - }
29.594 - sb.insert(start, "<" + tag + ">"); // NOI18N
29.595 - sb.append("</" + tag + ">\n"); // NOI18N
29.596 - lastWasEmpty = true;
29.597 - return;
29.598 - }
29.599 - }
29.600 -
29.601 - //sb.append(line);
29.602 - appendRstLine(line);
29.603 -
29.604 - sb.append("\n"); // NOI18N
29.605 - }
29.606 - } catch (CharConversionException ex) {
29.607 - Exceptions.printStackTrace(ex);
29.608 - }
29.609 - }
29.610 -
29.611 - public void appendSignature(Element element) {
29.612 - sb.append("<pre>"); // NOI18N
29.613 -
29.614 - if (element instanceof IndexedMethod) {
29.615 - IndexedMethod executable = (IndexedMethod)element;
29.616 - if (element.getIn() != null && !PythonIndex.isBuiltinModule(element.getIn())) {
29.617 - String in = element.getIn();
29.618 - sb.append("<i>"); // NOI18N
29.619 - sb.append(in);
29.620 - sb.append("</i>"); // NOI18N
29.621 - sb.append("<br>"); // NOI18N
29.622 - }
29.623 - // TODO - share this between Navigator implementation and here...
29.624 - sb.append("<b>"); // NOI18N
29.625 - sb.append(element.getName());
29.626 - sb.append("</b>"); // NOI18N
29.627 - String[] parameters = executable.getParams();
29.628 -
29.629 - if ((parameters != null) && (parameters.length > 0)) {
29.630 - sb.append("("); // NOI18N
29.631 -
29.632 - sb.append("<font color=\"#808080\">"); // NOI18N
29.633 -
29.634 - boolean first = true;
29.635 - for (String parameter : parameters) {
29.636 - if (first) {
29.637 - first = false;
29.638 - } else {
29.639 - sb.append(", ");
29.640 - }
29.641 - sb.append(parameter);
29.642 - }
29.643 -
29.644 - sb.append("</font>"); // NOI18N
29.645 -
29.646 - sb.append(")"); // NOI18N
29.647 - }
29.648 - } else if (element instanceof IndexedElement) {
29.649 - //IndexedElement clz = (IndexedElement)element;
29.650 - String name = element.getName();
29.651 -// final String fqn = clz.getFqn();
29.652 -// if (fqn != null && !name.equals(fqn)) {
29.653 -// signature.append("<i>"); // NOI18N
29.654 -// signature.append(fqn); // NOI18N
29.655 -// signature.append("</i>"); // NOI18N
29.656 -// signature.append("<br>"); // NOI18N
29.657 -// }
29.658 - sb.append("<b>"); // NOI18N
29.659 - sb.append(name);
29.660 - sb.append("</b>"); // NOI18N
29.661 - } else {
29.662 - sb.append(element.getName());
29.663 - }
29.664 -
29.665 - sb.append("</pre>\n"); // NOI18N
29.666 - }
29.667 -
29.668 - public void appendHtml(String html) {
29.669 - sb.append(html);
29.670 - }
29.671 -
29.672 - public void markEmpty() {
29.673 - beginPos = sb.length();
29.674 - }
29.675 -
29.676 - public String toHtml() {
29.677 - flush();
29.678 - return sb.toString();
29.679 - }
29.680 -
29.681 - public static String document(String rst) {
29.682 - RstFormatter formatter = new RstFormatter();
29.683 - String[] lines = rst.split("\n"); // NOI18N
29.684 - for (String line : lines) {
29.685 - formatter.append(line);
29.686 - }
29.687 - return formatter.toHtml();
29.688 - }
29.689 -
29.690 - public static String getDocumentation(IndexedElement indexedElement) {
29.691 - RstFormatter formatter = new RstFormatter();
29.692 - FileObject fileObject = indexedElement.getFileObject();
29.693 - if (fileObject == null) {
29.694 - return null;
29.695 - }
29.696 - BaseDocument document = GsfUtilities.getDocument(fileObject, true);
29.697 - if (document == null) {
29.698 - return null;
29.699 - }
29.700 -
29.701 - String[] signatureHolder = new String[1];
29.702 - String rst = formatter.extractRst(indexedElement, document, signatureHolder);
29.703 - if (rst != null && rst.length() > 0) {
29.704 - String signature = signatureHolder[0];
29.705 - if (signature == null) {
29.706 - formatter.appendSignature(indexedElement);
29.707 - formatter.appendHtml("\n<hr>\n"); // NOI18N
29.708 - formatter.markEmpty();
29.709 - } else {
29.710 - formatter.appendHtml("<pre>"); // NOI18N
29.711 - formatter.appendHtml("<b>"); // NOI18N
29.712 - int paren = signature.indexOf('(');
29.713 - if (paren != -1) {
29.714 - formatter.appendHtml(signature.substring(0, paren));
29.715 - formatter.appendHtml("</b>"); // NOI18N
29.716 - formatter.appendHtml("<font color=\"#808080\">"); // NOI18N
29.717 - formatter.appendHtml(signature.substring(paren));
29.718 - formatter.appendHtml("</font>"); // NOI18N
29.719 - } else {
29.720 - formatter.appendHtml(signature);
29.721 - formatter.appendHtml("()"); // NOI18N
29.722 - formatter.appendHtml("</b>"); // NOI18N
29.723 - }
29.724 - formatter.appendHtml("</pre>"); // NOI18N
29.725 - formatter.appendHtml("\n<hr>\n"); // NOI18N
29.726 - formatter.markEmpty();
29.727 - }
29.728 -
29.729 - String[] lines = rst.split("\n"); // NOI18N
29.730 - for (String line : lines) {
29.731 - formatter.append(line);
29.732 - }
29.733 - return formatter.toHtml();
29.734 - }
29.735 -
29.736 - return null;
29.737 - }
29.738 -
29.739 - /**
29.740 - * Find the reStructured text for the documentation for the given element
29.741 - * in the given RST document
29.742 - * @param indexedElement
29.743 - * @param document
29.744 - * @return
29.745 - */
29.746 - private String extractRst(IndexedElement element, BaseDocument doc, String[] signatureHolder) {
29.747 - return extractRst(element.getName(), element.getClz(), element.getKind(), doc, signatureHolder);
29.748 - }
29.749 -
29.750 - String extractRst(String name, String clz, ElementKind kind, BaseDocument doc, String[] signatureHolder) {
29.751 - try {
29.752 - String text = doc.getText(0, doc.getLength());
29.753 - // What about functions?
29.754 - if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
29.755 - int offset = findElementMatch(text, "function::", name, true); // NOI18N
29.756 - if (offset == -1) {
29.757 - offset = findElementMatch(text, "method::", name, false); // NOI18N
29.758 - if (offset == -1 && kind == ElementKind.CONSTRUCTOR) {
29.759 - offset = findElementMatch(text, "class::", name, false); // NOI18N
29.760 - if (offset == -1 && clz != null && clz.length() > 0 && "__init__".equals(name)) { // NOI18N
29.761 - offset = findElementMatch(text, "method::", clz, false); // NOI18N
29.762 - if (offset == -1) {
29.763 - offset = findElementMatch(text, "class::", clz, false); // NOI18N
29.764 - }
29.765 - }
29.766 - }
29.767 - }
29.768 - if (offset != -1) {
29.769 - int end = findElementEnd(text, offset);
29.770 - int nextLine = getNextLineOffset(text, offset);
29.771 - if (nextLine < end) {
29.772 - if (signatureHolder != null) {
29.773 - String signature = text.substring(text.indexOf("::", offset) + 2, nextLine).trim(); // NOI18N
29.774 - signatureHolder[0] = signature;
29.775 - }
29.776 - return text.substring(nextLine, end);
29.777 - }
29.778 - }
29.779 - } else if (kind == ElementKind.CLASS) {
29.780 - int offset = findElementMatch(text, "class::", name, false); // NOI18N
29.781 - if (offset == -1) {
29.782 - offset = findElementMatch(text, "exception::", name, false); // NOI18N
29.783 - }
29.784 - if (offset != -1) {
29.785 - int end = findElementEnd(text, offset);
29.786 - int nextLine = getNextLineOffset(text, offset);
29.787 - if (nextLine < end) {
29.788 - String elementText = text.substring(nextLine, end);
29.789 - return elementText;
29.790 - }
29.791 - }
29.792 - } else if (kind == ElementKind.MODULE) {
29.793 - int offset = findElementMatch(text, "module::", name, false); // NOI18N
29.794 - if (offset == -1) {
29.795 - offset = findElementMatch(text, "currentmodule::", name, false); // NOI18N
29.796 - }
29.797 - if (offset != -1) {
29.798 - int end = findElementEnd(text, offset);
29.799 - int nextLine = getNextLineOffset(text, offset);
29.800 - if (nextLine < end) {
29.801 - String elementText = text.substring(nextLine, end);
29.802 - return elementText;
29.803 - }
29.804 - }
29.805 - } else {
29.806 -// assert kind == ElementKind.ATTRIBUTE :;
29.807 - int offset = findElementMatch(text, "data::", name, true); // NOI18N
29.808 - if (offset == -1) {
29.809 - offset = findElementMatch(text, "attribute::", name, false); // NOI18N
29.810 - }
29.811 - if (offset != -1) {
29.812 - int end = findElementEnd(text, offset);
29.813 - int nextLine = getNextLineOffset(text, offset);
29.814 - if (nextLine < end) {
29.815 - String elementText = text.substring(nextLine, end);
29.816 - return elementText;
29.817 - }
29.818 - }
29.819 - }
29.820 - } catch (BadLocationException ex) {
29.821 - Exceptions.printStackTrace(ex);
29.822 - return "";
29.823 - }
29.824 -
29.825 -// while (true) {
29.826 -// try {
29.827 -// int ret = doc.find(new FinderFactory.StringFwdFinder(".. " + key + "::", true), offset, -1);
29.828 -// if (ret == -1) {
29.829 -// break;
29.830 -// }
29.831 -// } catch (BadLocationException ex) {
29.832 -// Exceptions.printStackTrace(ex);
29.833 -// }
29.834 -// }
29.835 -
29.836 -
29.837 - return "";
29.838 - }
29.839 -
29.840 - public static int getIndentation(String text, int lineBegin) {
29.841 - for (int i = lineBegin; i < text.length(); i++) {
29.842 - char c = text.charAt(i);
29.843 - if (c == '\n') {
29.844 - // Empty lines don't count
29.845 - return -1;
29.846 - }
29.847 - if (!Character.isWhitespace(c)) {
29.848 - // Doesn't quite work for tabs etc. but those aren't
29.849 - // really used in rst files... Fix when I switch to
29.850 - // direct document iteration
29.851 - return i - lineBegin;
29.852 - }
29.853 - }
29.854 -
29.855 - return -1;
29.856 - }
29.857 -
29.858 - public static int getNextLineOffset(String text, int offset) {
29.859 - int index = text.indexOf('\n', offset);
29.860 - if (index == -1) {
29.861 - return -1;
29.862 - } else {
29.863 - return index + 1;
29.864 - }
29.865 - }
29.866 -
29.867 - public static int findElementEnd(String text, int offset) {
29.868 - // Find beginning of line
29.869 - int lineBegin = 0;
29.870 - for (int i = offset; i > 0; i--) {
29.871 - char c = text.charAt(i);
29.872 - if (c == '\n') {
29.873 - lineBegin = i + 1;
29.874 - break;
29.875 - }
29.876 - }
29.877 -
29.878 - // Compute indentation of the ..
29.879 - int firstIndent = getIndentation(text, lineBegin);
29.880 - offset = getNextLineOffset(text, lineBegin);
29.881 - while (true) {
29.882 - offset = getNextLineOffset(text, offset);
29.883 - if (offset == -1) {
29.884 - return text.length();
29.885 - }
29.886 - int indent = getIndentation(text, offset);
29.887 - if (indent == -1) {
29.888 - // Empty line - doesn't count
29.889 - continue;
29.890 - } else if (indent <= firstIndent) {
29.891 - return offset;
29.892 - }
29.893 - }
29.894 - }
29.895 -
29.896 - public static int findElementMatch(String text, String key, String name, boolean checkAdjacentLines) {
29.897 - int nameLength = name.length();
29.898 - int offset = 0;
29.899 - int keyLength = key.length();
29.900 - while (true) {
29.901 - int next = text.indexOf(key, offset);
29.902 - if (next == -1) {
29.903 - break;
29.904 - }
29.905 - offset = next + keyLength;
29.906 -
29.907 - int lineEnd = text.indexOf('\n', offset);
29.908 - if (lineEnd == -1) {
29.909 - lineEnd = text.length(); // on last line with no crlf at the end
29.910 - }
29.911 -
29.912 - // Skip whitespace
29.913 - for (; offset < lineEnd; offset++) {
29.914 - char c = text.charAt(offset);
29.915 - if (c != ' ') {
29.916 - break;
29.917 - }
29.918 - }
29.919 -
29.920 - int nameBegin = offset;
29.921 - int nameEnd = -1;
29.922 -
29.923 - // Pick out the bame
29.924 - for (int i = offset; i < lineEnd; i++) {
29.925 - char c = text.charAt(i);
29.926 - if (c == '(' || c == ' ') {
29.927 - nameEnd = i;
29.928 - break;
29.929 - } else if (c == '.') {
29.930 - nameBegin = i + 1;
29.931 - }
29.932 - }
29.933 - if (nameEnd == -1) {
29.934 - nameEnd = lineEnd;
29.935 - }
29.936 -
29.937 -
29.938 - if (nameEnd - nameBegin == nameLength &&
29.939 - text.regionMatches(nameBegin, name, 0, nameLength)) {
29.940 - // TODO - validate the arguments list?
29.941 - return next;
29.942 - }
29.943 -
29.944 - // Look on subsequent lines too - we sometimes have adjacent lines
29.945 - // with additional signatures
29.946 - if (checkAdjacentLines) {
29.947 - while (true) {
29.948 - int lineBegin = lineEnd+1;
29.949 - if (lineBegin >= text.length()) {
29.950 - break;
29.951 - }
29.952 -
29.953 - lineEnd = text.indexOf('\n', lineBegin);
29.954 - if (lineEnd == -1) {
29.955 - lineEnd = text.length(); // on last line with no crlf at the end
29.956 - }
29.957 -
29.958 - while (lineBegin < lineEnd) {
29.959 - char c = text.charAt(lineBegin);
29.960 - if (!Character.isWhitespace(c)) {
29.961 - break;
29.962 - }
29.963 - lineBegin++;
29.964 - }
29.965 -
29.966 - while (lineEnd > lineBegin) {
29.967 - char c = text.charAt(lineEnd-1);
29.968 - if (!Character.isWhitespace(c)) {
29.969 - break;
29.970 - }
29.971 - lineEnd--;
29.972 - }
29.973 -
29.974 - if (lineEnd <= lineBegin) {
29.975 - break;
29.976 - }
29.977 -
29.978 - nameBegin = lineBegin;
29.979 - nameEnd = -1;
29.980 -
29.981 - // Pick out the name
29.982 - for (int i = lineBegin; i < lineEnd; i++) {
29.983 - char c = text.charAt(i);
29.984 - if (c == '(' || c == ' ') {
29.985 - nameEnd = i;
29.986 - break;
29.987 - } else if (c == '.') {
29.988 - nameBegin = i + 1;
29.989 - }
29.990 - }
29.991 - if (nameEnd == -1) {
29.992 - nameEnd = lineEnd;
29.993 - }
29.994 -
29.995 - if (nameEnd - nameBegin == nameLength &&
29.996 - text.regionMatches(nameBegin, name, 0, nameLength)) {
29.997 - // TODO - validate the arguments list?
29.998 - return next;
29.999 - }
29.1000 - }
29.1001 - }
29.1002 -
29.1003 - }
29.1004 -
29.1005 - return -1;
29.1006 - }
29.1007 -
29.1008 - public static String document(ParserResult info, ElementHandle element) {
29.1009 - if (element instanceof IndexedElement) {
29.1010 - IndexedElement indexedElement = (IndexedElement)element;
29.1011 -
29.1012 - FileObject fo = indexedElement.getFileObject();
29.1013 -
29.1014 - if (fo == null) {
29.1015 - return null;
29.1016 - }
29.1017 -
29.1018 - if (PythonUtils.isRstFile(fo)) {
29.1019 - return getDocumentation(indexedElement);
29.1020 - }
29.1021 -
29.1022 -
29.1023 - PythonTree node = indexedElement.getNode();
29.1024 - if (node != null) {
29.1025 - return document(info, node, indexedElement);
29.1026 - }
29.1027 - }
29.1028 - return null;
29.1029 - }
29.1030 -
29.1031 - public static String document(ParserResult info, PythonTree node, IndexedElement element) {
29.1032 - if (node != null) {
29.1033 - String doc = PythonAstUtils.getDocumentation(node);
29.1034 - if (doc != null) {
29.1035 - // Honor empty lines: paragraphs
29.1036 - RstFormatter formatter = new RstFormatter();
29.1037 - if (element != null) {
29.1038 - formatter.appendSignature(element);
29.1039 - }
29.1040 - if (doc.indexOf('\n') != -1) {
29.1041 - formatter.appendHtml("\n<hr>\n"); // NOI18N
29.1042 - formatter.markEmpty();
29.1043 - String[] lines = doc.split("\n"); // NOI18N
29.1044 - for (String line : lines) {
29.1045 - formatter.append(line);
29.1046 - }
29.1047 - } else if (doc.length() > 0) {
29.1048 - formatter.appendHtml("\n<hr>\n"); // NOI18N
29.1049 - formatter.markEmpty();
29.1050 - formatter.append(doc);
29.1051 - }
29.1052 -
29.1053 - return formatter.toHtml();
29.1054 - }
29.1055 - }
29.1056 -
29.1057 - return null;
29.1058 - }
29.1059 -
29.1060 - public static String getSignature(Element element) {
29.1061 - StringBuilder signature = new StringBuilder();
29.1062 - // TODO:
29.1063 - signature.append("<pre>"); // NOI18N
29.1064 -
29.1065 - if (element instanceof IndexedMethod) {
29.1066 - IndexedMethod executable = (IndexedMethod)element;
29.1067 - if (element.getIn() != null) {
29.1068 - String in = element.getIn();
29.1069 - signature.append("<i>"); // NOI18N
29.1070 - signature.append(in);
29.1071 - signature.append("</i>"); // NOI18N
29.1072 - signature.append("<br>"); // NOI18N
29.1073 - }
29.1074 - // TODO - share this between Navigator implementation and here...
29.1075 - signature.append("<b>"); // NOI18N
29.1076 - signature.append(element.getName());
29.1077 - signature.append("</b>"); // NOI18N
29.1078 - String[] parameters = executable.getParams();
29.1079 -
29.1080 - if ((parameters != null) && (parameters.length > 0)) {
29.1081 - signature.append("("); // NOI18N
29.1082 -
29.1083 - signature.append("<font color=\"#808080\">"); // NOI18N
29.1084 -
29.1085 - boolean first = true;
29.1086 - for (String parameter : parameters) {
29.1087 - if (first) {
29.1088 - first = false;
29.1089 - } else {
29.1090 - signature.append(", "); // NOI18N
29.1091 - }
29.1092 - signature.append(parameter);
29.1093 - }
29.1094 -
29.1095 - signature.append("</font>"); // NOI18N
29.1096 -
29.1097 - signature.append(")"); // NOI18N
29.1098 - }
29.1099 - } else if (element instanceof IndexedElement) {
29.1100 -// IndexedElement clz = (IndexedElement)element;
29.1101 - String name = element.getName();
29.1102 -// final String fqn = clz.getFqn();
29.1103 -// if (fqn != null && !name.equals(fqn)) {
29.1104 -// signature.append("<i>"); // NOI18N
29.1105 -// signature.append(fqn); // NOI18N
29.1106 -// signature.append("</i>"); // NOI18N
29.1107 -// signature.append("<br>"); // NOI18N
29.1108 -// }
29.1109 - signature.append("<b>"); // NOI18N
29.1110 - signature.append(name);
29.1111 - signature.append("</b>"); // NOI18N
29.1112 - } else {
29.1113 - signature.append(element.getName());
29.1114 - }
29.1115 -
29.1116 - signature.append("</pre>\n"); // NOI18N
29.1117 -
29.1118 - return signature.toString();
29.1119 - }
29.1120 -
29.1121 - @SuppressWarnings("unchecked")
29.1122 - private String getPythonHtml(List<String> source, boolean addPre) {
29.1123 - StringBuilder python = new StringBuilder(500);
29.1124 -
29.1125 - for (String s : source) {
29.1126 - python.append(s);
29.1127 - python.append("\n"); // NOI18N
29.1128 - }
29.1129 -
29.1130 - Language<?> language = PythonTokenId.language();
29.1131 - String mimeType = PythonMIMEResolver.PYTHON_MIME_TYPE;
29.1132 - // TODO - handle YAML and other languages I can see in the documentation...
29.1133 - /*if (python.indexOf(" <%") != -1) { // NOI18N
29.1134 - mimeType = "application/x-httpd-eruby"; // RHTML
29.1135 - Collection<LanguageProvider> providers = (Collection<LanguageProvider>) Lookup.getDefault().lookupAll(LanguageProvider.class);
29.1136 - for (LanguageProvider provider : providers) {
29.1137 - language = provider.findLanguage(mimeType);
29.1138 - if (language != null) {
29.1139 - break;
29.1140 - }
29.1141 - }
29.1142 -
29.1143 - if (language == null) {
29.1144 - mimeType = PythonTokenId.PYTHON_MIME_TYPE;
29.1145 - language = PythonTokenId.language();
29.1146 - }
29.1147 - } else*/ if (source.get(0).trim().startsWith("<")) {
29.1148 - // Looks like markup (other than RHTML) - don't colorize it
29.1149 - // since we don't know how
29.1150 - return null;
29.1151 - }
29.1152 -
29.1153 - StringBuilder buffer = new StringBuilder(1500);
29.1154 -
29.1155 - boolean errors = appendSequence(buffer, python.toString(), language, mimeType, addPre);
29.1156 - return errors ? null : buffer.toString();
29.1157 - }
29.1158 -
29.1159 - @SuppressWarnings("unchecked")
29.1160 - private boolean appendSequence(StringBuilder sb, String text,
29.1161 - Language<?> language, String mimeType, boolean addPre) {
29.1162 - // XXX is this getting called twice?
29.1163 - MimePath mimePath = MimePath.parse(mimeType);
29.1164 - Lookup lookup = MimeLookup.getLookup(mimePath);
29.1165 - FontColorSettings fcs = lookup.lookup(FontColorSettings.class);
29.1166 -
29.1167 - if (addPre) {
29.1168 - sb.append("<pre style=\""); // NOI18N
29.1169 -
29.1170 - sb.append("border-color: #dddddd; border-style: solid; border-width: 1px; ");
29.1171 -
29.1172 - AttributeSet attribs = fcs.getTokenFontColors("default"); // NOI18N
29.1173 - Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
29.1174 - if (fg != null) {
29.1175 - sb.append("color:"); // NOI18N
29.1176 - sb.append(getHtmlColor(fg));
29.1177 - sb.append(";"); // NOI18N
29.1178 - }
29.1179 - Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
29.1180 - // Only set the background for dark colors
29.1181 - if (bg != null && bg.getRed() < 128) {
29.1182 - sb.append("background:"); // NOI18N
29.1183 - sb.append(getHtmlColor(bg));
29.1184 - }
29.1185 -
29.1186 - sb.append("\">\n"); // NOI18N
29.1187 - }
29.1188 - TokenHierarchy hi = TokenHierarchy.create(text, language);
29.1189 - TokenSequence ts = hi.tokenSequence();
29.1190 -
29.1191 - int offset = 0;
29.1192 - ts.move(offset);
29.1193 -
29.1194 - if (ts.moveNext()) {
29.1195 - do {
29.1196 - Token t = ts.token();
29.1197 - String tokenText = t.text().toString();
29.1198 -
29.1199 - // TODO - make style classes instead of inlining everything as font!
29.1200 - String category = t.id().name();
29.1201 - String primaryCategory = t.id().primaryCategory();
29.1202 -
29.1203 - if ("error".equals(primaryCategory)) { // NOI18N
29.1204 - // Abort: an error token means the output probably isn't
29.1205 - // code, or it's code or markup but in a different language
29.1206 - // than we're trying to process it as
29.1207 - return true;
29.1208 - }
29.1209 -
29.1210 - AttributeSet attribs = fcs.getTokenFontColors(category);
29.1211 - String escapedText = tokenText;
29.1212 - try {
29.1213 - escapedText = XMLUtil.toElementContent(tokenText);
29.1214 - } catch (CharConversionException cce) {
29.1215 - Exceptions.printStackTrace(cce);
29.1216 - }
29.1217 -
29.1218 - if (attribs == null) {
29.1219 - category = primaryCategory;
29.1220 - attribs = fcs.getTokenFontColors(category);
29.1221 -
29.1222 - }
29.1223 -
29.1224 - TokenSequence embedded = ts.embedded();
29.1225 - if (embedded != null) {
29.1226 - //embedded.languagePath().mimePath();
29.1227 - String embeddedMimeType = MimePath.parse(embedded.languagePath().mimePath()).getPath();
29.1228 - Color bg = null;
29.1229 - Color fg = null;
29.1230 - if (attribs != null) {
29.1231 - bg = (Color)attribs.getAttribute(StyleConstants.Background);
29.1232 - fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
29.1233 - if (fg != null || bg != null) {
29.1234 - sb.append("<span style=\"");
29.1235 - if (bg != null) {
29.1236 - sb.append("background:"); // NOI18N
29.1237 - sb.append(getHtmlColor(bg));
29.1238 - sb.append(";");
29.1239 - }
29.1240 - if (fg != null) {
29.1241 - sb.append("color:"); // NOI18N
29.1242 - sb.append(getHtmlColor(fg));
29.1243 - }
29.1244 - sb.append("\">"); // NOI18N
29.1245 - }
29.1246 - }
29.1247 - appendSequence(sb, tokenText, embedded.language(), embeddedMimeType, false);
29.1248 - if (fg != null || bg != null) {
29.1249 - sb.append("</span>"); // NOI18N
29.1250 - }
29.1251 - continue;
29.1252 - }
29.1253 -
29.1254 - if (attribs == null) {
29.1255 - sb.append(escapedText);
29.1256 -
29.1257 - continue;
29.1258 - }
29.1259 -
29.1260 - if (escapedText.indexOf('\n') != -1) {
29.1261 - escapedText = escapedText.replace("\n", "<br>"); // NOI18N
29.1262 - }
29.1263 -
29.1264 - if (t.id() == PythonTokenId.WHITESPACE) {
29.1265 - sb.append(escapedText);
29.1266 - } else {
29.1267 - sb.append("<span style=\""); // NOI18N
29.1268 -
29.1269 - Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
29.1270 -
29.1271 - if (fg != null) {
29.1272 - sb.append("color:"); // NOI18N
29.1273 - sb.append(getHtmlColor(fg));
29.1274 - sb.append(";"); // NOI18N
29.1275 - }
29.1276 -
29.1277 - Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
29.1278 -
29.1279 - if (bg != null) {
29.1280 - sb.append("background:"); // NOI18N
29.1281 - sb.append(getHtmlColor(bg));
29.1282 - sb.append(";"); // NOI18NP
29.1283 - }
29.1284 -
29.1285 - Boolean b = (Boolean)attribs.getAttribute(StyleConstants.Bold);
29.1286 -
29.1287 - if ((b != null) && b) {
29.1288 - sb.append("font-weight:bold;"); // NOI18N
29.1289 - }
29.1290 -
29.1291 - b = (Boolean)attribs.getAttribute(StyleConstants.Italic);
29.1292 -
29.1293 - if ((b != null) && b) {
29.1294 - sb.append("font-style:italic;"); // NOI18N
29.1295 - }
29.1296 -
29.1297 - // TODO - underline, strikethrough, ... and FONTS!
29.1298 - sb.append("\">"); // NOI18N
29.1299 - sb.append(escapedText);
29.1300 - sb.append("</span>"); // NOI18N
29.1301 - }
29.1302 - } while (ts.moveNext());
29.1303 - }
29.1304 -
29.1305 - if (addPre) {
29.1306 - sb.append("</pre>\n");
29.1307 - }
29.1308 -
29.1309 - return false;
29.1310 - }
29.1311 -
29.1312 -
29.1313 - // TODO - move to GsfUtilities?
29.1314 - private static String getHtmlColor(Color c) {
29.1315 - int r = c.getRed();
29.1316 - int g = c.getGreen();
29.1317 - int b = c.getBlue();
29.1318 - StringBuffer result = new StringBuffer();
29.1319 - result.append('#');
29.1320 -
29.1321 - String rs = Integer.toHexString(r);
29.1322 - String gs = Integer.toHexString(g);
29.1323 - String bs = Integer.toHexString(b);
29.1324 -
29.1325 - if (r < 0x10) {
29.1326 - result.append('0');
29.1327 - }
29.1328 -
29.1329 - result.append(rs);
29.1330 -
29.1331 - if (g < 0x10) {
29.1332 - result.append('0');
29.1333 - }
29.1334 -
29.1335 - result.append(gs);
29.1336 -
29.1337 - if (b < 0x10) {
29.1338 - result.append('0');
29.1339 - }
29.1340 -
29.1341 - result.append(bs);
29.1342 -
29.1343 - return result.toString();
29.1344 - }
29.1345 -}
30.1 --- a/python.editor/src/org/netbeans/modules/python/editor/codecoverage/PythonCoverageProvider.java Fri Sep 18 16:20:24 2015 -0500
30.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codecoverage/PythonCoverageProvider.java Mon Sep 21 13:01:16 2015 +0200
30.3 @@ -74,8 +74,8 @@
30.4 import org.netbeans.modules.gsf.codecoverage.api.FileCoverageSummary;
30.5 import org.netbeans.modules.python.api.PythonExecution;
30.6 import org.netbeans.modules.python.api.PythonMIMEResolver;
30.7 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
30.8 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
30.9 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
30.10 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
30.11 import org.openide.filesystems.FileObject;
30.12 import org.openide.filesystems.FileUtil;
30.13 import org.openide.modules.InstalledFileLocator;
31.1 --- a/python.editor/src/org/netbeans/modules/python/editor/codegen/ClassCodeGenerator.java Fri Sep 18 16:20:24 2015 -0500
31.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/ClassCodeGenerator.java Mon Sep 21 13:01:16 2015 +0200
31.3 @@ -46,7 +46,7 @@
31.4 import javax.swing.text.JTextComponent;
31.5 import org.netbeans.editor.BaseDocument;
31.6 import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
31.7 -import org.netbeans.modules.python.editor.PythonUtils;
31.8 +import org.netbeans.modules.python.source.PythonUtils;
31.9 import org.netbeans.spi.editor.codegen.CodeGenerator;
31.10 import org.netbeans.spi.editor.codegen.CodeGeneratorContextProvider;
31.11 import org.openide.util.Lookup;
31.12 @@ -119,7 +119,7 @@
31.13 final BaseDocument doc = (BaseDocument)target.getDocument();
31.14 final CodeTemplateManager ctm = CodeTemplateManager.get(doc);
31.15 if (ctm != null) {
31.16 - String template = PythonUtils.getCodeTemplate(ctm, "cls", "class ", null); // NOI18N
31.17 + String template = CodeGenUtils.getCodeTemplate(ctm, "cls", "class ", null); // NOI18N
31.18 if (template == null) {
31.19 template = "class ${name}${1 default=\"(Extends)\"}:\n${initialindent editable=\"false\"}${indent editable=\"false\"}\"\"\"\n${initialindent editable=\"false\"}${indent editable=\"false\"}${Documentation}\n${initialindent editable=\"false\"}${indent editable=\"false\"}\"\"\"\n${initialindent editable=\"false\"}${indent editable=\"false\"}${cursor}\n";
31.20 }
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/CodeGenUtils.java Mon Sep 21 13:01:16 2015 +0200
32.3 @@ -0,0 +1,77 @@
32.4 +/*
32.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
32.6 + *
32.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
32.8 + *
32.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
32.10 + * Other names may be trademarks of their respective owners.
32.11 + *
32.12 + * The contents of this file are subject to the terms of either the GNU
32.13 + * General Public License Version 2 only ("GPL") or the Common
32.14 + * Development and Distribution License("CDDL") (collectively, the
32.15 + * "License"). You may not use this file except in compliance with the
32.16 + * License. You can obtain a copy of the License at
32.17 + * http://www.netbeans.org/cddl-gplv2.html
32.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
32.19 + * specific language governing permissions and limitations under the
32.20 + * License. When distributing the software, include this License Header
32.21 + * Notice in each file and include the License file at
32.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
32.23 + * particular file as subject to the "Classpath" exception as provided
32.24 + * by Oracle in the GPL Version 2 section of the License file that
32.25 + * accompanied this code. If applicable, add the following below the
32.26 + * License Header, with the fields enclosed by brackets [] replaced by
32.27 + * your own identifying information:
32.28 + * "Portions Copyrighted [year] [name of copyright owner]"
32.29 + *
32.30 + * If you wish your version of this file to be governed by only the CDDL
32.31 + * or only the GPL Version 2, indicate your decision by adding
32.32 + * "[Contributor] elects to include this software in this distribution
32.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
32.34 + * single choice of license, a recipient has the option to distribute
32.35 + * your version of this file under either the CDDL, the GPL Version 2 or
32.36 + * to extend the choice of license to its licensees as provided above.
32.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
32.38 + * Version 2 license, then the option applies only if the new code is
32.39 + * made subject to such option by the copyright holder.
32.40 + *
32.41 + * Contributor(s):
32.42 + *
32.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
32.44 + */
32.45 +package org.netbeans.modules.python.editor.codegen;
32.46 +
32.47 +import org.netbeans.lib.editor.codetemplates.api.CodeTemplate;
32.48 +import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
32.49 +
32.50 +/**
32.51 + *
32.52 + * @author Ralph Ruijs
32.53 + */
32.54 +public final class CodeGenUtils {
32.55 +
32.56 + private CodeGenUtils() {
32.57 + }
32.58 +
32.59 + public static String getCodeTemplate(CodeTemplateManager ctm, String abbrev, String textPrefix, String wrongTextPrefix) {
32.60 + String templateText = null;
32.61 + for (CodeTemplate t : ctm.getCodeTemplates()) {
32.62 + if (abbrev.equals(t.getAbbreviation())) {
32.63 + templateText = t.getParametrizedText();
32.64 + break;
32.65 + }
32.66 + }
32.67 + if (templateText == null) {
32.68 + for (CodeTemplate t : ctm.getCodeTemplates()) {
32.69 + String text = t.getParametrizedText();
32.70 + if (text.startsWith(textPrefix) && (wrongTextPrefix == null || !text.startsWith(wrongTextPrefix))) {
32.71 + templateText = text;
32.72 + break;
32.73 + }
32.74 + }
32.75 + }
32.76 +
32.77 + return templateText;
32.78 + }
32.79 +
32.80 +}
33.1 --- a/python.editor/src/org/netbeans/modules/python/editor/codegen/ConstructorGenerator.java Fri Sep 18 16:20:24 2015 -0500
33.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/ConstructorGenerator.java Mon Sep 21 13:01:16 2015 +0200
33.3 @@ -46,7 +46,7 @@
33.4 import javax.swing.text.JTextComponent;
33.5 import org.netbeans.editor.BaseDocument;
33.6 import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
33.7 -import org.netbeans.modules.python.editor.PythonUtils;
33.8 +import org.netbeans.modules.python.source.PythonUtils;
33.9 import org.netbeans.spi.editor.codegen.CodeGenerator;
33.10 import org.openide.util.Lookup;
33.11 import org.openide.util.NbBundle;
33.12 @@ -80,7 +80,7 @@
33.13 final BaseDocument doc = (BaseDocument)target.getDocument();
33.14 final CodeTemplateManager ctm = CodeTemplateManager.get(doc);
33.15 if (ctm != null) {
33.16 - String template = PythonUtils.getCodeTemplate(ctm, "init", "def __init__", null); // NOI18N
33.17 + String template = CodeGenUtils.getCodeTemplate(ctm, "init", "def __init__", null); // NOI18N
33.18 if (template == null) {
33.19 template = "def __init__(self${1 default=\", parameters\"}):\n ${cursor})"; // NOI18N
33.20 }
34.1 --- a/python.editor/src/org/netbeans/modules/python/editor/codegen/MethodCodeGenerator.java Fri Sep 18 16:20:24 2015 -0500
34.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/MethodCodeGenerator.java Mon Sep 21 13:01:16 2015 +0200
34.3 @@ -46,7 +46,7 @@
34.4 import javax.swing.text.JTextComponent;
34.5 import org.netbeans.editor.BaseDocument;
34.6 import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
34.7 -import org.netbeans.modules.python.editor.PythonUtils;
34.8 +import org.netbeans.modules.python.source.PythonUtils;
34.9 import org.netbeans.spi.editor.codegen.CodeGenerator;
34.10 import org.netbeans.spi.editor.codegen.CodeGeneratorContextProvider;
34.11 import org.openide.util.Lookup;
34.12 @@ -117,7 +117,7 @@
34.13 final BaseDocument doc = (BaseDocument)target.getDocument();
34.14 final CodeTemplateManager ctm = CodeTemplateManager.get(doc);
34.15 if (ctm != null) {
34.16 - String template = PythonUtils.getCodeTemplate(ctm, "def", "def ", "def __"); // NOI18N
34.17 + String template = CodeGenUtils.getCodeTemplate(ctm, "def", "def ", "def __"); // NOI18N
34.18 if (template == null) {
34.19 template="def ${name}(${1 default=\"parameters\"}):\n${initialindent editable=\"false\"}${indent editable=\"false\"}\"\"\"${Documentation}\"\"\"\n${initialindent editable=\"false\"}${indent editable=\"false\"}${cursor}\n";
34.20 }
35.1 --- a/python.editor/src/org/netbeans/modules/python/editor/elements/AstElement.java Fri Sep 18 16:20:24 2015 -0500
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,117 +0,0 @@
35.4 -/*
35.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
35.6 - *
35.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
35.8 - *
35.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
35.10 - * Other names may be trademarks of their respective owners.
35.11 - *
35.12 - * The contents of this file are subject to the terms of either the GNU
35.13 - * General Public License Version 2 only ("GPL") or the Common
35.14 - * Development and Distribution License("CDDL") (collectively, the
35.15 - * "License"). You may not use this file except in compliance with the
35.16 - * License. You can obtain a copy of the License at
35.17 - * http://www.netbeans.org/cddl-gplv2.html
35.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
35.19 - * specific language governing permissions and limitations under the
35.20 - * License. When distributing the software, include this License Header
35.21 - * Notice in each file and include the License file at
35.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
35.23 - * particular file as subject to the "Classpath" exception as provided
35.24 - * by Oracle in the GPL Version 2 section of the License file that
35.25 - * accompanied this code. If applicable, add the following below the
35.26 - * License Header, with the fields enclosed by brackets [] replaced by
35.27 - * your own identifying information:
35.28 - * "Portions Copyrighted [year] [name of copyright owner]"
35.29 - *
35.30 - * Contributor(s):
35.31 - *
35.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
35.33 - */
35.34 -package org.netbeans.modules.python.editor.elements;
35.35 -
35.36 -import java.util.Set;
35.37 -import org.netbeans.modules.csl.api.ElementKind;
35.38 -import org.netbeans.modules.csl.api.Modifier;
35.39 -import org.netbeans.modules.csl.api.OffsetRange;
35.40 -import org.netbeans.modules.csl.spi.ParserResult;
35.41 -import org.netbeans.modules.python.editor.PythonAstUtils;
35.42 -import org.netbeans.modules.python.editor.PythonParserResult;
35.43 -import org.netbeans.modules.python.editor.PythonStructureItem;
35.44 -import org.netbeans.modules.python.editor.PythonStructureScanner;
35.45 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
35.46 -import org.python.antlr.PythonTree;
35.47 -import org.python.antlr.ast.Call;
35.48 -import org.python.antlr.ast.ClassDef;
35.49 -import org.python.antlr.ast.FunctionDef;
35.50 -import org.python.antlr.ast.Name;
35.51 -
35.52 -/**
35.53 - * Elements representing a node in a parse tree
35.54 - *
35.55 - * @author Tor Norbye
35.56 - */
35.57 -public class AstElement extends Element {
35.58 - protected PythonTree node;
35.59 - protected String name;
35.60 - protected ElementKind kind;
35.61 - //protected CompilationInfo info;
35.62 - protected Set<Modifier> modifiers;
35.63 - protected SymbolTable scopes;
35.64 -
35.65 - public AstElement(SymbolTable scopes, PythonTree node, String name, ElementKind kind) {
35.66 - //this.info = info;
35.67 - this.scopes = scopes;
35.68 - this.node = node;
35.69 - this.name = name;
35.70 - this.kind = kind;
35.71 - }
35.72 -
35.73 - public static AstElement create(PythonParserResult result, PythonTree node) {
35.74 - SymbolTable scopes = result.getSymbolTable();
35.75 -
35.76 - if (node instanceof FunctionDef) {
35.77 - return new PythonStructureItem(scopes, (FunctionDef)node);
35.78 - } else if (node instanceof ClassDef) {
35.79 - return new PythonStructureItem(scopes, (ClassDef)node);
35.80 - } else if (node instanceof Call) {
35.81 - String name = PythonAstUtils.getCallName((Call)node);
35.82 - return new AstElement(scopes, node, name, ElementKind.METHOD);
35.83 - } else if (node instanceof Name) {
35.84 - return new AstElement(scopes, node, ((Name)node).getInternalId(), ElementKind.VARIABLE);
35.85 - } else {
35.86 - return new AstElement(scopes, node, null, ElementKind.OTHER);
35.87 - }
35.88 - }
35.89 -
35.90 - public PythonTree getNode() {
35.91 - return node;
35.92 - }
35.93 -
35.94 - @Override
35.95 - public String getName() {
35.96 - return name;
35.97 - }
35.98 -
35.99 - @Override
35.100 - public ElementKind getKind() {
35.101 - return kind;
35.102 - }
35.103 -
35.104 - @Override
35.105 - public Set<Modifier> getModifiers() {
35.106 - if (modifiers == null) {
35.107 - if (name != null && scopes.isPrivate(node, name)) {
35.108 - modifiers = IndexedElement.PRIVATE_MODIFIERS;
35.109 - } else {
35.110 - modifiers = IndexedElement.PUBLIC_MODIFIERS;
35.111 - }
35.112 - }
35.113 -
35.114 - return modifiers;
35.115 - }
35.116 -
35.117 - public Object getSignature() {
35.118 - return name;
35.119 - }
35.120 -}
36.1 --- a/python.editor/src/org/netbeans/modules/python/editor/elements/Element.java Fri Sep 18 16:20:24 2015 -0500
36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3 @@ -1,85 +0,0 @@
36.4 -/*
36.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
36.6 - *
36.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
36.8 - *
36.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
36.10 - * Other names may be trademarks of their respective owners.
36.11 - *
36.12 - * The contents of this file are subject to the terms of either the GNU
36.13 - * General Public License Version 2 only ("GPL") or the Common
36.14 - * Development and Distribution License("CDDL") (collectively, the
36.15 - * "License"). You may not use this file except in compliance with the
36.16 - * License. You can obtain a copy of the License at
36.17 - * http://www.netbeans.org/cddl-gplv2.html
36.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
36.19 - * specific language governing permissions and limitations under the
36.20 - * License. When distributing the software, include this License Header
36.21 - * Notice in each file and include the License file at
36.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
36.23 - * particular file as subject to the "Classpath" exception as provided
36.24 - * by Oracle in the GPL Version 2 section of the License file that
36.25 - * accompanied this code. If applicable, add the following below the
36.26 - * License Header, with the fields enclosed by brackets [] replaced by
36.27 - * your own identifying information:
36.28 - * "Portions Copyrighted [year] [name of copyright owner]"
36.29 - *
36.30 - * Contributor(s):
36.31 - *
36.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
36.33 - */
36.34 -package org.netbeans.modules.python.editor.elements;
36.35 -
36.36 -import java.util.Collections;
36.37 -import java.util.Set;
36.38 -import org.netbeans.modules.csl.api.ElementHandle;
36.39 -import org.netbeans.modules.csl.api.ElementKind;
36.40 -import org.netbeans.modules.csl.api.Modifier;
36.41 -import org.netbeans.modules.csl.api.OffsetRange;
36.42 -import org.netbeans.modules.csl.spi.ParserResult;
36.43 -import org.netbeans.modules.python.api.PythonMIMEResolver;
36.44 -import org.openide.filesystems.FileObject;
36.45 -
36.46 -/**
36.47 - *
36.48 - * @author Tor Norbye
36.49 - */
36.50 -public abstract class Element implements ElementHandle {
36.51 - @Override
36.52 - public abstract String getName();
36.53 -
36.54 - @Override
36.55 - public abstract ElementKind getKind();
36.56 -
36.57 - @Override
36.58 - public String getMimeType() {
36.59 - return PythonMIMEResolver.PYTHON_MIME_TYPE;
36.60 - }
36.61 -
36.62 - @Override
36.63 - public boolean signatureEquals(ElementHandle handle) {
36.64 - // XXX TODO
36.65 - return false;
36.66 - }
36.67 -
36.68 - @Override
36.69 - public OffsetRange getOffsetRange(ParserResult pr) {
36.70 - // XXX TODO
36.71 - return null;
36.72 - }
36.73 -
36.74 - @Override
36.75 - public FileObject getFileObject() {
36.76 - return null;
36.77 - }
36.78 -
36.79 - @Override
36.80 - public Set<Modifier> getModifiers() {
36.81 - return Collections.emptySet();
36.82 - }
36.83 -
36.84 - @Override
36.85 - public String getIn() {
36.86 - return null;
36.87 - }
36.88 -}
37.1 --- a/python.editor/src/org/netbeans/modules/python/editor/elements/IndexedElement.java Fri Sep 18 16:20:24 2015 -0500
37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3 @@ -1,527 +0,0 @@
37.4 -/*
37.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
37.6 - *
37.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
37.8 - *
37.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
37.10 - * Other names may be trademarks of their respective owners.
37.11 - *
37.12 - * The contents of this file are subject to the terms of either the GNU
37.13 - * General Public License Version 2 only ("GPL") or the Common
37.14 - * Development and Distribution License("CDDL") (collectively, the
37.15 - * "License"). You may not use this file except in compliance with the
37.16 - * License. You can obtain a copy of the License at
37.17 - * http://www.netbeans.org/cddl-gplv2.html
37.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
37.19 - * specific language governing permissions and limitations under the
37.20 - * License. When distributing the software, include this License Header
37.21 - * Notice in each file and include the License file at
37.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
37.23 - * particular file as subject to the "Classpath" exception as provided
37.24 - * by Oracle in the GPL Version 2 section of the License file that
37.25 - * accompanied this code. If applicable, add the following below the
37.26 - * License Header, with the fields enclosed by brackets [] replaced by
37.27 - * your own identifying information:
37.28 - * "Portions Copyrighted [year] [name of copyright owner]"
37.29 - *
37.30 - * Contributor(s):
37.31 - *
37.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
37.33 - */
37.34 -package org.netbeans.modules.python.editor.elements;
37.35 -
37.36 -import java.util.Collections;
37.37 -import java.util.EnumSet;
37.38 -import java.util.Set;
37.39 -import org.netbeans.modules.csl.api.ElementKind;
37.40 -import org.netbeans.modules.csl.api.Modifier;
37.41 -import org.netbeans.modules.csl.api.OffsetRange;
37.42 -import org.netbeans.modules.csl.spi.ParserResult;
37.43 -import org.netbeans.modules.python.editor.PythonIndex;
37.44 -import org.netbeans.modules.python.editor.PythonAstUtils;
37.45 -import org.openide.filesystems.FileObject;
37.46 -import org.python.antlr.PythonTree;
37.47 -
37.48 -/**
37.49 - * Elements representing information coming from the persistent index
37.50 - *
37.51 - * @author Tor Norbye
37.52 - */
37.53 -public class IndexedElement extends Element {
37.54 - public static final EnumSet<Modifier> PRIVATE_MODIFIERS = EnumSet.of(Modifier.PRIVATE);
37.55 - public static final EnumSet<Modifier> PROTECTED_MODIFIERS = EnumSet.of(Modifier.PROTECTED);
37.56 - public static final EnumSet<Modifier> STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC);
37.57 - public static final EnumSet<Modifier> PRIVATE_STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC, Modifier.PRIVATE);
37.58 - public static final EnumSet<Modifier> PROTECTED_STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC, Modifier.PROTECTED);
37.59 - public static final Set<Modifier> PUBLIC_MODIFIERS = Collections.emptySet();
37.60 -
37.61 - // Plan: Stash a single item for class entries so I can search by document for the class.
37.62 - // Add more types into the types
37.63 - /** This method is documented */
37.64 - public static final int DOCUMENTED = 1 << 0;
37.65 - /** This method is private */
37.66 - public static final int PRIVATE = 1 << 2;
37.67 - /** This is a function, not a property */
37.68 - public static final int FUNCTION = 1 << 3;
37.69 - /** This element is "static" (e.g. it's a classvar for fields, class method for methods etc) */
37.70 - public static final int STATIC = 1 << 4;
37.71 - /** This element is deliberately not documented (rdoc :nodoc:) */
37.72 - public static final int NODOC = 1 << 5;
37.73 - /** This is a global variable */
37.74 - public static final int GLOBAL = 1 << 6;
37.75 - /** This is a constructor */
37.76 - public static final int CONSTRUCTOR = 1 << 7;
37.77 - /** This is a deprecated */
37.78 - public static final int DEPRECATED = 1 << 8;
37.79 - /** This is a documentation-only definition */
37.80 - public static final int DOC_ONLY = 1 << 9;
37.81 - /** This is a constant/final */
37.82 - public static final int FINAL = 1 << 10;
37.83 -
37.84 - // Flags noting semicolon positions in attributes
37.85 - public static final int NAME_INDEX = 0;
37.86 - public static final int TYPE_INDEX = 1;
37.87 - public static final int FLAG_INDEX = 2;
37.88 - public static final int ARG_INDEX = 3;
37.89 -// public static final int IN_INDEX = 1;
37.90 -// public static final int CASE_SENSITIVE_INDEX = 2;
37.91 -// public static final int FLAG_INDEX = 3;
37.92 -// public static final int ARG_INDEX = 4;
37.93 -// public static final int NODE_INDEX = 5;
37.94 -// public static final int DOC_INDEX = 6;
37.95 -// public static final int BROWSER_INDEX = 7;
37.96 -// public static final int TYPE_INDEX = 8;
37.97 - protected final String name;
37.98 - protected final ElementKind kind;
37.99 - protected String url;
37.100 - protected FileObject fileObject;
37.101 - protected final String module;
37.102 - protected String rhs;
37.103 - protected boolean smart;
37.104 - protected boolean inherited;
37.105 - protected Set<Modifier> modifiers;
37.106 - protected PythonTree node;
37.107 - protected int flags;
37.108 - protected final String attributes;
37.109 - protected final String clz;
37.110 - protected int order;
37.111 -
37.112 - public IndexedElement(String name, ElementKind kind, String url, String module, String clz, String attributes) {
37.113 - this.name = name;
37.114 - this.kind = kind;
37.115 - this.url = url;
37.116 - this.module = module;
37.117 - this.clz = clz;
37.118 - this.attributes = attributes;
37.119 -
37.120 - // Should be IndexedMethod:
37.121 - //assert !((!(this instanceof IndexedMethod)) && (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR)) : this;
37.122 - }
37.123 -
37.124 - public static IndexedElement create(String signature, String module, String url, String clz) {
37.125 - int semi = signature.indexOf(';');
37.126 - assert semi != -1;
37.127 -
37.128 - String name = signature.substring(0, semi);
37.129 - int flags = IndexedElement.decode(signature, semi + 3, 0);
37.130 -
37.131 - char type = signature.charAt(semi + 1);
37.132 - ElementKind kind;
37.133 - switch (type) {
37.134 - case 'C':
37.135 - kind = ElementKind.CLASS;
37.136 - break;
37.137 - case 'I':
37.138 - kind = ElementKind.MODULE;
37.139 - break;
37.140 - case 'D':
37.141 - kind = ElementKind.VARIABLE;
37.142 - break;
37.143 - case 'A':
37.144 - kind = ElementKind.ATTRIBUTE;
37.145 - break;
37.146 - case 'F':
37.147 - case 'M':
37.148 - case 'c': {
37.149 - kind = type == 'c' ? ElementKind.CONSTRUCTOR : ElementKind.METHOD;
37.150 - IndexedMethod method = new IndexedMethod(name, kind, url, module, clz, signature);
37.151 - method.flags = flags;
37.152 - return method;
37.153 - }
37.154 - default:
37.155 - kind = ElementKind.OTHER;
37.156 - break;
37.157 - }
37.158 -
37.159 - IndexedElement element = new IndexedElement(name, kind, url, module, clz, signature);
37.160 - element.flags = flags;
37.161 - return element;
37.162 - }
37.163 -
37.164 - @Override
37.165 - public boolean equals(Object obj) {
37.166 - if (obj == null) {
37.167 - return false;
37.168 - }
37.169 - if (getClass() != obj.getClass()) {
37.170 - return false;
37.171 - }
37.172 - final IndexedElement other = (IndexedElement)obj;
37.173 - if (this.name != other.name && (this.name == null || !this.name.equals(other.name))) {
37.174 - return false;
37.175 - }
37.176 - if (this.module != other.module && (this.module == null || !this.module.equals(other.module))) {
37.177 - return false;
37.178 - }
37.179 - if (this.kind != other.kind) {
37.180 - return false;
37.181 - }
37.182 - return true;
37.183 - }
37.184 -
37.185 - public String getModule() {
37.186 - return module;
37.187 - }
37.188 -
37.189 - @Override
37.190 - public int hashCode() {
37.191 - int hash = 3;
37.192 - hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
37.193 - hash = 67 * hash + (this.kind != null ? this.kind.hashCode() : 0);
37.194 - return hash;
37.195 - }
37.196 -
37.197 - @Override
37.198 - public String getName() {
37.199 - return name;
37.200 - }
37.201 -
37.202 - @Override
37.203 - public ElementKind getKind() {
37.204 - return kind;
37.205 - }
37.206 -
37.207 - public String getFilenameUrl() {
37.208 - return url;
37.209 - }
37.210 -
37.211 - @Override
37.212 - public FileObject getFileObject() {
37.213 - if ((fileObject == null) && (url != null)) {
37.214 - fileObject = PythonIndex.getFileObject(url);
37.215 -
37.216 - if (fileObject == null) {
37.217 - // Don't try again
37.218 - url = null;
37.219 - }
37.220 - }
37.221 -
37.222 - return fileObject;
37.223 - }
37.224 -
37.225 - public void setFlags(int flags) {
37.226 - this.flags = flags;
37.227 - }
37.228 -
37.229 - public void setInherited(boolean inherited) {
37.230 - this.inherited = inherited;
37.231 - }
37.232 -
37.233 - public boolean isInherited() {
37.234 - return inherited;
37.235 - }
37.236 -
37.237 - public String getType() {
37.238 - return null;
37.239 - }
37.240 -
37.241 - public String getOrigin() {
37.242 - return module;
37.243 - }
37.244 -
37.245 - public boolean isSmart() {
37.246 - return smart;
37.247 - }
37.248 -
37.249 - public void setSmart(boolean smart) {
37.250 - this.smart = smart;
37.251 - }
37.252 -
37.253 - public String getRhs() {
37.254 - if (rhs == null) {
37.255 - rhs = module;
37.256 - if (rhs.equals("stub_missing")) { // NOI18N
37.257 - rhs = "<i>builtin</i>";
37.258 - }
37.259 - }
37.260 - return rhs;
37.261 - }
37.262 -
37.263 - public void setRhs(String rhs) {
37.264 - this.rhs = rhs;
37.265 - }
37.266 -
37.267 - @Override
37.268 - public String getIn() {
37.269 - return module;
37.270 - }
37.271 -
37.272 - public String getSignature() {
37.273 - if (clz != null) {
37.274 - return clz + "." + name;
37.275 - }
37.276 -
37.277 - return name;
37.278 - }
37.279 -
37.280 - public String getClz() {
37.281 - return clz;
37.282 - }
37.283 -
37.284 - public int getOrder() {
37.285 - return order;
37.286 - }
37.287 -
37.288 - public void setOrder(int order) {
37.289 - this.order = order;
37.290 - }
37.291 -
37.292 - public static Set<Modifier> getModifiersForName(String name, boolean isPrivate, boolean isProtected, boolean isStatic) {
37.293 - Set<Modifier> modifiers;
37.294 -
37.295 - // Private variables: start with __ but doesn't end with __
37.296 - // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
37.297 - if (name != null && name.startsWith("__") && !name.endsWith("__")) { // NOI18N
37.298 - isPrivate = true;
37.299 - } else if (name != null && name.startsWith("_") && !name.endsWith("_")) { // NOI18N
37.300 - // From PEP8: Single_leading_underscore: weak "internal use" indicator
37.301 - // (e.g. "from M import *" does not import objects whose name
37.302 - // starts with an underscore).
37.303 - // The protected modifier might work well to visually indicate this.
37.304 - isProtected = true;
37.305 - }
37.306 - if (isPrivate) {
37.307 - if (isStatic) {
37.308 - modifiers = PRIVATE_STATIC_MODIFIERS;
37.309 - } else {
37.310 - modifiers = PRIVATE_MODIFIERS;
37.311 - }
37.312 - } else if (isProtected) {
37.313 - if (isStatic) {
37.314 - modifiers = PROTECTED_STATIC_MODIFIERS;
37.315 - } else {
37.316 - modifiers = PROTECTED_MODIFIERS;
37.317 - }
37.318 - } else {
37.319 - if (isStatic) {
37.320 - modifiers = STATIC_MODIFIERS;
37.321 - } else {
37.322 - modifiers = PUBLIC_MODIFIERS;
37.323 - }
37.324 - }
37.325 -
37.326 - return modifiers;
37.327 - }
37.328 -
37.329 - @Override
37.330 - public Set<Modifier> getModifiers() {
37.331 - if (modifiers == null) {
37.332 - modifiers = getModifiersForName(name, isPrivate(), false, isStatic());
37.333 - }
37.334 -
37.335 - return modifiers;
37.336 - }
37.337 -
37.338 - public PythonTree getNode() {
37.339 - if (node == null) {
37.340 - node = PythonAstUtils.getForeignNode(this, null);
37.341 - }
37.342 - return node;
37.343 - }
37.344 -
37.345 - @Override
37.346 - public String toString() {
37.347 - return "IndexedElement:" + name + "," + kind + "," + rhs;
37.348 - }
37.349 -
37.350 - protected int getAttributeSection(int section) {
37.351 - assert section != 0; // Obtain directly, and logic below (+1) is wrong
37.352 - int attributeIndex = 0;
37.353 - for (int i = 0; i < section; i++) {
37.354 - attributeIndex = attributes.indexOf(';', attributeIndex + 1);
37.355 - }
37.356 -
37.357 - assert attributeIndex != -1;
37.358 - return attributeIndex + 1;
37.359 - }
37.360 -
37.361 - /** Return a string (suitable for persistence) encoding the given flags */
37.362 - public static String encode(int flags) {
37.363 - return Integer.toString(flags, 16);
37.364 - }
37.365 -
37.366 - /** Return flag corresponding to the given encoding chars */
37.367 - public static int decode(String s, int startIndex, int defaultValue) {
37.368 - int value = 0;
37.369 - for (int i = startIndex, n = s.length(); i < n; i++) {
37.370 - char c = s.charAt(i);
37.371 - if (c == ';') {
37.372 - if (i == startIndex) {
37.373 - return defaultValue;
37.374 - }
37.375 - break;
37.376 - }
37.377 -
37.378 - value = value << 4;
37.379 -
37.380 - if (c > '9') {
37.381 - value += c - 'a' + 10;
37.382 - } else {
37.383 - value += c - '0';
37.384 - }
37.385 - }
37.386 -
37.387 - return value;
37.388 - }
37.389 -
37.390 - public static int getFlags(AstElement element) {
37.391 - // Return the flags corresponding to the given AST element
37.392 - int value = 0;
37.393 -
37.394 - ElementKind k = element.getKind();
37.395 - if (k == ElementKind.CONSTRUCTOR) {
37.396 - value = value | CONSTRUCTOR;
37.397 - }
37.398 - if (k == ElementKind.METHOD || k == ElementKind.CONSTRUCTOR) {
37.399 - value = value | FUNCTION;
37.400 - } else if (k == ElementKind.GLOBAL) {
37.401 - value = value | GLOBAL;
37.402 - }
37.403 - if (element.getModifiers().contains(Modifier.STATIC)) {
37.404 - value = value | STATIC;
37.405 - }
37.406 - if (element.getModifiers().contains(Modifier.DEPRECATED)) {
37.407 - value = value | DEPRECATED;
37.408 - }
37.409 - if (element.getModifiers().contains(Modifier.PRIVATE)) {
37.410 - value = value | PRIVATE;
37.411 - }
37.412 -
37.413 - return value;
37.414 - }
37.415 -
37.416 - public boolean isDocumented() {
37.417 - return (flags & DOCUMENTED) != 0;
37.418 - }
37.419 -
37.420 - public boolean isPublic() {
37.421 - return (flags & PRIVATE) == 0;
37.422 - }
37.423 -
37.424 - public boolean isPrivate() {
37.425 - return (flags & PRIVATE) != 0;
37.426 - }
37.427 -
37.428 - public boolean isFunction() {
37.429 - return (flags & FUNCTION) != 0;
37.430 - }
37.431 -
37.432 - public boolean isStatic() {
37.433 - return (flags & STATIC) != 0;
37.434 - }
37.435 -
37.436 - public boolean isNoDoc() {
37.437 - return (flags & NODOC) != 0;
37.438 - }
37.439 -
37.440 - public boolean isFinal() {
37.441 - return (flags & FINAL) != 0;
37.442 - }
37.443 -
37.444 - public boolean isConstructor() {
37.445 - return (flags & CONSTRUCTOR) != 0;
37.446 - }
37.447 -
37.448 - public boolean isDeprecated() {
37.449 - return (flags & DEPRECATED) != 0;
37.450 - }
37.451 -
37.452 - public boolean isDocOnly() {
37.453 - return (flags & DOC_ONLY) != 0;
37.454 - }
37.455 -
37.456 - public static String decodeFlags(int flags) {
37.457 - StringBuilder sb = new StringBuilder();
37.458 - if ((flags & DOCUMENTED) != 0) {
37.459 - sb.append("|DOCUMENTED");
37.460 - }
37.461 -
37.462 - if ((flags & PRIVATE) != 0) {
37.463 - sb.append("|PRIVATE");
37.464 - }
37.465 -
37.466 - if ((flags & CONSTRUCTOR) != 0) {
37.467 - sb.append("|CONSTRUCTOR");
37.468 - } else if ((flags & FUNCTION) != 0) {
37.469 - sb.append("|FUNCTION");
37.470 - } else if ((flags & GLOBAL) != 0) {
37.471 - sb.append("|GLOBAL");
37.472 - }
37.473 -
37.474 - if ((flags & STATIC) != 0) {
37.475 - sb.append("|STATIC");
37.476 - }
37.477 -
37.478 - if ((flags & NODOC) != 0) {
37.479 - sb.append("|NODOC");
37.480 - }
37.481 -
37.482 - if ((flags & DEPRECATED) != 0) {
37.483 - sb.append("|DEPRECATED");
37.484 - }
37.485 -
37.486 - if ((flags & DOC_ONLY) != 0) {
37.487 - sb.append("|DOC_ONLY");
37.488 - }
37.489 -
37.490 - if ((flags & FINAL) != 0) {
37.491 - sb.append("|FINAL");
37.492 - }
37.493 -
37.494 - if (sb.length() > 0) {
37.495 - sb.append("|");
37.496 - }
37.497 - return sb.toString();
37.498 - }
37.499 -
37.500 - // For testsuite
37.501 - public static int stringToFlags(String string) {
37.502 - int flags = 0;
37.503 - if (string.contains("|DOCUMENTED")) {
37.504 - flags |= DOCUMENTED;
37.505 - }
37.506 - if (string.contains("|PRIVATE")) {
37.507 - flags |= PRIVATE;
37.508 - }
37.509 - if (string.contains("|DEPRECATED")) {
37.510 - flags |= DEPRECATED;
37.511 - }
37.512 - if (string.contains("|CONSTRUCTOR")) {
37.513 - flags |= CONSTRUCTOR;
37.514 - }
37.515 -// if (string.indexOf("|PROTECTED") != -1) {
37.516 -// flags |= PROTECTED;
37.517 -// }
37.518 -// if (string.indexOf("|TOPLEVEL") != -1) {
37.519 -// flags |= TOPLEVEL;
37.520 -// }
37.521 - if (string.contains("|STATIC")) {
37.522 - flags |= STATIC;
37.523 - }
37.524 - if (string.contains("|NODOC")) {
37.525 - flags |= NODOC;
37.526 - }
37.527 -
37.528 - return flags;
37.529 - }
37.530 -}
38.1 --- a/python.editor/src/org/netbeans/modules/python/editor/elements/IndexedMethod.java Fri Sep 18 16:20:24 2015 -0500
38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3 @@ -1,88 +0,0 @@
38.4 -/*
38.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
38.6 - *
38.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
38.8 - *
38.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
38.10 - * Other names may be trademarks of their respective owners.
38.11 - *
38.12 - * The contents of this file are subject to the terms of either the GNU
38.13 - * General Public License Version 2 only ("GPL") or the Common
38.14 - * Development and Distribution License("CDDL") (collectively, the
38.15 - * "License"). You may not use this file except in compliance with the
38.16 - * License. You can obtain a copy of the License at
38.17 - * http://www.netbeans.org/cddl-gplv2.html
38.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
38.19 - * specific language governing permissions and limitations under the
38.20 - * License. When distributing the software, include this License Header
38.21 - * Notice in each file and include the License file at
38.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
38.23 - * particular file as subject to the "Classpath" exception as provided
38.24 - * by Oracle in the GPL Version 2 section of the License file that
38.25 - * accompanied this code. If applicable, add the following below the
38.26 - * License Header, with the fields enclosed by brackets [] replaced by
38.27 - * your own identifying information:
38.28 - * "Portions Copyrighted [year] [name of copyright owner]"
38.29 - *
38.30 - * Contributor(s):
38.31 - *
38.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
38.33 - */
38.34 -package org.netbeans.modules.python.editor.elements;
38.35 -
38.36 -import org.netbeans.modules.csl.api.ElementKind;
38.37 -
38.38 -/**
38.39 - *
38.40 - * @author Tor Norbye
38.41 - */
38.42 -public class IndexedMethod extends IndexedElement {
38.43 - private String[] params;
38.44 -
38.45 - public IndexedMethod(String name, ElementKind kind, String url, String module, String clz, String signature) {
38.46 - super(name, kind, url, module, clz, signature);
38.47 - }
38.48 -
38.49 - public String[] getParams() {
38.50 - if (params == null) {
38.51 - //int argsBegin = name.length()+3;
38.52 - int argsBegin = getAttributeSection(IndexedElement.ARG_INDEX);
38.53 - int argsEnd = attributes.indexOf(';', argsBegin);
38.54 - assert argsEnd != -1 : attributes;
38.55 - if (argsEnd > argsBegin) {
38.56 - String paramString = attributes.substring(argsBegin, argsEnd);
38.57 - params = paramString.split(",");
38.58 - } else {
38.59 - params = new String[0];
38.60 - }
38.61 - }
38.62 -
38.63 - return params;
38.64 - }
38.65 -
38.66 - @Override
38.67 - public boolean equals(Object obj) {
38.68 - if (obj == null) {
38.69 - return false;
38.70 - }
38.71 - if (getClass() != obj.getClass()) {
38.72 - return false;
38.73 - }
38.74 - final IndexedMethod other = (IndexedMethod)obj;
38.75 - if (this.attributes != other.attributes && (this.attributes == null || !this.attributes.equals(other.attributes))) {
38.76 - return false;
38.77 - }
38.78 - if (this.clz != other.clz && (this.clz == null || !this.clz.equals(other.clz))) {
38.79 - return false;
38.80 - }
38.81 - return true;
38.82 - }
38.83 -
38.84 - @Override
38.85 - public int hashCode() {
38.86 - int hash = 7;
38.87 - hash = 53 * hash + (this.attributes != null ? this.attributes.hashCode() : 0);
38.88 - hash = 53 * hash + (this.clz != null ? this.clz.hashCode() : 0);
38.89 - return hash;
38.90 - }
38.91 -}
39.1 --- a/python.editor/src/org/netbeans/modules/python/editor/elements/IndexedPackage.java Fri Sep 18 16:20:24 2015 -0500
39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
39.3 @@ -1,106 +0,0 @@
39.4 -/*
39.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
39.6 - *
39.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
39.8 - *
39.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
39.10 - * Other names may be trademarks of their respective owners.
39.11 - *
39.12 - * The contents of this file are subject to the terms of either the GNU
39.13 - * General Public License Version 2 only ("GPL") or the Common
39.14 - * Development and Distribution License("CDDL") (collectively, the
39.15 - * "License"). You may not use this file except in compliance with the
39.16 - * License. You can obtain a copy of the License at
39.17 - * http://www.netbeans.org/cddl-gplv2.html
39.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
39.19 - * specific language governing permissions and limitations under the
39.20 - * License. When distributing the software, include this License Header
39.21 - * Notice in each file and include the License file at
39.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
39.23 - * particular file as subject to the "Classpath" exception as provided
39.24 - * by Oracle in the GPL Version 2 section of the License file that
39.25 - * accompanied this code. If applicable, add the following below the
39.26 - * License Header, with the fields enclosed by brackets [] replaced by
39.27 - * your own identifying information:
39.28 - * "Portions Copyrighted [year] [name of copyright owner]"
39.29 - *
39.30 - * If you wish your version of this file to be governed by only the CDDL
39.31 - * or only the GPL Version 2, indicate your decision by adding
39.32 - * "[Contributor] elects to include this software in this distribution
39.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
39.34 - * single choice of license, a recipient has the option to distribute
39.35 - * your version of this file under either the CDDL, the GPL Version 2 or
39.36 - * to extend the choice of license to its licensees as provided above.
39.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
39.38 - * Version 2 license, then the option applies only if the new code is
39.39 - * made subject to such option by the copyright holder.
39.40 - *
39.41 - * Contributor(s):
39.42 - *
39.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
39.44 - */
39.45 -package org.netbeans.modules.python.editor.elements;
39.46 -
39.47 -import java.util.Collections;
39.48 -import java.util.Set;
39.49 -import org.netbeans.modules.csl.api.ElementKind;
39.50 -import org.netbeans.modules.csl.api.Modifier;
39.51 -
39.52 -/**
39.53 - *
39.54 - * @author Tor Norbye
39.55 - */
39.56 -public class IndexedPackage extends IndexedElement {
39.57 - private String pkg;
39.58 - private boolean hasMore;
39.59 -
39.60 - public IndexedPackage(String name, String pkg, String url, boolean hasMore) {
39.61 - super(name, ElementKind.PACKAGE, url, null, null, null);
39.62 - this.pkg = pkg;
39.63 - this.hasMore = hasMore;
39.64 - }
39.65 -
39.66 - @Override
39.67 - public Set<Modifier> getModifiers() {
39.68 - return Collections.emptySet();
39.69 - }
39.70 -
39.71 - public String getPkg() {
39.72 - return pkg;
39.73 - }
39.74 -
39.75 - public boolean hasMore() {
39.76 - return hasMore;
39.77 - }
39.78 -
39.79 - @Override
39.80 - public boolean equals(Object obj) {
39.81 - if (obj == null) {
39.82 - return false;
39.83 - }
39.84 - if (getClass() != obj.getClass()) {
39.85 - return false;
39.86 - }
39.87 - final IndexedPackage other = (IndexedPackage)obj;
39.88 -
39.89 - // Side effect:
39.90 - // If any element thinks we have more
39.91 - if (other.hasMore) {
39.92 - this.hasMore = other.hasMore;
39.93 - } else if (this.hasMore) {
39.94 - other.hasMore = this.hasMore;
39.95 - }
39.96 -
39.97 - if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
39.98 - return false;
39.99 - }
39.100 - return true;
39.101 - }
39.102 -
39.103 - @Override
39.104 - public int hashCode() {
39.105 - int hash = 7;
39.106 - hash = 73 * hash + (this.name != null ? this.name.hashCode() : 0);
39.107 - return hash;
39.108 - }
39.109 -}
40.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/AccessToProtected.java Fri Sep 18 16:20:24 2015 -0500
40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
40.3 @@ -1,150 +0,0 @@
40.4 -/*
40.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
40.6 - *
40.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
40.8 - *
40.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
40.10 - * Other names may be trademarks of their respective owners.
40.11 - *
40.12 - * The contents of this file are subject to the terms of either the GNU
40.13 - * General Public License Version 2 only ("GPL") or the Common
40.14 - * Development and Distribution License("CDDL") (collectively, the
40.15 - * "License"). You may not use this file except in compliance with the
40.16 - * License. You can obtain a copy of the License at
40.17 - * http://www.netbeans.org/cddl-gplv2.html
40.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
40.19 - * specific language governing permissions and limitations under the
40.20 - * License. When distributing the software, include this License Header
40.21 - * Notice in each file and include the License file at
40.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
40.23 - * particular file as subject to the "Classpath" exception as provided
40.24 - * by Oracle in the GPL Version 2 section of the License file that
40.25 - * accompanied this code. If applicable, add the following below the
40.26 - * License Header, with the fields enclosed by brackets [] replaced by
40.27 - * your own identifying information:
40.28 - * "Portions Copyrighted [year] [name of copyright owner]"
40.29 - *
40.30 - * If you wish your version of this file to be governed by only the CDDL
40.31 - * or only the GPL Version 2, indicate your decision by adding
40.32 - * "[Contributor] elects to include this software in this distribution
40.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
40.34 - * single choice of license, a recipient has the option to distribute
40.35 - * your version of this file under either the CDDL, the GPL Version 2 or
40.36 - * to extend the choice of license to its licensees as provided above.
40.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
40.38 - * Version 2 license, then the option applies only if the new code is
40.39 - * made subject to such option by the copyright holder.
40.40 - *
40.41 - * Contributor(s):
40.42 - *
40.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
40.44 - */
40.45 -package org.netbeans.modules.python.editor.hints;
40.46 -
40.47 -import java.util.Collections;
40.48 -import java.util.List;
40.49 -import java.util.Set;
40.50 -import java.util.prefs.Preferences;
40.51 -import javax.swing.JComponent;
40.52 -import org.netbeans.modules.csl.api.Hint;
40.53 -import org.netbeans.modules.csl.api.HintFix;
40.54 -import org.netbeans.modules.csl.api.HintSeverity;
40.55 -import org.netbeans.modules.csl.api.OffsetRange;
40.56 -import org.netbeans.modules.csl.api.RuleContext;
40.57 -import org.netbeans.modules.python.editor.PythonAstUtils;
40.58 -import org.netbeans.modules.python.editor.PythonParserResult;
40.59 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
40.60 -import org.netbeans.modules.python.editor.scopes.SymInfo;
40.61 -import org.openide.util.NbBundle;
40.62 -import org.python.antlr.ast.Attribute;
40.63 -import org.python.antlr.ast.Name;
40.64 -import org.python.antlr.base.expr;
40.65 -
40.66 -/**
40.67 - * Check direct acces to parent protected variables or methods
40.68 - * @author jean-yves Mengant
40.69 - */
40.70 -public class AccessToProtected extends PythonAstRule {
40.71 - private final static String ACCESS_PROTECTED_ID = "AccessProtected"; // NOI18N
40.72 - private final static String ACCESS_PROTECTED_VARIABLE = "AccessProtectedVariable"; // NOI18N
40.73 - private final static String ACCESS_PROTECTED_DESC = "AccessProtectedDesc"; // NOI18N
40.74 -
40.75 - @Override
40.76 - public Set<Class> getKinds() {
40.77 - return Collections.<Class>singleton(Attribute.class);
40.78 - }
40.79 -
40.80 - @Override
40.81 - public void run(PythonRuleContext context, List<Hint> result) {
40.82 - PythonParserResult info = (PythonParserResult) context.parserResult;
40.83 - Attribute cur = (Attribute)context.node;
40.84 - String curAttr = cur.getInternalAttr();
40.85 - if (curAttr == null) {
40.86 - return;
40.87 - }
40.88 -
40.89 - if (SymInfo.isProtectedName(curAttr)) {
40.90 - expr curValue = cur.getInternalValue();
40.91 - if (curValue instanceof Name) {
40.92 - Name nam = (Name)curValue;
40.93 - String id = nam.getInternalId();
40.94 - if (id.equals("self")) { // NOI18N
40.95 - return; // normal access from class instance
40.96 - }
40.97 - if (PythonAstUtils.getParentClassFromNode(context.path, null, id) != null) {
40.98 - return; // parent access
40.99 - }
40.100 - // we should warn here : Access to protected Attributes from non child
40.101 - // classes
40.102 - OffsetRange range = PythonAstUtils.getRange(cur);
40.103 - range = PythonLexerUtils.getLexerOffsets(info, range);
40.104 - if (range != OffsetRange.NONE) {
40.105 - List<HintFix> fixList = Collections.emptyList();
40.106 - String message = NbBundle.getMessage(NameRule.class, ACCESS_PROTECTED_VARIABLE, curAttr);
40.107 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
40.108 - result.add(desc);
40.109 - }
40.110 - }
40.111 - }
40.112 - }
40.113 -
40.114 - @Override
40.115 - public String getId() {
40.116 - return ACCESS_PROTECTED_ID;
40.117 - }
40.118 -
40.119 - @Override
40.120 - public String getDescription() {
40.121 - return NbBundle.getMessage(RelativeImports.class, ACCESS_PROTECTED_DESC);
40.122 - }
40.123 -
40.124 - @Override
40.125 - public boolean getDefaultEnabled() {
40.126 - return false;
40.127 - }
40.128 -
40.129 - @Override
40.130 - public JComponent getCustomizer(Preferences node) {
40.131 - return null;
40.132 - }
40.133 -
40.134 - @Override
40.135 - public boolean appliesTo(RuleContext context) {
40.136 - return true;
40.137 - }
40.138 -
40.139 - @Override
40.140 - public String getDisplayName() {
40.141 - return NbBundle.getMessage(AccessToProtected.class, ACCESS_PROTECTED_ID);
40.142 - }
40.143 -
40.144 - @Override
40.145 - public boolean showInTasklist() {
40.146 - return true;
40.147 - }
40.148 -
40.149 - @Override
40.150 - public HintSeverity getDefaultSeverity() {
40.151 - return HintSeverity.WARNING;
40.152 - }
40.153 -}
41.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/AllAssignExists.java Fri Sep 18 16:20:24 2015 -0500
41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3 @@ -1,148 +0,0 @@
41.4 -/*
41.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
41.6 - *
41.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
41.8 - *
41.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
41.10 - * Other names may be trademarks of their respective owners.
41.11 - *
41.12 - * The contents of this file are subject to the terms of either the GNU
41.13 - * General Public License Version 2 only ("GPL") or the Common
41.14 - * Development and Distribution License("CDDL") (collectively, the
41.15 - * "License"). You may not use this file except in compliance with the
41.16 - * License. You can obtain a copy of the License at
41.17 - * http://www.netbeans.org/cddl-gplv2.html
41.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
41.19 - * specific language governing permissions and limitations under the
41.20 - * License. When distributing the software, include this License Header
41.21 - * Notice in each file and include the License file at
41.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
41.23 - * particular file as subject to the "Classpath" exception as provided
41.24 - * by Oracle in the GPL Version 2 section of the License file that
41.25 - * accompanied this code. If applicable, add the following below the
41.26 - * License Header, with the fields enclosed by brackets [] replaced by
41.27 - * your own identifying information:
41.28 - * "Portions Copyrighted [year] [name of copyright owner]"
41.29 - *
41.30 - * If you wish your version of this file to be governed by only the CDDL
41.31 - * or only the GPL Version 2, indicate your decision by adding
41.32 - * "[Contributor] elects to include this software in this distribution
41.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
41.34 - * single choice of license, a recipient has the option to distribute
41.35 - * your version of this file under either the CDDL, the GPL Version 2 or
41.36 - * to extend the choice of license to its licensees as provided above.
41.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
41.38 - * Version 2 license, then the option applies only if the new code is
41.39 - * made subject to such option by the copyright holder.
41.40 - *
41.41 - * Contributor(s):
41.42 - *
41.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
41.44 - */
41.45 -package org.netbeans.modules.python.editor.hints;
41.46 -
41.47 -import java.util.Collections;
41.48 -import java.util.List;
41.49 -import java.util.Set;
41.50 -import java.util.prefs.Preferences;
41.51 -import javax.swing.JComponent;
41.52 -import org.netbeans.modules.csl.api.Hint;
41.53 -import org.netbeans.modules.csl.api.HintFix;
41.54 -import org.netbeans.modules.csl.api.HintSeverity;
41.55 -import org.netbeans.modules.csl.api.OffsetRange;
41.56 -import org.netbeans.modules.csl.api.RuleContext;
41.57 -import org.netbeans.modules.python.editor.PythonAstUtils;
41.58 -import org.netbeans.modules.python.editor.PythonParserResult;
41.59 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
41.60 -import org.netbeans.modules.python.editor.scopes.ScopeInfo;
41.61 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
41.62 -import org.netbeans.modules.python.editor.scopes.SymInfo;
41.63 -import org.openide.util.NbBundle;
41.64 -import org.python.antlr.ast.Module;
41.65 -import org.python.antlr.ast.Str;
41.66 -
41.67 -/**
41.68 - *
41.69 - * @author Tor Norbye
41.70 - */
41.71 -public class AllAssignExists extends PythonAstRule {
41.72 - @Override
41.73 - public Set<Class> getKinds() {
41.74 - return Collections.<Class>singleton(Module.class);
41.75 - }
41.76 -
41.77 - @Override
41.78 - public void run(PythonRuleContext context, List<Hint> result) {
41.79 - PythonParserResult ppr = (PythonParserResult)context.parserResult;
41.80 - SymbolTable symbolTable = ppr.getSymbolTable();
41.81 - List<Str> publicSymbols = symbolTable.getPublicSymbols();
41.82 - if (publicSymbols != null) {
41.83 - // Check that we actually have all the symbols called for
41.84 - // by the all-list
41.85 -
41.86 - ScopeInfo topScope = symbolTable.getScopeInfo(context.node);
41.87 - assert topScope != null;
41.88 -
41.89 - // Mark all other symbols private!
41.90 - for (Str str : publicSymbols) {
41.91 - //String name = PythonAstUtils.getExprName(expr);
41.92 - String name = PythonAstUtils.getStrContent(str);
41.93 - if (name != null) {
41.94 - SymInfo sym = topScope.tbl.get(name);
41.95 - if (sym == null) {
41.96 - // Uh oh -- missing!
41.97 - PythonParserResult info = (PythonParserResult) context.parserResult;
41.98 - OffsetRange range = PythonAstUtils.getNameRange(info, str);
41.99 - range = PythonLexerUtils.getLexerOffsets(info, range);
41.100 - if (range != OffsetRange.NONE) {
41.101 - List<HintFix> fixList = Collections.emptyList();
41.102 - String message = NbBundle.getMessage(AllAssignExists.class, "AllAssignExistsMsg", name);
41.103 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 205);
41.104 - result.add(desc);
41.105 - }
41.106 - }
41.107 - }
41.108 - }
41.109 - }
41.110 - }
41.111 -
41.112 - @Override
41.113 - public String getId() {
41.114 - return "AllAssignExists"; // NOI18N
41.115 - }
41.116 -
41.117 - @Override
41.118 - public String getDescription() {
41.119 - return NbBundle.getMessage(AllAssignExists.class, "AllAssignExistsDesc");
41.120 - }
41.121 -
41.122 - @Override
41.123 - public boolean getDefaultEnabled() {
41.124 - return true;
41.125 - }
41.126 -
41.127 - @Override
41.128 - public JComponent getCustomizer(Preferences node) {
41.129 - return null;
41.130 - }
41.131 -
41.132 - @Override
41.133 - public boolean appliesTo(RuleContext context) {
41.134 - return true;
41.135 - }
41.136 -
41.137 - @Override
41.138 - public String getDisplayName() {
41.139 - return NbBundle.getMessage(AllAssignExists.class, "AllAssignExists");
41.140 - }
41.141 -
41.142 - @Override
41.143 - public boolean showInTasklist() {
41.144 - return true;
41.145 - }
41.146 -
41.147 - @Override
41.148 - public HintSeverity getDefaultSeverity() {
41.149 - return HintSeverity.ERROR;
41.150 - }
41.151 -}
42.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/AssignToVariable.java Fri Sep 18 16:20:24 2015 -0500
42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
42.3 @@ -1,245 +0,0 @@
42.4 -/*
42.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
42.6 - *
42.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
42.8 - *
42.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
42.10 - * Other names may be trademarks of their respective owners.
42.11 - *
42.12 - * The contents of this file are subject to the terms of either the GNU
42.13 - * General Public License Version 2 only ("GPL") or the Common
42.14 - * Development and Distribution License("CDDL") (collectively, the
42.15 - * "License"). You may not use this file except in compliance with the
42.16 - * License. You can obtain a copy of the License at
42.17 - * http://www.netbeans.org/cddl-gplv2.html
42.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
42.19 - * specific language governing permissions and limitations under the
42.20 - * License. When distributing the software, include this License Header
42.21 - * Notice in each file and include the License file at
42.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
42.23 - * particular file as subject to the "Classpath" exception as provided
42.24 - * by Oracle in the GPL Version 2 section of the License file that
42.25 - * accompanied this code. If applicable, add the following below the
42.26 - * License Header, with the fields enclosed by brackets [] replaced by
42.27 - * your own identifying information:
42.28 - * "Portions Copyrighted [year] [name of copyright owner]"
42.29 - *
42.30 - * If you wish your version of this file to be governed by only the CDDL
42.31 - * or only the GPL Version 2, indicate your decision by adding
42.32 - * "[Contributor] elects to include this software in this distribution
42.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
42.34 - * single choice of license, a recipient has the option to distribute
42.35 - * your version of this file under either the CDDL, the GPL Version 2 or
42.36 - * to extend the choice of license to its licensees as provided above.
42.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
42.38 - * Version 2 license, then the option applies only if the new code is
42.39 - * made subject to such option by the copyright holder.
42.40 - *
42.41 - * Contributor(s):
42.42 - *
42.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
42.44 - */
42.45 -package org.netbeans.modules.python.editor.hints;
42.46 -
42.47 -import java.util.ArrayList;
42.48 -import java.util.Collections;
42.49 -import java.util.List;
42.50 -import java.util.Set;
42.51 -import java.util.prefs.Preferences;
42.52 -import javax.swing.JComponent;
42.53 -import javax.swing.text.BadLocationException;
42.54 -import javax.swing.text.JTextComponent;
42.55 -import javax.swing.text.Position;
42.56 -import org.netbeans.modules.python.editor.PythonAstUtils;
42.57 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
42.58 -import org.netbeans.editor.BaseDocument;
42.59 -import org.netbeans.editor.Utilities;
42.60 -import org.netbeans.modules.csl.api.EditList;
42.61 -import org.netbeans.modules.csl.api.Hint;
42.62 -import org.netbeans.modules.csl.api.HintFix;
42.63 -import org.netbeans.modules.csl.api.HintSeverity;
42.64 -import org.netbeans.modules.csl.api.OffsetRange;
42.65 -import org.netbeans.modules.csl.api.PreviewableFix;
42.66 -import org.netbeans.modules.csl.api.RuleContext;
42.67 -import org.netbeans.modules.csl.spi.GsfUtilities;
42.68 -import org.netbeans.modules.python.editor.PythonParserResult;
42.69 -import org.openide.util.Exceptions;
42.70 -import org.openide.util.NbBundle;
42.71 -import org.python.antlr.PythonTree;
42.72 -import org.python.antlr.ast.Call;
42.73 -import org.python.antlr.ast.Expr;
42.74 -import org.python.antlr.ast.FunctionDef;
42.75 -import org.python.antlr.ast.Str;
42.76 -import org.python.antlr.base.expr;
42.77 -import org.python.antlr.base.stmt;
42.78 -
42.79 -/**
42.80 - * Assign an expression to a variable
42.81 - *
42.82 - * @author Tor Norbye
42.83 - */
42.84 -public class AssignToVariable extends PythonAstRule {
42.85 - @Override
42.86 - public Set<Class> getKinds() {
42.87 - return Collections.singleton((Class)Expr.class);
42.88 - }
42.89 -
42.90 - @Override
42.91 - public void run(PythonRuleContext context, List<Hint> result) {
42.92 - PythonTree node = context.node;
42.93 - Expr expr = (Expr)node;
42.94 - expr exprValue = expr.getInternalValue();
42.95 - if (exprValue instanceof Str) {
42.96 - // Skip triple-quoted strings (typically doc strings)
42.97 - Str str = (Str)exprValue;
42.98 - String s = str.getText();
42.99 - if (s.startsWith("'''") || s.startsWith("\"\"\"")) { // NOI18N
42.100 - return;
42.101 - }
42.102 - PythonTree grandParent = context.path.leafGrandParent();
42.103 - if (grandParent instanceof FunctionDef) {
42.104 - FunctionDef def = (FunctionDef)grandParent;
42.105 - List<stmt> body = def.getInternalBody();
42.106 - if (body != null && body.size() > 0 && body.get(0) == expr) {
42.107 - // First string in a function -- it's a docstring
42.108 - return;
42.109 - }
42.110 - }
42.111 - }
42.112 - if (exprValue instanceof Call) {
42.113 - // Skip calls - they may have side effects
42.114 - // ...unless it looks like a "getter" style Python method
42.115 - Call call = (Call)exprValue;
42.116 - if (!PythonAstUtils.isGetter(call, false)) {
42.117 - return;
42.118 - }
42.119 - }
42.120 - PythonParserResult info = (PythonParserResult) context.parserResult;
42.121 - OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
42.122 - OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
42.123 - BaseDocument doc = context.doc;
42.124 - try {
42.125 - if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
42.126 - (context.caretOffset == -1 ||
42.127 - Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
42.128 - List<HintFix> fixList = new ArrayList<>();
42.129 - fixList.add(new AssignToVariableFix(context, node));
42.130 - String displayName = getDisplayName();
42.131 - Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
42.132 - result.add(desc);
42.133 - }
42.134 - } catch (BadLocationException ex) {
42.135 - Exceptions.printStackTrace(ex);
42.136 - }
42.137 - }
42.138 -
42.139 - @Override
42.140 - public String getId() {
42.141 - return "AssignToVariable"; // NOI18N
42.142 - }
42.143 -
42.144 - @Override
42.145 - public String getDisplayName() {
42.146 - return NbBundle.getMessage(AssignToVariable.class, "AssignToVariable");
42.147 - }
42.148 -
42.149 - @Override
42.150 - public String getDescription() {
42.151 - return NbBundle.getMessage(AssignToVariable.class, "AssignToVariableDesc");
42.152 - }
42.153 -
42.154 - @Override
42.155 - public boolean getDefaultEnabled() {
42.156 - return true;
42.157 - }
42.158 -
42.159 - @Override
42.160 - public JComponent getCustomizer(Preferences node) {
42.161 - return null;
42.162 - }
42.163 -
42.164 - @Override
42.165 - public boolean appliesTo(RuleContext context) {
42.166 - return true;
42.167 - }
42.168 -
42.169 - @Override
42.170 - public boolean showInTasklist() {
42.171 - return false;
42.172 - }
42.173 -
42.174 - @Override
42.175 - public HintSeverity getDefaultSeverity() {
42.176 - return HintSeverity.CURRENT_LINE_WARNING;
42.177 - }
42.178 -
42.179 - private static class AssignToVariableFix implements PreviewableFix {
42.180 - private final PythonRuleContext context;
42.181 - private final PythonTree node;
42.182 - private int varOffset;
42.183 - private String varName;
42.184 -
42.185 - private AssignToVariableFix(PythonRuleContext context, PythonTree node) {
42.186 - this.context = context;
42.187 - this.node = node;
42.188 - }
42.189 -
42.190 - @Override
42.191 - public String getDescription() {
42.192 - return NbBundle.getMessage(AssignToVariable.class, "AssignToVariableFix");
42.193 - }
42.194 -
42.195 - @Override
42.196 - public boolean canPreview() {
42.197 - return true;
42.198 - }
42.199 -
42.200 - @Override
42.201 - public EditList getEditList() throws Exception {
42.202 - BaseDocument doc = context.doc;
42.203 - EditList edits = new EditList(doc);
42.204 -
42.205 - OffsetRange astRange = PythonAstUtils.getRange(node);
42.206 - if (astRange != OffsetRange.NONE) {
42.207 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
42.208 - if (lexRange != OffsetRange.NONE) {
42.209 - int offset = lexRange.getStart();
42.210 - StringBuilder sb = new StringBuilder();
42.211 - varName = NbBundle.getMessage(AssignToVariable.class, "VarName");
42.212 - sb.append(varName);
42.213 - sb.append(" = "); // NOI18N
42.214 - varOffset = offset;
42.215 - edits.replace(offset, 0, sb.toString(), false, 0);
42.216 - }
42.217 - }
42.218 -
42.219 - return edits;
42.220 - }
42.221 -
42.222 - @Override
42.223 - public void implement() throws Exception {
42.224 - EditList edits = getEditList();
42.225 -
42.226 - Position pos = edits.createPosition(varOffset);
42.227 - edits.apply();
42.228 - if (pos != null && pos.getOffset() != -1) {
42.229 - JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
42.230 - if (target != null) {
42.231 - int start = pos.getOffset();
42.232 - int end = start + varName.length();
42.233 - target.select(start, end);
42.234 - }
42.235 - }
42.236 - }
42.237 -
42.238 - @Override
42.239 - public boolean isSafe() {
42.240 - return true;
42.241 - }
42.242 -
42.243 - @Override
42.244 - public boolean isInteractive() {
42.245 - return false;
42.246 - }
42.247 - }
42.248 -}
43.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/AttributeDefinedOutsideInit.java Fri Sep 18 16:20:24 2015 -0500
43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
43.3 @@ -1,140 +0,0 @@
43.4 -/*
43.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
43.6 - *
43.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
43.8 - *
43.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
43.10 - * Other names may be trademarks of their respective owners.
43.11 - *
43.12 - * The contents of this file are subject to the terms of either the GNU
43.13 - * General Public License Version 2 only ("GPL") or the Common
43.14 - * Development and Distribution License("CDDL") (collectively, the
43.15 - * "License"). You may not use this file except in compliance with the
43.16 - * License. You can obtain a copy of the License at
43.17 - * http://www.netbeans.org/cddl-gplv2.html
43.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
43.19 - * specific language governing permissions and limitations under the
43.20 - * License. When distributing the software, include this License Header
43.21 - * Notice in each file and include the License file at
43.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
43.23 - * particular file as subject to the "Classpath" exception as provided
43.24 - * by Oracle in the GPL Version 2 section of the License file that
43.25 - * accompanied this code. If applicable, add the following below the
43.26 - * License Header, with the fields enclosed by brackets [] replaced by
43.27 - * your own identifying information:
43.28 - * "Portions Copyrighted [year] [name of copyright owner]"
43.29 - *
43.30 - * If you wish your version of this file to be governed by only the CDDL
43.31 - * or only the GPL Version 2, indicate your decision by adding
43.32 - * "[Contributor] elects to include this software in this distribution
43.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
43.34 - * single choice of license, a recipient has the option to distribute
43.35 - * your version of this file under either the CDDL, the GPL Version 2 or
43.36 - * to extend the choice of license to its licensees as provided above.
43.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
43.38 - * Version 2 license, then the option applies only if the new code is
43.39 - * made subject to such option by the copyright holder.
43.40 - *
43.41 - * Contributor(s):
43.42 - *
43.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
43.44 - */
43.45 -package org.netbeans.modules.python.editor.hints;
43.46 -
43.47 -import java.util.Collections;
43.48 -import java.util.List;
43.49 -import java.util.Set;
43.50 -import java.util.prefs.Preferences;
43.51 -import javax.swing.JComponent;
43.52 -import org.netbeans.modules.csl.api.Hint;
43.53 -import org.netbeans.modules.csl.api.HintFix;
43.54 -import org.netbeans.modules.csl.api.HintSeverity;
43.55 -import org.netbeans.modules.csl.api.OffsetRange;
43.56 -import org.netbeans.modules.csl.api.RuleContext;
43.57 -import org.netbeans.modules.python.editor.PythonAstUtils;
43.58 -import org.netbeans.modules.python.editor.PythonParserResult;
43.59 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
43.60 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
43.61 -import org.openide.util.NbBundle;
43.62 -import org.python.antlr.ast.Attribute;
43.63 -import org.python.antlr.ast.Module;
43.64 -
43.65 -/**
43.66 - *
43.67 - * @author Jean-Yves Mengant
43.68 - */
43.69 -public class AttributeDefinedOutsideInit extends PythonAstRule {
43.70 - private final static String ATTRIBUTE_DEFINED_OUTSIDE_INIT = "AttributeDefinedOutsideInit";
43.71 - private final static String ATTRIBUTE_DEFINED_OUTSITE_INIT_VAR = "AttributeDefinedOutsideInitVariable";
43.72 - private final static String ATTRIBUTE_DEFINED_OUTSIDE_INIT_DESC = "AttributeDefinedOutsideInitDesc";
43.73 -
43.74 - @Override
43.75 - public Set<Class> getKinds() {
43.76 - return Collections.<Class>singleton(Module.class);
43.77 - }
43.78 -
43.79 - @Override
43.80 - public void run(PythonRuleContext context, List<Hint> result) {
43.81 - PythonParserResult info = (PythonParserResult) context.parserResult;
43.82 - PythonParserResult pr = PythonAstUtils.getParseResult(info);
43.83 - SymbolTable symbolTable = pr.getSymbolTable();
43.84 -
43.85 -
43.86 - List<Attribute> notInIntBound = symbolTable.getNotInInitAttributes(info);
43.87 - if (notInIntBound.size() > 0) {
43.88 - for (Attribute cur : notInIntBound) {
43.89 - OffsetRange range = PythonAstUtils.getRange(cur);
43.90 - range = PythonLexerUtils.getLexerOffsets(info, range);
43.91 - if (range != OffsetRange.NONE) {
43.92 - List<HintFix> fixList = Collections.emptyList();
43.93 - String message = NbBundle.getMessage(NameRule.class,
43.94 - ATTRIBUTE_DEFINED_OUTSITE_INIT_VAR,
43.95 - cur.getInternalAttr());
43.96 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
43.97 - result.add(desc);
43.98 - }
43.99 - }
43.100 - }
43.101 -
43.102 - }
43.103 -
43.104 - @Override
43.105 - public String getId() {
43.106 - return ATTRIBUTE_DEFINED_OUTSIDE_INIT;
43.107 - }
43.108 -
43.109 - @Override
43.110 - public String getDescription() {
43.111 - return NbBundle.getMessage(RelativeImports.class, ATTRIBUTE_DEFINED_OUTSIDE_INIT_DESC);
43.112 - }
43.113 -
43.114 - @Override
43.115 - public boolean getDefaultEnabled() {
43.116 - return false;
43.117 - }
43.118 -
43.119 - @Override
43.120 - public JComponent getCustomizer(Preferences node) {
43.121 - return null;
43.122 - }
43.123 -
43.124 - @Override
43.125 - public boolean appliesTo(RuleContext context) {
43.126 - return true;
43.127 - }
43.128 -
43.129 - @Override
43.130 - public String getDisplayName() {
43.131 - return NbBundle.getMessage(AccessToProtected.class, ATTRIBUTE_DEFINED_OUTSIDE_INIT);
43.132 - }
43.133 -
43.134 - @Override
43.135 - public boolean showInTasklist() {
43.136 - return true;
43.137 - }
43.138 -
43.139 - @Override
43.140 - public HintSeverity getDefaultSeverity() {
43.141 - return HintSeverity.WARNING;
43.142 - }
43.143 -}
44.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/Bundle.properties Fri Sep 18 16:20:24 2015 -0500
44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
44.3 @@ -1,146 +0,0 @@
44.4 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
44.5 -#
44.6 -# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
44.7 -#
44.8 -# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
44.9 -# Other names may be trademarks of their respective owners.
44.10 -#
44.11 -# The contents of this file are subject to the terms of either the GNU
44.12 -# General Public License Version 2 only ("GPL") or the Common
44.13 -# Development and Distribution License("CDDL") (collectively, the
44.14 -# "License"). You may not use this file except in compliance with the
44.15 -# License. You can obtain a copy of the License at
44.16 -# http://www.netbeans.org/cddl-gplv2.html
44.17 -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
44.18 -# specific language governing permissions and limitations under the
44.19 -# License. When distributing the software, include this License Header
44.20 -# Notice in each file and include the License file at
44.21 -# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
44.22 -# particular file as subject to the "Classpath" exception as provided
44.23 -# by Oracle in the GPL Version 2 section of the License file that
44.24 -# accompanied this code. If applicable, add the following below the
44.25 -# License Header, with the fields enclosed by brackets [] replaced by
44.26 -# your own identifying information:
44.27 -# "Portions Copyrighted [year] [name of copyright owner]"
44.28 -#
44.29 -# Contributor(s):
44.30 -#
44.31 -# The Original Software is NetBeans. The Initial Developer of the Original
44.32 -# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
44.33 -# Microsystems, Inc. All Rights Reserved.
44.34 -#
44.35 -# If you wish your version of this file to be governed by only the CDDL
44.36 -# or only the GPL Version 2, indicate your decision by adding
44.37 -# "[Contributor] elects to include this software in this distribution
44.38 -# under the [CDDL or GPL Version 2] license." If you do not indicate a
44.39 -# single choice of license, a recipient has the option to distribute
44.40 -# your version of this file under either the CDDL, the GPL Version 2 or
44.41 -# to extend the choice of license to its licensees as provided above.
44.42 -# However, if you add GPL Version 2 code and therefore, elected the GPL
44.43 -# Version 2 license, then the option applies only if the new code is
44.44 -# made subject to such option by the copyright holder.
44.45 -
44.46 -# Category descriptions in the Options Panel
44.47 -gsf-hints/text/x-python/hints/general=General
44.48 -
44.49 -# NameRule
44.50 -NameRule=Naming Conventions
44.51 -NameRuleDesc=Check class, function and variable names for style guide compliance (see http://www.python.org/dev/peps/pep-0008/ for rules)
44.52 -NameRuleWrongNoArg=First argument should be 'self' or 'cls'
44.53 -NameRuleWrongArg=First argument ({0}) should be 'self' or 'cls'
44.54 -WrongStyle=Name "{0}" is not a valid {1} name according to your code style ({2})
44.55 -Module=module
44.56 -Function=function
44.57 -Class=class
44.58 -Variable=variable
44.59 -ChangeStyle=Change preferred {0} name style to {1}
44.60 -ChangeNoStyle=Turn off {0} name style checks
44.61 -IgnoreWord=Ignore name violations for "{0}"
44.62 -NameRulePrefs.selfCb.text=First method params should be "self" or "cls"
44.63 -NameRulePrefs.moduleLabel.text=Modules:
44.64 -NameRulePrefs.classLabel.text=Classes:
44.65 -NameRulePrefs.functionLabel.text=Functions:
44.66 -NameRulePrefs.parameterLabel.text=Parameters:
44.67 -NameRulePrefs.variableLabel.text=Variables:
44.68 -NoPreference=No Preference
44.69 -NameRulePrefs.ignoreLabel.text=Ignored:
44.70 -
44.71 -CreateDocString=Create document comment
44.72 -CreateDocStringDesc=Offer to create a documentation comment for the current function, class or module
44.73 -CreateDocStringFix=Add a one-liner docstring
44.74 -CreateDocStringFixMulti=Add a multi-line docstring
44.75 -
44.76 -AssignToVariable=Assign expression to a variable
44.77 -AssignToVariableDesc=Assign expression under the caret to a variable
44.78 -AssignToVariableFix=Assign expression to a variable
44.79 -VarName=name
44.80 -
44.81 -SplitImports=Multiple imports per import statement is discouraged
44.82 -SplitImportsDesc=Split an import which imports multiple modules into individual import statements as recommended by the Python styleguide
44.83 -SplitImportsFix=Split import into individual import statements
44.84 -
44.85 -RelativeImports=Relative imports for intra-package imports are actively discouraged (as per PEP-008)
44.86 -RelativeImportsDesc=Relative imports for intra-package imports are actively discouraged (as per PEP-008) and this rule warns about usages of relative imports
44.87 -RelativeImportsFix=Replace with absolute import
44.88 -
44.89 -Deprecations=Deprecated
44.90 -DeprecationsMsg={0} is deprecated
44.91 -DeprecationsMsgDetail={0} is deprecated. {1}
44.92 -DeprecationsDesc=Check for deprecated modules
44.93 -
44.94 -SurroundWith=Surround With...
44.95 -#SurroundWithDesc=Offer to surround selected code with try/catch, etc
44.96 -SurroundWithTE=Surround With Try/Except
44.97 -SurroundWithTEF=Surround With Try/Except/Finally
44.98 -SurroundWithTF=Surround With Try/Finally
44.99 -InsertSelf=Insert a new first parameter "self"
44.100 -RenameSelf=Rename first parameter "{0}" to self
44.101 -
44.102 -ExtractCode=Extract Code
44.103 -IntroduceMethod=Extract Method
44.104 -IntroduceVariable=Introduce Variable
44.105 -IntroduceConstant=Introduce Constant
44.106 -IntroduceField=Introduce Field
44.107 -
44.108 -UnusedImport=Unused Import
44.109 -UnusedImportSymbols=Some symbols are unused ({0})
44.110 -UnusedImports=Find Unused Imports
44.111 -UnusedImportsDesc=Find imports that aren't used in this module and can be removed
44.112 -UnusedFix=Remove Unused Import
44.113 -UnusedFixSymbols=Remove {0} from import
44.114 -OrganizeImports=Clean up and Organize Imports
44.115 -DeleteAllUnused=Remove All Unused Imports
44.116 -
44.117 -Unused=Find Unused Variables
44.118 -UnusedDesc=Find variables that are defined but never used
44.119 -UnusedVariable=Unused Variable {0}
44.120 -
44.121 -Unresolved=Find Undefined Names
44.122 -UnresolvedDesc=Find names that are used but have not been bound
44.123 -UnresolvedVariable=Undefined name "{0}"
44.124 -UnresolvedVariableMaybe=Undefined name "{0}" - did you mean "{1}" ?
44.125 -FixImport=Import {0}
44.126 -
44.127 -UnresolvedAttributes=Find Unresolved classes attributes and parentages
44.128 -UnresolvedAttributesDesc=Find class attributes that are used but have not been bound and undefined inherited classes
44.129 -UnresolvedAttributesVariable=Undefined attribute "{0}"
44.130 -UnresolvedInheritanceVariable=Inheriting from undefined parent class "{0}"
44.131 -
44.132 -AccessProtected=Access Protected Attributes
44.133 -AccessProtectedDesc=Find access to protected variables/methods of non parent classes
44.134 -AccessProtectedVariable=Access to protected variable "{0}"
44.135 -
44.136 -AttributeDefinedOutsideInit=Attribute Defined Outside __init__
44.137 -AttributeDefinedOutsideInitDesc=Class Attribute defined outside __init__ constructor
44.138 -AttributeDefinedOutsideInitVariable=Attribute Defined Outside __init__ "{0}"
44.139 -
44.140 -ClassCircularRedundancy=Parent Child circular redundancy
44.141 -ClassCircularRedundancyDesc=Parent Child circular redundancy = A inherits B and B inherits A
44.142 -ClassCircularRedundancyVariable=Parent/child {0} inheritance circular redundancy
44.143 -
44.144 -AllAssignExists=Symbol defined in __all__ does not exist
44.145 -AllAssignExistsDesc=Checks that all symbols listed in __all__ actually exist
44.146 -AllAssignExistsMsg="{0}" defined in __all__ does not exist!
44.147 -UnusedDetectorPrefs.skipParams.text=Ignore unused function parameters
44.148 -UnusedDetectorPrefs.ignoredLabel.text=Ignored names:
44.149 -UnusedDetectorPrefs.skipTupleAssignments.text=Ignore unused variables in tuple-assignments
45.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/ClassCircularRedundancy.java Fri Sep 18 16:20:24 2015 -0500
45.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
45.3 @@ -1,140 +0,0 @@
45.4 -/*
45.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
45.6 - *
45.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
45.8 - *
45.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
45.10 - * Other names may be trademarks of their respective owners.
45.11 - *
45.12 - * The contents of this file are subject to the terms of either the GNU
45.13 - * General Public License Version 2 only ("GPL") or the Common
45.14 - * Development and Distribution License("CDDL") (collectively, the
45.15 - * "License"). You may not use this file except in compliance with the
45.16 - * License. You can obtain a copy of the License at
45.17 - * http://www.netbeans.org/cddl-gplv2.html
45.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
45.19 - * specific language governing permissions and limitations under the
45.20 - * License. When distributing the software, include this License Header
45.21 - * Notice in each file and include the License file at
45.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
45.23 - * particular file as subject to the "Classpath" exception as provided
45.24 - * by Oracle in the GPL Version 2 section of the License file that
45.25 - * accompanied this code. If applicable, add the following below the
45.26 - * License Header, with the fields enclosed by brackets [] replaced by
45.27 - * your own identifying information:
45.28 - * "Portions Copyrighted [year] [name of copyright owner]"
45.29 - *
45.30 - * If you wish your version of this file to be governed by only the CDDL
45.31 - * or only the GPL Version 2, indicate your decision by adding
45.32 - * "[Contributor] elects to include this software in this distribution
45.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
45.34 - * single choice of license, a recipient has the option to distribute
45.35 - * your version of this file under either the CDDL, the GPL Version 2 or
45.36 - * to extend the choice of license to its licensees as provided above.
45.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
45.38 - * Version 2 license, then the option applies only if the new code is
45.39 - * made subject to such option by the copyright holder.
45.40 - *
45.41 - * Contributor(s):
45.42 - *
45.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
45.44 - */
45.45 -package org.netbeans.modules.python.editor.hints;
45.46 -
45.47 -import java.util.Collections;
45.48 -import java.util.HashMap;
45.49 -import java.util.List;
45.50 -import java.util.Map.Entry;
45.51 -import java.util.Set;
45.52 -import java.util.prefs.Preferences;
45.53 -import javax.swing.JComponent;
45.54 -import org.netbeans.modules.csl.api.Hint;
45.55 -import org.netbeans.modules.csl.api.HintFix;
45.56 -import org.netbeans.modules.csl.api.HintSeverity;
45.57 -import org.netbeans.modules.csl.api.OffsetRange;
45.58 -import org.netbeans.modules.csl.api.RuleContext;
45.59 -import org.netbeans.modules.python.editor.PythonAstUtils;
45.60 -import org.netbeans.modules.python.editor.PythonParserResult;
45.61 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
45.62 -import org.openide.util.NbBundle;
45.63 -import org.python.antlr.ast.ClassDef;
45.64 -import org.python.antlr.ast.Module;
45.65 -
45.66 -/**
45.67 - * check for redundancy cycling in parent child
45.68 - * @author Jean-Yves Mengant
45.69 - */
45.70 -public class ClassCircularRedundancy extends PythonAstRule {
45.71 - private final static String CLASS_CIRCULAR_REDUNDANCY = "ClassCircularRedundancy";
45.72 - private final static String CLASS_CIRCULAR_REDUNDANCY_VAR = "ClassCircularRedundancyVariable";
45.73 - private final static String CLASS_CIRCULAR_REDUNDANCY_DESC = "ClassCircularRedundancyDesc";
45.74 -
45.75 - @Override
45.76 - public Set<Class> getKinds() {
45.77 - return Collections.<Class>singleton(Module.class);
45.78 - }
45.79 -
45.80 - @Override
45.81 - public void run(PythonRuleContext context, List<Hint> result) {
45.82 - PythonParserResult info = (PythonParserResult) context.parserResult;
45.83 - SymbolTable symbolTable = info.getSymbolTable();
45.84 -
45.85 -
45.86 - HashMap<ClassDef, String> cyclingRedundancies = symbolTable.getClassesCyclingRedundancies(info);
45.87 - if (cyclingRedundancies.size() > 0) {
45.88 - Set<Entry<ClassDef, String>> wk = cyclingRedundancies.entrySet();
45.89 - for (Entry<ClassDef, String> cur : wk) {
45.90 - ClassDef curClass = cur.getKey();
45.91 - String curCyclingMsg = curClass.getInternalName() + "/" + cur.getValue(); // NOI18N
45.92 - OffsetRange range = PythonAstUtils.getNameRange(info, curClass);
45.93 - // range = PythonLexerUtils.getLexerOffsets(info, range);
45.94 - if (range != OffsetRange.NONE) {
45.95 - List<HintFix> fixList = Collections.emptyList();
45.96 - String message = NbBundle.getMessage(NameRule.class, CLASS_CIRCULAR_REDUNDANCY_VAR, curCyclingMsg);
45.97 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
45.98 - result.add(desc);
45.99 - }
45.100 - }
45.101 - }
45.102 - }
45.103 -
45.104 - @Override
45.105 - public String getId() {
45.106 - return CLASS_CIRCULAR_REDUNDANCY;
45.107 - }
45.108 -
45.109 - @Override
45.110 - public String getDescription() {
45.111 - return NbBundle.getMessage(RelativeImports.class, CLASS_CIRCULAR_REDUNDANCY_DESC);
45.112 - }
45.113 -
45.114 - @Override
45.115 - public boolean getDefaultEnabled() {
45.116 - return false;
45.117 - }
45.118 -
45.119 - @Override
45.120 - public JComponent getCustomizer(Preferences node) {
45.121 - return null;
45.122 - }
45.123 -
45.124 - @Override
45.125 - public boolean appliesTo(RuleContext context) {
45.126 - return true;
45.127 - }
45.128 -
45.129 - @Override
45.130 - public String getDisplayName() {
45.131 - return NbBundle.getMessage(AccessToProtected.class, CLASS_CIRCULAR_REDUNDANCY);
45.132 - }
45.133 -
45.134 - @Override
45.135 - public boolean showInTasklist() {
45.136 - return true;
45.137 - }
45.138 -
45.139 - @Override
45.140 - public HintSeverity getDefaultSeverity() {
45.141 - return HintSeverity.ERROR;
45.142 - }
45.143 -}
46.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/CreateDocString.java Fri Sep 18 16:20:24 2015 -0500
46.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
46.3 @@ -1,241 +0,0 @@
46.4 -/*
46.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
46.6 - *
46.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
46.8 - *
46.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
46.10 - * Other names may be trademarks of their respective owners.
46.11 - *
46.12 - * The contents of this file are subject to the terms of either the GNU
46.13 - * General Public License Version 2 only ("GPL") or the Common
46.14 - * Development and Distribution License("CDDL") (collectively, the
46.15 - * "License"). You may not use this file except in compliance with the
46.16 - * License. You can obtain a copy of the License at
46.17 - * http://www.netbeans.org/cddl-gplv2.html
46.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
46.19 - * specific language governing permissions and limitations under the
46.20 - * License. When distributing the software, include this License Header
46.21 - * Notice in each file and include the License file at
46.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
46.23 - * particular file as subject to the "Classpath" exception as provided
46.24 - * by Oracle in the GPL Version 2 section of the License file that
46.25 - * accompanied this code. If applicable, add the following below the
46.26 - * License Header, with the fields enclosed by brackets [] replaced by
46.27 - * your own identifying information:
46.28 - * "Portions Copyrighted [year] [name of copyright owner]"
46.29 - *
46.30 - * Contributor(s):
46.31 - *
46.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
46.33 - */
46.34 -package org.netbeans.modules.python.editor.hints;
46.35 -
46.36 -import java.util.ArrayList;
46.37 -import java.util.Collections;
46.38 -import java.util.HashSet;
46.39 -import java.util.List;
46.40 -import java.util.Set;
46.41 -import java.util.prefs.Preferences;
46.42 -import javax.swing.JComponent;
46.43 -import javax.swing.text.BadLocationException;
46.44 -import javax.swing.text.JTextComponent;
46.45 -import javax.swing.text.Position;
46.46 -import org.netbeans.modules.python.editor.PythonAstUtils;
46.47 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
46.48 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
46.49 -import org.netbeans.api.lexer.Token;
46.50 -import org.netbeans.api.lexer.TokenSequence;
46.51 -import org.netbeans.editor.BaseDocument;
46.52 -import org.netbeans.editor.Utilities;
46.53 -import org.netbeans.modules.csl.api.EditList;
46.54 -import org.netbeans.modules.csl.api.Hint;
46.55 -import org.netbeans.modules.csl.api.HintFix;
46.56 -import org.netbeans.modules.csl.api.HintSeverity;
46.57 -import org.netbeans.modules.csl.api.OffsetRange;
46.58 -import org.netbeans.modules.csl.api.PreviewableFix;
46.59 -import org.netbeans.modules.csl.api.RuleContext;
46.60 -import org.netbeans.modules.csl.spi.GsfUtilities;
46.61 -import org.netbeans.modules.editor.indent.api.IndentUtils;
46.62 -import org.netbeans.modules.python.editor.PythonParserResult;
46.63 -import org.openide.util.Exceptions;
46.64 -import org.openide.util.NbBundle;
46.65 -import org.python.antlr.PythonTree;
46.66 -import org.python.antlr.ast.ClassDef;
46.67 -import org.python.antlr.ast.FunctionDef;
46.68 -
46.69 -/**
46.70 - * Offer to create docstrings.
46.71 - * @todo Handle modules?
46.72 - * @todo Handle parameter tags (for epydoc etc)
46.73 - *
46.74 - * @author Tor Norbye
46.75 - */
46.76 -public class CreateDocString extends PythonAstRule {
46.77 - @Override
46.78 - public Set<Class> getKinds() {
46.79 - Set<Class> classes = new HashSet<>();
46.80 - classes.add(FunctionDef.class);
46.81 - classes.add(ClassDef.class);
46.82 -
46.83 - return classes;
46.84 - }
46.85 -
46.86 - @Override
46.87 - public void run(PythonRuleContext context, List<Hint> result) {
46.88 -
46.89 - PythonTree node = context.node;
46.90 - if (PythonAstUtils.getDocumentationNode(node) != null) {
46.91 - return;
46.92 - }
46.93 -
46.94 - // Create new fix
46.95 - PythonParserResult info = (PythonParserResult) context.parserResult;
46.96 - OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
46.97 - OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
46.98 - BaseDocument doc = context.doc;
46.99 - try {
46.100 - if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
46.101 - (context.caretOffset == -1 ||
46.102 - Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
46.103 - List<HintFix> fixList = new ArrayList<>();
46.104 - boolean singleIsDefault = node.getClass() == FunctionDef.class;
46.105 - fixList.add(new CreateDocStringFix(context, node, !singleIsDefault));
46.106 - fixList.add(new CreateDocStringFix(context, node, singleIsDefault));
46.107 - String displayName = getDisplayName();
46.108 - Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
46.109 - result.add(desc);
46.110 - }
46.111 - } catch (BadLocationException ex) {
46.112 - Exceptions.printStackTrace(ex);
46.113 - }
46.114 - }
46.115 -
46.116 - @Override
46.117 - public String getId() {
46.118 - return "CreateDocString"; // NOI18N
46.119 - }
46.120 -
46.121 - @Override
46.122 - public String getDisplayName() {
46.123 - return NbBundle.getMessage(CreateDocString.class, "CreateDocString");
46.124 - }
46.125 -
46.126 - @Override
46.127 - public String getDescription() {
46.128 - return NbBundle.getMessage(CreateDocString.class, "CreateDocStringDesc");
46.129 - }
46.130 -
46.131 - @Override
46.132 - public boolean getDefaultEnabled() {
46.133 - return true;
46.134 - }
46.135 -
46.136 - @Override
46.137 - public JComponent getCustomizer(Preferences node) {
46.138 - return null;
46.139 - }
46.140 -
46.141 - @Override
46.142 - public boolean appliesTo(RuleContext context) {
46.143 - return true;
46.144 - }
46.145 -
46.146 - @Override
46.147 - public boolean showInTasklist() {
46.148 - return false;
46.149 - }
46.150 -
46.151 - @Override
46.152 - public HintSeverity getDefaultSeverity() {
46.153 - return HintSeverity.CURRENT_LINE_WARNING;
46.154 - }
46.155 -
46.156 - private static class CreateDocStringFix implements PreviewableFix {
46.157 - private final PythonRuleContext context;
46.158 - private final PythonTree node;
46.159 - private final boolean multiLine;
46.160 - private int editListPosition;
46.161 -
46.162 - private CreateDocStringFix(PythonRuleContext context, PythonTree node, boolean multiLine) {
46.163 - this.context = context;
46.164 - this.node = node;
46.165 - this.multiLine = multiLine;
46.166 - }
46.167 -
46.168 - @Override
46.169 - public String getDescription() {
46.170 - return multiLine ? NbBundle.getMessage(CreateDocString.class, "CreateDocStringFixMulti") : NbBundle.getMessage(CreateDocString.class, "CreateDocStringFix");
46.171 - }
46.172 -
46.173 - @Override
46.174 - public boolean canPreview() {
46.175 - return true;
46.176 - }
46.177 -
46.178 - @Override
46.179 - public EditList getEditList() throws Exception {
46.180 - BaseDocument doc = context.doc;
46.181 - EditList edits = new EditList(doc);
46.182 -
46.183 - OffsetRange astRange = PythonAstUtils.getRange(node);
46.184 - if (astRange != OffsetRange.NONE) {
46.185 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
46.186 - if (lexRange != OffsetRange.NONE) {
46.187 - // Find the colon
46.188 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPositionedSequence(doc, lexRange.getStart());
46.189 - if (ts != null) {
46.190 - Token<? extends PythonTokenId> token = PythonLexerUtils.findNextIncluding(ts, Collections.singletonList(PythonTokenId.COLON));
46.191 - if (token != null) {
46.192 - int offset = ts.offset();
46.193 - if (offset < lexRange.getEnd()) {
46.194 - int indent = GsfUtilities.getLineIndent(doc, lexRange.getStart()) +
46.195 - IndentUtils.indentLevelSize(doc);
46.196 - StringBuilder sb = new StringBuilder();
46.197 - sb.append(IndentUtils.createIndentString(doc, indent));
46.198 - int rowEnd = Utilities.getRowEnd(doc, offset) + 1;
46.199 - sb.append("\"\"\""); // NOI18N
46.200 - if (multiLine) {
46.201 - sb.append("\n"); // NOI18N
46.202 - sb.append(IndentUtils.createIndentString(doc, indent));
46.203 - }
46.204 - editListPosition = rowEnd + sb.length();
46.205 - if (multiLine) {
46.206 - sb.append("\n"); // NOI18N
46.207 - sb.append(IndentUtils.createIndentString(doc, indent));
46.208 - }
46.209 - sb.append("\"\"\"\n"); // NOI18N
46.210 - edits.replace(rowEnd, 0, sb.toString(), false, 0);
46.211 - }
46.212 - }
46.213 - }
46.214 - }
46.215 - }
46.216 -
46.217 - return edits;
46.218 - }
46.219 -
46.220 - @Override
46.221 - public void implement() throws Exception {
46.222 - EditList edits = getEditList();
46.223 -
46.224 - Position pos = edits.createPosition(editListPosition);
46.225 - edits.apply();
46.226 - if (pos != null && pos.getOffset() != -1) {
46.227 - JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
46.228 - if (target != null) {
46.229 - target.setCaretPosition(pos.getOffset());
46.230 - }
46.231 - }
46.232 - }
46.233 -
46.234 - @Override
46.235 - public boolean isSafe() {
46.236 - return true;
46.237 - }
46.238 -
46.239 - @Override
46.240 - public boolean isInteractive() {
46.241 - return false;
46.242 - }
46.243 - }
46.244 -}
47.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/Deprecations.java Fri Sep 18 16:20:24 2015 -0500
47.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
47.3 @@ -1,293 +0,0 @@
47.4 -/*
47.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
47.6 - *
47.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
47.8 - *
47.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
47.10 - * Other names may be trademarks of their respective owners.
47.11 - *
47.12 - * The contents of this file are subject to the terms of either the GNU
47.13 - * General Public License Version 2 only ("GPL") or the Common
47.14 - * Development and Distribution License("CDDL") (collectively, the
47.15 - * "License"). You may not use this file except in compliance with the
47.16 - * License. You can obtain a copy of the License at
47.17 - * http://www.netbeans.org/cddl-gplv2.html
47.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
47.19 - * specific language governing permissions and limitations under the
47.20 - * License. When distributing the software, include this License Header
47.21 - * Notice in each file and include the License file at
47.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
47.23 - * particular file as subject to the "Classpath" exception as provided
47.24 - * by Oracle in the GPL Version 2 section of the License file that
47.25 - * accompanied this code. If applicable, add the following below the
47.26 - * License Header, with the fields enclosed by brackets [] replaced by
47.27 - * your own identifying information:
47.28 - * "Portions Copyrighted [year] [name of copyright owner]"
47.29 - *
47.30 - * If you wish your version of this file to be governed by only the CDDL
47.31 - * or only the GPL Version 2, indicate your decision by adding
47.32 - * "[Contributor] elects to include this software in this distribution
47.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
47.34 - * single choice of license, a recipient has the option to distribute
47.35 - * your version of this file under either the CDDL, the GPL Version 2 or
47.36 - * to extend the choice of license to its licensees as provided above.
47.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
47.38 - * Version 2 license, then the option applies only if the new code is
47.39 - * made subject to such option by the copyright holder.
47.40 - *
47.41 - * Contributor(s):
47.42 - *
47.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
47.44 - */
47.45 -package org.netbeans.modules.python.editor.hints;
47.46 -
47.47 -import java.util.Collections;
47.48 -import java.util.HashMap;
47.49 -import java.util.HashSet;
47.50 -import java.util.List;
47.51 -import java.util.Map;
47.52 -import java.util.Set;
47.53 -import java.util.prefs.Preferences;
47.54 -import javax.swing.JComponent;
47.55 -import javax.swing.text.BadLocationException;
47.56 -import org.netbeans.modules.python.editor.PythonAstUtils;
47.57 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
47.58 -import org.netbeans.editor.BaseDocument;
47.59 -import org.netbeans.editor.Utilities;
47.60 -import org.netbeans.modules.csl.api.Hint;
47.61 -import org.netbeans.modules.csl.api.HintFix;
47.62 -import org.netbeans.modules.csl.api.HintSeverity;
47.63 -import org.netbeans.modules.csl.api.OffsetRange;
47.64 -import org.netbeans.modules.csl.api.RuleContext;
47.65 -import org.netbeans.modules.python.editor.PythonParserResult;
47.66 -import org.openide.util.Exceptions;
47.67 -import org.openide.util.NbBundle;
47.68 -import org.python.antlr.PythonTree;
47.69 -import org.python.antlr.ast.Import;
47.70 -import org.python.antlr.ast.ImportFrom;
47.71 -import org.python.antlr.ast.alias;
47.72 -
47.73 -/**
47.74 - * Handle deprecaton warnings, for modules listed as obsolete or
47.75 - * deprecated in PEP4:
47.76 - * http://www.python.org/dev/peps/pep-0004/
47.77 - *
47.78 - * Todo: Add a hint to enforce this from PEP8:
47.79 -- Comparisons to singletons like None should always be done with
47.80 -'is' or 'is not', never the equality operators.
47.81 - * In general, see the "Programming Recommendations" list from
47.82 - * http://www.python.org/dev/peps/pep-0008/ - there are lots
47.83 - * of thins to check from there. Check the PyLint list as well.
47.84 - *
47.85 - *
47.86 - * @author Tor Norbye
47.87 - */
47.88 -public class Deprecations extends PythonAstRule {
47.89 - private static final Map<String, String> deprecated = new HashMap<>();
47.90 -
47.91 -
47.92 - static {
47.93 - for (String module : new String[]{"cl", "sv", "timing"}) {
47.94 - deprecated.put(module, "Listed as obsolete in the library documentation");
47.95 - }
47.96 -
47.97 - for (String module : new String[]{
47.98 - "addpack", "cmp", "cmpcache", "codehack", "dircmp", "dump", "find", "fmt",
47.99 - "grep", "lockfile", "newdir", "ni", "packmail", "Para", "poly",
47.100 - "rand", "reconvert", "regex", "regsub", "statcache", "tb", "tzparse",
47.101 - "util", "whatsound", "whrandom", "zmod"}) {
47.102 - deprecated.put(module, "Obsolete module, removed in Python 2.5");
47.103 -
47.104 - }
47.105 -
47.106 - for (String module : new String[]{"gopherlib", "rgbimg", "macfs"}) {
47.107 - deprecated.put(module, "Obsolete module, removed in Python 2.6");
47.108 - }
47.109 -
47.110 - /*
47.111 - al.rst: The :mod:`al` module has been deprecated for removal in Python 3.0.
47.112 - al.rst: The :mod:`AL` module has been deprecated for removal in Python 3.0.
47.113 - bsddb.rst: The :mod:`bsddb` module has been deprecated for removal in Python 3.0.
47.114 - cd.rst: The :mod:`cd` module has been deprecated for removal in Python 3.0.
47.115 - dbhash.rst: The :mod:`dbhash` module has been deprecated for removal in Python 3.0.
47.116 - fl.rst: The :mod:`fl` module has been deprecated for removal in Python 3.0.
47.117 - fl.rst: The :mod:`FL` module has been deprecated for removal in Python 3.0.
47.118 - fl.rst: The :mod:`flp` module has been deprecated for removal in Python 3.0.
47.119 - fm.rst: The :mod:`fm` module has been deprecated for removal in Python 3.0.
47.120 - gl.rst: The :mod:`gl` module has been deprecated for removal in Python 3.0.
47.121 - gl.rst: The :mod:`DEVICE` module has been deprecated for removal in Python 3.0.
47.122 - gl.rst: The :mod:`GL` module has been deprecated for removal in Python 3.0.
47.123 - imgfile.rst: The :mod:`imgfile` module has been deprecated for removal in Python 3.0.
47.124 - jpeg.rst: The :mod:`jpeg` module has been deprecated for removal in Python 3.0.
47.125 - statvfs.rst: The :mod:`statvfs` module has been deprecated for removal in Python 3.0.
47.126 - sunaudio.rst: The :mod:`sunaudiodev` module has been deprecated for removal in Python 3.0.
47.127 - sunaudio.rst: The :mod:`SUNAUDIODEV` module has been deprecated for removal in Python 3.0.
47.128 - tarfile.rst: The :class:`TarFileCompat` class has been deprecated for removal in Python 3.0.
47.129 - */
47.130 -
47.131 - deprecated.put("posixfile",
47.132 - "Locking is better done by fcntl.lockf().");
47.133 -
47.134 - deprecated.put("gopherlib",
47.135 - "The gopher protocol is not in active use anymore.");
47.136 -
47.137 - deprecated.put("rgbimgmodule",
47.138 - "");
47.139 -
47.140 - deprecated.put("pre",
47.141 - "The underlying PCRE engine doesn't support Unicode, and has been unmaintained since Python 1.5.2.");
47.142 -
47.143 - deprecated.put("whrandom",
47.144 - "The module's default seed computation was inherently insecure; the random module should be used instead.");
47.145 -
47.146 - deprecated.put("rfc822",
47.147 - "Supplanted by Python 2.2's email package.");
47.148 -
47.149 - deprecated.put("mimetools",
47.150 - "Supplanted by Python 2.2's email package.");
47.151 -
47.152 - deprecated.put("MimeWriter",
47.153 - "Supplanted by Python 2.2's email package.");
47.154 -
47.155 - deprecated.put("mimify",
47.156 - "Supplanted by Python 2.2's email package.");
47.157 -
47.158 - deprecated.put("rotor",
47.159 - "Uses insecure algorithm.");
47.160 -
47.161 - deprecated.put("TERMIOS.py",
47.162 - "The constants in this file are now in the 'termios' module.");
47.163 -
47.164 - deprecated.put("statcache",
47.165 - "Using the cache can be fragile and error-prone; applications should just use os.stat() directly.");
47.166 -
47.167 - deprecated.put("mpz",
47.168 - "Third-party packages provide similiar features and wrap more of GMP's API.");
47.169 -
47.170 -
47.171 - deprecated.put("xreadlines",
47.172 - "Using 'for line in file', introduced in 2.3, is preferable.");
47.173 -
47.174 - deprecated.put("multifile",
47.175 - "Supplanted by the email package.");
47.176 -
47.177 - deprecated.put("sets",
47.178 - "The built-in set/frozenset types, introduced in Python 2.4, supplant the module.");
47.179 -
47.180 - deprecated.put("buildtools",
47.181 - "");
47.182 -
47.183 - deprecated.put("cfmfile",
47.184 - "");
47.185 -
47.186 - deprecated.put("macfs",
47.187 - "");
47.188 -
47.189 - deprecated.put("md5",
47.190 - "Replaced by the 'hashlib' module.");
47.191 -
47.192 - deprecated.put("sha",
47.193 - "Replaced by the 'hashlib' module.");
47.194 - }
47.195 -
47.196 - public static boolean isDeprecatedModule(String module) {
47.197 - return deprecated.containsKey(module);
47.198 - }
47.199 -
47.200 - @Override
47.201 - public Set<Class> getKinds() {
47.202 - HashSet<Class> kinds = new HashSet<>();
47.203 - kinds.add(Import.class);
47.204 - kinds.add(ImportFrom.class);
47.205 -
47.206 - return kinds;
47.207 - }
47.208 -
47.209 - @Override
47.210 - public void run(PythonRuleContext context, List<Hint> result) {
47.211 - PythonTree node = context.node;
47.212 - if (node instanceof Import) {
47.213 - Import imp = (Import)node;
47.214 - List<alias> names = imp.getInternalNames();
47.215 - if (names != null) {
47.216 - for (alias alias : names) {
47.217 - String name = alias.getInternalName();
47.218 - if (deprecated.containsKey(name)) {
47.219 - addDeprecation(name, deprecated.get(name), context, result);
47.220 - }
47.221 - }
47.222 - }
47.223 - } else {
47.224 - assert node instanceof ImportFrom;
47.225 - ImportFrom imp = (ImportFrom)node;
47.226 - String name = imp.getInternalModule();
47.227 - if (deprecated.containsKey(name)) {
47.228 - addDeprecation(name, deprecated.get(name), context, result);
47.229 - }
47.230 - }
47.231 - }
47.232 -
47.233 - private void addDeprecation(String module, String rationale, PythonRuleContext context, List<Hint> result) {
47.234 - PythonParserResult info = (PythonParserResult) context.parserResult;
47.235 - OffsetRange astOffsets = PythonAstUtils.getNameRange(info, context.node);
47.236 - OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
47.237 - BaseDocument doc = context.doc;
47.238 - try {
47.239 - if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
47.240 - (context.caretOffset == -1 ||
47.241 - Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
47.242 - List<HintFix> fixList = Collections.emptyList();
47.243 - String displayName;
47.244 - if (rationale.length() > 0) {
47.245 - displayName = NbBundle.getMessage(Deprecations.class, "DeprecationsMsgDetail", module, rationale);
47.246 - } else {
47.247 - displayName = NbBundle.getMessage(Deprecations.class, "DeprecationsMsg", module);
47.248 - }
47.249 - Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
47.250 - result.add(desc);
47.251 - }
47.252 - } catch (BadLocationException ex) {
47.253 - Exceptions.printStackTrace(ex);
47.254 - }
47.255 - }
47.256 -
47.257 - @Override
47.258 - public String getId() {
47.259 - return "Deprecations"; // NOI18N
47.260 - }
47.261 -
47.262 - @Override
47.263 - public String getDisplayName() {
47.264 - return NbBundle.getMessage(Deprecations.class, "Deprecations");
47.265 - }
47.266 -
47.267 - @Override
47.268 - public String getDescription() {
47.269 - return NbBundle.getMessage(Deprecations.class, "DeprecationsDesc");
47.270 - }
47.271 -
47.272 - @Override
47.273 - public boolean getDefaultEnabled() {
47.274 - return true;
47.275 - }
47.276 -
47.277 - @Override
47.278 - public JComponent getCustomizer(Preferences node) {
47.279 - return null;
47.280 - }
47.281 -
47.282 - @Override
47.283 - public boolean appliesTo(RuleContext context) {
47.284 - return true;
47.285 - }
47.286 -
47.287 - @Override
47.288 - public boolean showInTasklist() {
47.289 - return true;
47.290 - }
47.291 -
47.292 - @Override
47.293 - public HintSeverity getDefaultSeverity() {
47.294 - return HintSeverity.WARNING;
47.295 - }
47.296 -}
48.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/ExtractCode.java Fri Sep 18 16:20:24 2015 -0500
48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
48.3 @@ -1,759 +0,0 @@
48.4 -/*
48.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
48.6 - *
48.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
48.8 - *
48.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
48.10 - * Other names may be trademarks of their respective owners.
48.11 - *
48.12 - * The contents of this file are subject to the terms of either the GNU
48.13 - * General Public License Version 2 only ("GPL") or the Common
48.14 - * Development and Distribution License("CDDL") (collectively, the
48.15 - * "License"). You may not use this file except in compliance with the
48.16 - * License. You can obtain a copy of the License at
48.17 - * http://www.netbeans.org/cddl-gplv2.html
48.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
48.19 - * specific language governing permissions and limitations under the
48.20 - * License. When distributing the software, include this License Header
48.21 - * Notice in each file and include the License file at
48.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
48.23 - * particular file as subject to the "Classpath" exception as provided
48.24 - * by Oracle in the GPL Version 2 section of the License file that
48.25 - * accompanied this code. If applicable, add the following below the
48.26 - * License Header, with the fields enclosed by brackets [] replaced by
48.27 - * your own identifying information:
48.28 - * "Portions Copyrighted [year] [name of copyright owner]"
48.29 - *
48.30 - * Contributor(s):
48.31 - *
48.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
48.33 - */
48.34 -package org.netbeans.modules.python.editor.hints;
48.35 -
48.36 -import java.util.ArrayList;
48.37 -import java.util.Collections;
48.38 -import java.util.HashSet;
48.39 -import java.util.List;
48.40 -import java.util.Set;
48.41 -import java.util.prefs.Preferences;
48.42 -import javax.swing.JComponent;
48.43 -import javax.swing.text.JTextComponent;
48.44 -import org.netbeans.editor.BaseDocument;
48.45 -import org.netbeans.editor.Utilities;
48.46 -import org.netbeans.modules.csl.api.EditList;
48.47 -import org.netbeans.modules.csl.api.EditRegions;
48.48 -import org.netbeans.modules.csl.api.Hint;
48.49 -import org.netbeans.modules.csl.api.HintFix;
48.50 -import org.netbeans.modules.csl.api.HintSeverity;
48.51 -import org.netbeans.modules.csl.api.OffsetRange;
48.52 -import org.netbeans.modules.csl.api.PreviewableFix;
48.53 -import org.netbeans.modules.csl.api.RuleContext;
48.54 -import org.netbeans.modules.csl.spi.GsfUtilities;
48.55 -import org.netbeans.modules.editor.indent.api.IndentUtils;
48.56 -import org.netbeans.modules.python.editor.AstPath;
48.57 -import org.netbeans.modules.python.editor.PythonAstUtils;
48.58 -import org.netbeans.modules.python.editor.PythonParserResult;
48.59 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
48.60 -import org.openide.util.Exceptions;
48.61 -import org.openide.util.NbBundle;
48.62 -import org.python.antlr.PythonTree;
48.63 -import org.python.antlr.Visitor;
48.64 -import org.python.antlr.ast.Assert;
48.65 -import org.python.antlr.ast.Assign;
48.66 -import org.python.antlr.ast.AugAssign;
48.67 -import org.python.antlr.ast.Break;
48.68 -import org.python.antlr.ast.Call;
48.69 -import org.python.antlr.ast.ClassDef;
48.70 -import org.python.antlr.ast.Continue;
48.71 -import org.python.antlr.ast.Delete;
48.72 -import org.python.antlr.ast.For;
48.73 -import org.python.antlr.ast.FunctionDef;
48.74 -import org.python.antlr.ast.Global;
48.75 -import org.python.antlr.ast.If;
48.76 -import org.python.antlr.ast.IfExp;
48.77 -import org.python.antlr.ast.Import;
48.78 -import org.python.antlr.ast.ImportFrom;
48.79 -import org.python.antlr.ast.Module;
48.80 -import org.python.antlr.ast.Name;
48.81 -import org.python.antlr.ast.Num;
48.82 -import org.python.antlr.ast.Pass;
48.83 -import org.python.antlr.ast.Print;
48.84 -import org.python.antlr.ast.Raise;
48.85 -import org.python.antlr.ast.Return;
48.86 -import org.python.antlr.ast.Str;
48.87 -import org.python.antlr.ast.Suite;
48.88 -import org.python.antlr.ast.TryExcept;
48.89 -import org.python.antlr.ast.TryFinally;
48.90 -import org.python.antlr.ast.Tuple;
48.91 -import org.python.antlr.ast.While;
48.92 -import org.python.antlr.ast.With;
48.93 -import org.python.antlr.ast.Yield;
48.94 -
48.95 -/**
48.96 - * Offer to introduce method/variable/constant
48.97 - * @todo There is no need to pass in class or top level constants to code fragments
48.98 - * @todo Handle flow control: If a code fragment contains an early return, figure out
48.99 - * how to pass that information back to the method callsite and do something clever,
48.100 - * for example pass back a to-return flag which returns the same value
48.101 - * @todo Unit tests must check instant rename as well!
48.102 - *
48.103 - * @author Tor Norbye
48.104 - */
48.105 -public class ExtractCode extends PythonSelectionRule {
48.106 - //private static final int NOT_APPLICABLE = 0;
48.107 - private static final int INTRODUCE_METHOD = 1;
48.108 - private static final int INTRODUCE_VARIABLE = 2;
48.109 - private static final int INTRODUCE_CONSTANT = 4;
48.110 - private static final int INTRODUCE_FIELD = 8;
48.111 - private static final int NON_EXPRESSIONS = INTRODUCE_VARIABLE | INTRODUCE_FIELD | INTRODUCE_CONSTANT;
48.112 - private static final int ALL = ~0;
48.113 -
48.114 - @Override
48.115 - protected int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange) {
48.116 - return ApplicabilityVisitor.getType(root, astRange);
48.117 - }
48.118 -
48.119 - @Override
48.120 - public void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability) {
48.121 - int start = range.getStart();
48.122 - int end = range.getEnd();
48.123 -
48.124 -// HACK: Only extract method works at this point
48.125 - applicability = applicability & INTRODUCE_METHOD;
48.126 -
48.127 -
48.128 - // Adjust the fix range to be right around the dot so that the light bulb ends up
48.129 - // on the same line as the caret and alt-enter works
48.130 - JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
48.131 - if (target != null) {
48.132 - int dot = target.getCaret().getDot();
48.133 - range = new OffsetRange(dot, dot);
48.134 - }
48.135 -
48.136 - List<HintFix> fixList = new ArrayList<>(3);
48.137 - if ((applicability & INTRODUCE_METHOD) != 0) {
48.138 - fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_METHOD));
48.139 - }
48.140 - if ((applicability & INTRODUCE_VARIABLE) != 0) {
48.141 - fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_VARIABLE));
48.142 - }
48.143 - if ((applicability & INTRODUCE_CONSTANT) != 0) {
48.144 - fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_CONSTANT));
48.145 - }
48.146 - if ((applicability & INTRODUCE_FIELD) != 0) {
48.147 - fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_FIELD));
48.148 - }
48.149 - if (fixList.size() > 0) {
48.150 - String displayName = getDisplayName();
48.151 - Hint desc = new Hint(this, displayName, context.parserResult.getSnapshot().getSource().getFileObject(),
48.152 - range, fixList, 490);
48.153 - result.add(desc);
48.154 - }
48.155 - }
48.156 -
48.157 - @Override
48.158 - public boolean appliesTo(RuleContext context) {
48.159 - return true;
48.160 - }
48.161 -
48.162 - @Override
48.163 - public String getDisplayName() {
48.164 - return NbBundle.getMessage(ExtractCode.class, "ExtractCode");
48.165 - }
48.166 -
48.167 - @Override
48.168 - public String getId() {
48.169 - return "ExtractCode"; // NOI18N
48.170 - }
48.171 -
48.172 - @Override
48.173 - public String getDescription() {
48.174 - return "";
48.175 - }
48.176 -
48.177 - @Override
48.178 - public boolean getDefaultEnabled() {
48.179 - return true;
48.180 - }
48.181 -
48.182 - @Override
48.183 - public JComponent getCustomizer(Preferences node) {
48.184 - return null;
48.185 - }
48.186 -
48.187 - @Override
48.188 - public boolean showInTasklist() {
48.189 - return false;
48.190 - }
48.191 -
48.192 - @Override
48.193 - public HintSeverity getDefaultSeverity() {
48.194 - return HintSeverity.CURRENT_LINE_WARNING;
48.195 - }
48.196 -
48.197 - private static class ExtractCodeFix implements PreviewableFix {
48.198 - private final PythonRuleContext context;
48.199 - //private Position callSitePos;
48.200 - //private Position extractedPos;
48.201 - private int finalCallSiteOffset;
48.202 - private int finalExtractedSiteOffset;
48.203 - ;
48.204 - private final int type;
48.205 - private final int start;
48.206 - private final int end;
48.207 - private String newName;
48.208 -
48.209 - private ExtractCodeFix(PythonRuleContext context,
48.210 - int start, int end, int type) {
48.211 - this.context = context;
48.212 -
48.213 - OffsetRange range = PythonLexerUtils.narrow(context.doc, new OffsetRange(start, end), false);
48.214 - this.start = range.getStart();
48.215 - this.end = range.getEnd();
48.216 -
48.217 - this.type = type;
48.218 - }
48.219 -
48.220 - @Override
48.221 - public String getDescription() {
48.222 - switch (type) {
48.223 - case INTRODUCE_VARIABLE:
48.224 - return NbBundle.getMessage(CreateDocString.class, "IntroduceVariable");
48.225 - case INTRODUCE_CONSTANT:
48.226 - return NbBundle.getMessage(CreateDocString.class, "IntroduceConstant");
48.227 - case INTRODUCE_METHOD:
48.228 - return NbBundle.getMessage(CreateDocString.class, "IntroduceMethod");
48.229 - case INTRODUCE_FIELD:
48.230 - return NbBundle.getMessage(CreateDocString.class, "IntroduceField");
48.231 - default:
48.232 - throw new IllegalArgumentException();
48.233 - }
48.234 - }
48.235 -
48.236 - @Override
48.237 - public boolean canPreview() {
48.238 - return true;
48.239 - }
48.240 -
48.241 - @Override
48.242 - public EditList getEditList() throws Exception {
48.243 - BaseDocument doc = context.doc;
48.244 - PythonParserResult info = (PythonParserResult) context.parserResult;
48.245 - EditList edits = new EditList(doc);
48.246 -
48.247 - int extractedOffset = doc.getLength();
48.248 - int prevFunctionOffset = 0;
48.249 - PythonTree root = PythonAstUtils.getRoot(info);
48.250 -
48.251 - OffsetRange narrowed = PythonLexerUtils.narrow(doc, new OffsetRange(start, end), true);
48.252 -
48.253 - int astStart = PythonAstUtils.getAstOffset(info, narrowed != OffsetRange.NONE ? narrowed.getStart() : start);
48.254 - int astEnd = PythonAstUtils.getAstOffset(info, narrowed != OffsetRange.NONE ? narrowed.getEnd() : end);
48.255 - if (astStart == -1 || astEnd == -1) {
48.256 - return edits;
48.257 - }
48.258 - AstPath startPath = AstPath.get(root, astStart);
48.259 - AstPath endPath = AstPath.get(root, astEnd);
48.260 - PythonTree localScope = PythonAstUtils.getLocalScope(startPath);
48.261 - if (localScope != null) {
48.262 - OffsetRange astRange = PythonAstUtils.getRange(localScope);
48.263 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
48.264 - if (lexRange != OffsetRange.NONE) {
48.265 - extractedOffset = lexRange.getEnd();
48.266 -
48.267 - // Function end offsets are a bit sloppy so try to deal with that
48.268 - int firstNonWhite = Utilities.getRowFirstNonWhite(doc, Math.min(extractedOffset, doc.getLength()));
48.269 - if (firstNonWhite == -1 || extractedOffset <= firstNonWhite) {
48.270 - extractedOffset = Utilities.getRowStart(doc, extractedOffset);
48.271 - }
48.272 -
48.273 - prevFunctionOffset = lexRange.getStart();
48.274 - if (extractedOffset > doc.getLength()) {
48.275 - extractedOffset = doc.getLength();
48.276 - }
48.277 - }
48.278 - }
48.279 - int callSiteOffset = start;
48.280 - int callSiteReplaceLength = end - start;
48.281 -
48.282 - int indentSize = IndentUtils.indentLevelSize(doc);
48.283 - int lineStart = Utilities.getRowStart(doc, prevFunctionOffset);
48.284 - int initialIndent = IndentUtils.lineIndent(doc, lineStart);
48.285 - String initialIndentStr = IndentUtils.createIndentString(doc, initialIndent);
48.286 -
48.287 - newName = "new_name"; // TODO - localize!
48.288 -
48.289 - // Compute input/output arguments
48.290 - PythonTree startNode = startPath.leaf();
48.291 - PythonTree endNode = endPath.leaf();
48.292 -
48.293 - InputOutputFinder finder = new InputOutputFinder(startNode, endNode, Collections.<PythonTree>emptyList());
48.294 - finder.traverse(localScope);
48.295 - List<String> inParams = new ArrayList<>(finder.getInputVars());
48.296 - List<String> outParams = new ArrayList<>(finder.getOutputVars());
48.297 - Collections.sort(inParams);
48.298 - Collections.sort(outParams);
48.299 -
48.300 - ClassDef cls = PythonAstUtils.getClassDef(startPath);
48.301 -
48.302 - // Adjust the insert location in case we are at the top level
48.303 - if (cls == null && PythonAstUtils.getFuncDef(startPath) == null) {
48.304 - extractedOffset = -1;
48.305 - PythonTree top = startPath.topModuleLevel();
48.306 - if (top != null) {
48.307 - OffsetRange astRange = PythonAstUtils.getRange(top);
48.308 - extractedOffset = PythonLexerUtils.getLexerOffset(info, astRange.getStart());
48.309 - }
48.310 -
48.311 - // We're at the top level - I can't insert the function -after- the current function
48.312 - // because that will result in a runtime error
48.313 - if (extractedOffset == -1) {
48.314 - extractedOffset = Utilities.getRowStart(doc, Math.min(doc.getLength(), start));
48.315 - }
48.316 - }
48.317 -
48.318 - String extractedCode = null;
48.319 - int extractedSiteDelta = 0;
48.320 - if (type == INTRODUCE_METHOD) {
48.321 - StringBuilder sb = new StringBuilder();
48.322 - if (Utilities.getRowStart(doc, Math.min(extractedOffset, doc.getLength())) < extractedOffset) {
48.323 - sb.append("\n"); // NOI18N
48.324 - }
48.325 - sb.append("\n"); // NOI18N
48.326 - sb.append(initialIndentStr);
48.327 - sb.append("def "); // NOI18N
48.328 - extractedSiteDelta = sb.length();
48.329 - sb.append(newName);
48.330 - sb.append("("); // NOI18N
48.331 - if (cls != null) {
48.332 - sb.append("self"); // NOI18N
48.333 - if (inParams.size() > 0) {
48.334 - sb.append(", "); // NOI18N
48.335 - }
48.336 - }
48.337 - boolean first = true;
48.338 - for (String param : inParams) {
48.339 - if (first) {
48.340 - first = false;
48.341 - } else {
48.342 - sb.append(", "); // NOI18N
48.343 - }
48.344 - sb.append(param);
48.345 - }
48.346 - sb.append("):\n"); // NOI18N
48.347 -
48.348 - // Copy in the extracted code
48.349 - int firstIndent = IndentUtils.lineIndent(doc, Utilities.getRowStart(doc, start));
48.350 - for (int offset = start; offset < end; offset = Utilities.getRowEnd(doc, offset) + 1) {
48.351 - // TODO - handle multiline literal strings correctly!!!
48.352 - if (!(Utilities.isRowEmpty(doc, offset) || Utilities.isRowWhite(doc, offset))) {
48.353 - int lineIndent = IndentUtils.lineIndent(doc, Utilities.getRowStart(doc, offset));
48.354 - int newIndent = (lineIndent - firstIndent) + initialIndent + indentSize;
48.355 - if (newIndent > 0) {
48.356 - sb.append(IndentUtils.createIndentString(doc, newIndent));
48.357 - }
48.358 - int rowFirstNonWhite = Utilities.getRowFirstNonWhite(doc, offset);
48.359 - int rowLastNonWhite = Utilities.getRowLastNonWhite(doc, offset) + 1; // +1: doesn't include last char
48.360 - sb.append(doc.getText(rowFirstNonWhite, rowLastNonWhite - rowFirstNonWhite));
48.361 - }
48.362 - sb.append("\n"); // NOI18N
48.363 - }
48.364 - sb.append("\n");
48.365 -
48.366 - if (outParams.size() > 0) {
48.367 - sb.append(IndentUtils.createIndentString(doc, initialIndent + indentSize));
48.368 - sb.append("return "); // NOI18N
48.369 - first = true;
48.370 - for (String param : outParams) {
48.371 - if (first) {
48.372 - first = false;
48.373 - } else {
48.374 - // No spaces in the comma list for return tuples
48.375 - sb.append(","); // NOI18N
48.376 - }
48.377 - sb.append(param);
48.378 - }
48.379 - sb.append("\n\n"); // NOI18N
48.380 - }
48.381 -
48.382 - // Insert the extracted code at the end
48.383 - extractedCode = sb.toString();
48.384 - } else {
48.385 - assert (type == INTRODUCE_FIELD || type == INTRODUCE_CONSTANT || type == INTRODUCE_VARIABLE);
48.386 - throw new RuntimeException("Not yet implemented");
48.387 - }
48.388 -
48.389 - // Replace the code at the extract site with just the call
48.390 - StringBuilder sb = new StringBuilder();
48.391 - if (type == INTRODUCE_METHOD) {
48.392 - // Assign to the output variables if any
48.393 - if (outParams.size() > 0) {
48.394 - boolean first = true;
48.395 - for (String param : outParams) {
48.396 - if (first) {
48.397 - first = false;
48.398 - } else {
48.399 - // No spaces in the comma list for return tuples
48.400 - sb.append(","); // NOI18N
48.401 - }
48.402 - sb.append(param);
48.403 - }
48.404 -
48.405 - sb.append(" = ");
48.406 - }
48.407 - } else {
48.408 - assert (type == INTRODUCE_FIELD || type == INTRODUCE_CONSTANT || type == INTRODUCE_VARIABLE);
48.409 - }
48.410 -
48.411 - int callSiteDelta = sb.length();
48.412 - sb.append(newName);
48.413 - if (type == INTRODUCE_METHOD) {
48.414 - sb.append('(');
48.415 - if (cls != null) {
48.416 - sb.append("self"); // NOI18N
48.417 - if (inParams.size() > 0) {
48.418 - sb.append(", "); // NOI18N
48.419 - }
48.420 - }
48.421 - boolean first = true;
48.422 - for (String param : inParams) {
48.423 - if (first) {
48.424 - first = false;
48.425 - } else {
48.426 - sb.append(", "); // NOI18N
48.427 - }
48.428 - sb.append(param);
48.429 - }
48.430 - sb.append(')');
48.431 - }
48.432 - String callSiteCode = sb.toString();
48.433 -
48.434 -
48.435 - // Apply changes
48.436 - if (extractedOffset >= callSiteOffset && extractedOffset <= callSiteOffset + callSiteReplaceLength) {
48.437 - if (extractedOffset > callSiteOffset) {
48.438 - // We're trying to insert the extracted code segment after the call - that must mean we're
48.439 - // in something like a function
48.440 - edits.replace(callSiteOffset, callSiteReplaceLength, callSiteCode + extractedCode, false, 0);
48.441 -
48.442 - // Work around bug in Document.Position
48.443 - //extractedPos = edits.createPosition(callSiteOffset+callSiteCode.length()+extractedSiteDelta, Bias.Forward);
48.444 - //callSitePos = edits.createPosition(callSiteOffset+callSiteDelta, Bias.Forward);
48.445 - finalCallSiteOffset = callSiteOffset + callSiteDelta;
48.446 - finalExtractedSiteOffset = callSiteOffset + callSiteCode.length() + extractedSiteDelta;
48.447 - } else {
48.448 - edits.replace(callSiteOffset, callSiteReplaceLength, extractedCode + callSiteCode, false, 0);
48.449 -
48.450 - // Work around bug in Document.Position
48.451 - //extractedPos = edits.createPosition(callSiteOffset+extractedSiteDelta, Bias.Forward);
48.452 - //callSitePos = edits.createPosition(callSiteOffset+extractedCode.length()+callSiteDelta, Bias.Forward);
48.453 - finalCallSiteOffset = callSiteOffset + extractedCode.length() + callSiteDelta;
48.454 - finalExtractedSiteOffset = callSiteOffset + extractedSiteDelta;
48.455 - }
48.456 - } else {
48.457 - edits.replace(extractedOffset, 0, extractedCode, false, 1);
48.458 - edits.replace(callSiteOffset, callSiteReplaceLength, callSiteCode, false, 0);
48.459 -
48.460 - // There's a bug document/editlist position code - the offsets aren't updated on my
48.461 - // edits! For now just compute the offsets directly since we know the exact edits applied
48.462 - //extractedPos = edits.createPosition(extractedOffset+extractedSiteDelta, Bias.Backward);
48.463 - //callSitePos = edits.createPosition(callSiteOffset+callSiteDelta, Bias.Backward);
48.464 - if (extractedOffset < callSiteOffset) {
48.465 - finalCallSiteOffset = callSiteOffset + callSiteDelta + extractedCode.length();
48.466 - finalExtractedSiteOffset = extractedOffset + extractedSiteDelta;
48.467 - } else {
48.468 - finalCallSiteOffset = callSiteOffset + callSiteDelta;
48.469 - finalExtractedSiteOffset = extractedOffset + extractedSiteDelta + callSiteCode.length() - callSiteReplaceLength;
48.470 - }
48.471 - }
48.472 -
48.473 - return edits;
48.474 - }
48.475 -
48.476 - @Override
48.477 - public void implement() throws Exception {
48.478 - EditList edits = getEditList();
48.479 -
48.480 - edits.apply();
48.481 -
48.482 - // Refactoring isn't necessary here since local variables and block
48.483 - // variables are limited to the local scope, so we can accurately just
48.484 - // find their positions using the AST and let the user edit them synchronously.
48.485 - Set<OffsetRange> ranges = new HashSet<>();
48.486 - int length = newName.length();
48.487 - ranges.add(new OffsetRange(finalCallSiteOffset, finalCallSiteOffset + length));
48.488 - ranges.add(new OffsetRange(finalExtractedSiteOffset, finalExtractedSiteOffset + length));
48.489 -
48.490 - // Initiate synchronous editing:
48.491 - EditRegions.getInstance().edit(context.parserResult.getSnapshot().getSource().getFileObject(), ranges, finalExtractedSiteOffset);
48.492 - }
48.493 -
48.494 - @Override
48.495 - public boolean isSafe() {
48.496 - return true;
48.497 - }
48.498 -
48.499 - @Override
48.500 - public boolean isInteractive() {
48.501 - return false;
48.502 - }
48.503 - }
48.504 -
48.505 - /** @todo Prune search in traverse, ala AstPath.
48.506 - * @todo Build up start and end AstPaths.
48.507 - */
48.508 - private static class ApplicabilityVisitor extends Visitor {
48.509 - private boolean applies = true;
48.510 - private int disabled;
48.511 - private int enabled;
48.512 - private final int start;
48.513 - private final int end;
48.514 -
48.515 - static int getType(PythonTree root, OffsetRange astRange) {
48.516 - ApplicabilityVisitor visitor = new ApplicabilityVisitor(astRange);
48.517 - try {
48.518 - visitor.visit(root);
48.519 - } catch (Exception ex) {
48.520 - Exceptions.printStackTrace(ex);
48.521 - return 0;
48.522 - }
48.523 - return visitor.getType();
48.524 - }
48.525 -
48.526 - ApplicabilityVisitor(OffsetRange astRange) {
48.527 - this.start = astRange.getStart();
48.528 - this.end = astRange.getEnd();
48.529 - }
48.530 -
48.531 - private void enable(PythonTree node, int mask) {
48.532 - if (node.getCharStartIndex() >= start && node.getCharStopIndex() <= end) {
48.533 - enabled |= mask;
48.534 - }
48.535 - }
48.536 -
48.537 - private void disable(PythonTree node, int mask) {
48.538 - if (node.getCharStartIndex() >= start && node.getCharStopIndex() <= end) {
48.539 - disabled |= mask;
48.540 - }
48.541 - }
48.542 -
48.543 - public int getType() {
48.544 - return enabled & ~disabled;
48.545 - }
48.546 -
48.547 - private void maybeBail(PythonTree node) {
48.548 - int nodeStart = node.getCharStartIndex();
48.549 - int nodeEnd = node.getCharStopIndex();
48.550 - if (nodeStart >= start && nodeStart < end) {
48.551 - applies = false;
48.552 - disable(node, ALL);
48.553 - }
48.554 - if (nodeEnd > start && nodeEnd < end) {
48.555 - applies = false;
48.556 - disable(node, ALL);
48.557 - }
48.558 - }
48.559 -
48.560 - @Override
48.561 - public void traverse(PythonTree node) throws Exception {
48.562 - if (!applies) {
48.563 - return;
48.564 - }
48.565 -
48.566 - int nodeStart = node.getCharStartIndex();
48.567 - int nodeStop = node.getCharStopIndex();
48.568 - //if (!(nodeStop < start || nodeStart > end)) {
48.569 - if (nodeStop >= start && nodeStart <= end) {
48.570 - super.traverse(node);
48.571 - }
48.572 - }
48.573 -
48.574 - @Override
48.575 - public Object visitClassDef(ClassDef node) throws Exception {
48.576 - maybeBail(node);
48.577 - return super.visitClassDef(node);
48.578 - }
48.579 -
48.580 - @Override
48.581 - public Object visitFunctionDef(FunctionDef node) throws Exception {
48.582 - maybeBail(node);
48.583 - return super.visitFunctionDef(node);
48.584 - }
48.585 -
48.586 - @Override
48.587 - public Object visitImport(Import node) throws Exception {
48.588 - disable(node, ALL);
48.589 - return super.visitImport(node);
48.590 - }
48.591 -
48.592 - @Override
48.593 - public Object visitImportFrom(ImportFrom node) throws Exception {
48.594 - disable(node, ALL);
48.595 - return super.visitImportFrom(node);
48.596 - }
48.597 -
48.598 - @Override
48.599 - public Object visitAssign(Assign node) throws Exception {
48.600 - disable(node, NON_EXPRESSIONS);
48.601 - disable(node, NON_EXPRESSIONS);
48.602 - return super.visitAssign(node);
48.603 - }
48.604 -
48.605 - @Override
48.606 - public Object visitCall(Call node) throws Exception {
48.607 - enable(node, ALL);
48.608 - disable(node, INTRODUCE_CONSTANT);
48.609 - return super.visitCall(node);
48.610 - }
48.611 -
48.612 - @Override
48.613 - public Object visitAugAssign(AugAssign node) throws Exception {
48.614 - disable(node, NON_EXPRESSIONS);
48.615 - return super.visitAugAssign(node);
48.616 - }
48.617 -
48.618 - @Override
48.619 - public Object visitBreak(Break node) throws Exception {
48.620 - disable(node, NON_EXPRESSIONS);
48.621 - return super.visitBreak(node);
48.622 - }
48.623 -
48.624 - @Override
48.625 - public Object visitContinue(Continue node) throws Exception {
48.626 - disable(node, NON_EXPRESSIONS);
48.627 - return super.visitContinue(node);
48.628 - }
48.629 -
48.630 - @Override
48.631 - public Object visitDelete(Delete node) throws Exception {
48.632 - disable(node, NON_EXPRESSIONS);
48.633 - return super.visitDelete(node);
48.634 - }
48.635 -
48.636 - @Override
48.637 - public Object visitFor(For node) throws Exception {
48.638 - disable(node, NON_EXPRESSIONS);
48.639 - return super.visitFor(node);
48.640 - }
48.641 -
48.642 - @Override
48.643 - public Object visitIf(If node) throws Exception {
48.644 - disable(node, NON_EXPRESSIONS);
48.645 - return super.visitIf(node);
48.646 - }
48.647 -
48.648 - @Override
48.649 - public Object visitIfExp(IfExp node) throws Exception {
48.650 - disable(node, NON_EXPRESSIONS);
48.651 - return super.visitIfExp(node);
48.652 - }
48.653 -
48.654 - @Override
48.655 - public Object visitPrint(Print node) throws Exception {
48.656 - disable(node, NON_EXPRESSIONS);
48.657 - return super.visitPrint(node);
48.658 - }
48.659 -
48.660 - @Override
48.661 - public Object visitYield(Yield node) throws Exception {
48.662 - disable(node, NON_EXPRESSIONS);
48.663 - return super.visitYield(node);
48.664 - }
48.665 -
48.666 - @Override
48.667 - public Object visitWith(With node) throws Exception {
48.668 - disable(node, NON_EXPRESSIONS);
48.669 - return super.visitWith(node);
48.670 - }
48.671 -
48.672 - @Override
48.673 - public Object visitWhile(While node) throws Exception {
48.674 - disable(node, NON_EXPRESSIONS);
48.675 - return super.visitWhile(node);
48.676 - }
48.677 -
48.678 - @Override
48.679 - public Object visitTryFinally(TryFinally node) throws Exception {
48.680 - disable(node, NON_EXPRESSIONS);
48.681 - return super.visitTryFinally(node);
48.682 - }
48.683 -
48.684 - @Override
48.685 - public Object visitTryExcept(TryExcept node) throws Exception {
48.686 - disable(node, NON_EXPRESSIONS);
48.687 - return super.visitTryExcept(node);
48.688 - }
48.689 -
48.690 - @Override
48.691 - public Object visitSuite(Suite node) throws Exception {
48.692 - disable(node, NON_EXPRESSIONS);
48.693 - return super.visitSuite(node);
48.694 - }
48.695 -
48.696 - @Override
48.697 - public Object visitReturn(Return node) throws Exception {
48.698 -// disable(node, NON_EXPRESSIONS);
48.699 - // TODO - handle flow control!!
48.700 - disable(node, ALL);
48.701 - return super.visitReturn(node);
48.702 - }
48.703 -
48.704 - @Override
48.705 - public Object visitModule(Module node) throws Exception {
48.706 - if (node.getCharStartIndex() > start && node.getCharStopIndex() < end) {
48.707 -// disable(node, NON_EXPRESSIONS);
48.708 - disable(node, ALL);
48.709 - }
48.710 - return super.visitModule(node);
48.711 - }
48.712 -
48.713 - @Override
48.714 - public Object visitPass(Pass node) throws Exception {
48.715 - disable(node, NON_EXPRESSIONS);
48.716 - return super.visitPass(node);
48.717 - }
48.718 -
48.719 - @Override
48.720 - public Object visitRaise(Raise node) throws Exception {
48.721 - disable(node, NON_EXPRESSIONS);
48.722 - return super.visitRaise(node);
48.723 - }
48.724 -
48.725 - @Override
48.726 - public Object visitAssert(Assert node) throws Exception {
48.727 - disable(node, NON_EXPRESSIONS);
48.728 - return super.visitAssert(node);
48.729 - }
48.730 -
48.731 - @Override
48.732 - public Object visitNum(Num node) throws Exception {
48.733 - enable(node, ALL);
48.734 - return super.visitNum(node);
48.735 - }
48.736 -
48.737 - @Override
48.738 - public Object visitName(Name node) throws Exception {
48.739 - enable(node, ALL);
48.740 - return super.visitName(node);
48.741 - }
48.742 -
48.743 - @Override
48.744 - public Object visitGlobal(Global node) throws Exception {
48.745 - enable(node, ALL);
48.746 - disable(node, INTRODUCE_CONSTANT);
48.747 - return super.visitGlobal(node);
48.748 - }
48.749 -
48.750 - @Override
48.751 - public Object visitTuple(Tuple node) throws Exception {
48.752 - enable(node, ALL);
48.753 - return super.visitTuple(node);
48.754 - }
48.755 -
48.756 - @Override
48.757 - public Object visitStr(Str node) throws Exception {
48.758 - enable(node, ALL);
48.759 - return super.visitStr(node);
48.760 - }
48.761 - }
48.762 -}
49.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/InputOutputFinder.java Fri Sep 18 16:20:24 2015 -0500
49.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
49.3 @@ -1,304 +0,0 @@
49.4 -/*
49.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
49.6 - *
49.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
49.8 - *
49.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
49.10 - * Other names may be trademarks of their respective owners.
49.11 - *
49.12 - * The contents of this file are subject to the terms of either the GNU
49.13 - * General Public License Version 2 only ("GPL") or the Common
49.14 - * Development and Distribution License("CDDL") (collectively, the
49.15 - * "License"). You may not use this file except in compliance with the
49.16 - * License. You can obtain a copy of the License at
49.17 - * http://www.netbeans.org/cddl-gplv2.html
49.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
49.19 - * specific language governing permissions and limitations under the
49.20 - * License. When distributing the software, include this License Header
49.21 - * Notice in each file and include the License file at
49.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
49.23 - * particular file as subject to the "Classpath" exception as provided
49.24 - * by Oracle in the GPL Version 2 section of the License file that
49.25 - * accompanied this code. If applicable, add the following below the
49.26 - * License Header, with the fields enclosed by brackets [] replaced by
49.27 - * your own identifying information:
49.28 - * "Portions Copyrighted [year] [name of copyright owner]"
49.29 - *
49.30 - * If you wish your version of this file to be governed by only the CDDL
49.31 - * or only the GPL Version 2, indicate your decision by adding
49.32 - * "[Contributor] elects to include this software in this distribution
49.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
49.34 - * single choice of license, a recipient has the option to distribute
49.35 - * your version of this file under either the CDDL, the GPL Version 2 or
49.36 - * to extend the choice of license to its licensees as provided above.
49.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
49.38 - * Version 2 license, then the option applies only if the new code is
49.39 - * made subject to such option by the copyright holder.
49.40 - *
49.41 - * Contributor(s):
49.42 - *
49.43 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
49.44 - */
49.45 -package org.netbeans.modules.python.editor.hints;
49.46 -
49.47 -import java.util.HashMap;
49.48 -import java.util.HashSet;
49.49 -import java.util.List;
49.50 -import java.util.Map;
49.51 -import java.util.Set;
49.52 -import org.netbeans.modules.python.editor.PythonAstUtils;
49.53 -import org.python.antlr.PythonTree;
49.54 -import org.python.antlr.Visitor;
49.55 -import org.python.antlr.ast.Assign;
49.56 -import org.python.antlr.ast.Call;
49.57 -import org.python.antlr.ast.FunctionDef;
49.58 -import org.python.antlr.ast.Name;
49.59 -import org.python.antlr.base.expr;
49.60 -
49.61 -/**
49.62 - * This visitor computes the set of input and output variables required by
49.63 - * a code block for extract method.
49.64 - * In particular, it tracks the local variable assignments inside the method,
49.65 - * and checks which are used outside of the method (which would make it an
49.66 - * output variable) and similarly, which variables are used inside the method
49.67 - * before getting assigned (which would make it an input variable).
49.68 - *
49.69 - * @author Tor Norbye
49.70 - */
49.71 -class InputOutputFinder extends Visitor {
49.72 - //private enum When { BEFORE, DURING, AFTER };
49.73 - private static final int WHEN_BEFORE = 0;
49.74 - private static final int WHEN_DURING = 1;
49.75 - private static final int WHEN_AFTER = 2;
49.76 - private final PythonTree startNode;
49.77 - private final PythonTree endNode;
49.78 - private final int startPos;
49.79 - private final int endPos;
49.80 - private final List<PythonTree> applicableBlocks;
49.81 - private int when = WHEN_BEFORE;
49.82 - private int ifs;
49.83 - //private PythonTree currentBlock;
49.84 - //private final List<PythonTree> blockStack = new ArrayList<PythonTree>(); // JDK16: Use Deque
49.85 - private Map<PythonTree, UsageScope> blockScopes = new HashMap<>();
49.86 - private UsageScope methodScope = new UsageScope(null);
49.87 - //private UsageScope blockScope;
49.88 - private PythonTree parent;
49.89 - private boolean isWriting;
49.90 -
49.91 - /** The node ranges are inclusive */
49.92 - InputOutputFinder(PythonTree startNode, PythonTree endNode, List<PythonTree> applicableBlocks) {
49.93 - this.startNode = startNode;
49.94 - this.endNode = endNode;
49.95 - this.applicableBlocks = applicableBlocks;
49.96 -
49.97 - startPos = startNode.getCharStartIndex();
49.98 - endPos = endNode.getCharStopIndex();
49.99 - }
49.100 -
49.101 - public Set<String> getInputVars() {
49.102 - UsageScope scope = methodScope;
49.103 - for (UsageScope s : blockScopes.values()) {
49.104 - if (s.block != null && !applicableBlocks.contains(s.block)) {
49.105 - continue;
49.106 - }
49.107 - scope.merge(s);
49.108 - }
49.109 -
49.110 - Set<String> inputs = new HashSet<>(scope.readDuring);
49.111 - // But not read before
49.112 - inputs.removeAll(scope.writtenBeforeReadDuring);
49.113 -
49.114 - // Also need to pass in any variables I'm modifying that are read after
49.115 - Set<String> outputs = new HashSet<>(scope.writtenDuring);
49.116 - outputs.retainAll(scope.readAfter);
49.117 - Set<String> extraOutputs = new HashSet<>(scope.writtenBefore);
49.118 - extraOutputs.retainAll(outputs);
49.119 - // unless they are written before read
49.120 - extraOutputs.removeAll(scope.writtenBeforeReadDuring);
49.121 - inputs.addAll(extraOutputs);
49.122 -
49.123 - return inputs;
49.124 - }
49.125 -
49.126 - public Set<String> getOutputVars() {
49.127 - UsageScope scope = methodScope;
49.128 - for (UsageScope s : blockScopes.values()) {
49.129 - if (s.block != null && !applicableBlocks.contains(s.block)) {
49.130 - continue;
49.131 - }
49.132 - scope.merge(s);
49.133 - }
49.134 -
49.135 - Set<String> outputs = new HashSet<>(scope.writtenDuring);
49.136 - outputs.retainAll(scope.readAfter);
49.137 -
49.138 - return outputs;
49.139 - }
49.140 -
49.141 - @Override
49.142 - public Object visitFunctionDef(FunctionDef node) throws Exception {
49.143 - // Record the parameters
49.144 -// assert when == WHEN_BEFORE; // Is this true when I extract a whole method? I can't do that, right?
49.145 - boolean x = true;
49.146 - assert x;
49.147 -
49.148 - for (String param : PythonAstUtils.getParameters(node)) {
49.149 - methodScope.write(param);
49.150 - }
49.151 -
49.152 - return super.visitFunctionDef(node);
49.153 - }
49.154 -
49.155 - @SuppressWarnings("unchecked")
49.156 - @Override
49.157 - public Object visitAssign(Assign node) throws Exception {
49.158 - // Visit the right hand side of the assignment first, such
49.159 - // that with for example
49.160 - // x = x + 1
49.161 - // we treat this as a read of x, before a write of x.
49.162 - // The Assign.traverse() implementation will do the targets first,
49.163 - // so we explicitly do it here in the opposite order instead...
49.164 -
49.165 - if (when == WHEN_BEFORE && node.getCharStartIndex() >= startPos) {
49.166 - when = WHEN_DURING;
49.167 - }
49.168 - int oldWhen = when;
49.169 -
49.170 - expr nodeValue = node.getInternalValue();
49.171 - if (nodeValue != null) {
49.172 - nodeValue.accept(this);
49.173 - }
49.174 - int newWhen = when;
49.175 - when = oldWhen;
49.176 -
49.177 - boolean oldWriting = isWriting;
49.178 - try {
49.179 - isWriting = true;
49.180 - List<expr> targets = node.getInternalTargets();
49.181 - if (targets != null) {
49.182 - for (expr expr : targets) {
49.183 - if (expr != null) {
49.184 - expr.accept(this);
49.185 - }
49.186 - }
49.187 - }
49.188 - } finally {
49.189 - isWriting = oldWriting;
49.190 - }
49.191 -
49.192 - when = newWhen;
49.193 -
49.194 - return node;
49.195 - }
49.196 -
49.197 - @Override
49.198 - public Object visitName(Name node) throws Exception {
49.199 - if (parent instanceof Call && ((Call)parent).getInternalFunc() == node) { // Name in a call is the call name, not a variable
49.200 - return super.visitName(node);
49.201 - }
49.202 -
49.203 - methodScope.read(node.getInternalId());
49.204 -
49.205 - return super.visitName(node);
49.206 - }
49.207 -
49.208 - @Override
49.209 - public void traverse(PythonTree node) throws Exception {
49.210 - if (node == startNode) {
49.211 - when = WHEN_DURING;
49.212 - }
49.213 -
49.214 - PythonTree oldParent = parent;
49.215 - parent = node;
49.216 - super.traverse(node);
49.217 - parent = oldParent;
49.218 -
49.219 - if (node == endNode) {
49.220 - when = WHEN_AFTER;
49.221 - }
49.222 -
49.223 - }
49.224 -
49.225 - private class UsageScope {
49.226 - UsageScope(PythonTree block) {
49.227 - this.block = block;
49.228 - }
49.229 -
49.230 - private void read(String name) {
49.231 - // No need to pass class references or constants in/out
49.232 - // TODO: Make this smarter such that what it really does
49.233 - // is ignore any variables that aren't defined locally - so
49.234 - // global variables for example aren't passed in since they
49.235 - // can -also- be accessed from the extracted method.
49.236 - if (Character.isUpperCase(name.charAt(0))) {
49.237 - return;
49.238 - }
49.239 -
49.240 - if (isWriting) {
49.241 - // A read in the AST for example on the left hand side of an
49.242 - // assignment is really a write
49.243 - write(name);
49.244 - return;
49.245 - }
49.246 -
49.247 - if (when == WHEN_DURING) {
49.248 - if (!writtenBeforeReadDuring.contains(name)) {
49.249 - readDuring.add(name);
49.250 - }
49.251 - } else if (when == WHEN_AFTER) {
49.252 - // I don't want a reassignment of the variable before it's been
49.253 - // read to count as a usage of the result from the fragment
49.254 - if (!writtenAfter.contains(name)) {
49.255 - readAfter.add(name);
49.256 - }
49.257 - }
49.258 - }
49.259 -
49.260 - private void write(String name) {
49.261 - // No need to pass class references or constants in/out
49.262 - // TODO: Make this smarter such that what it really does
49.263 - // is ignore any variables that aren't defined locally - so
49.264 - // global variables for example aren't passed in since they
49.265 - // can -also- be accessed from the extracted method.
49.266 - if (Character.isUpperCase(name.charAt(0))) {
49.267 - return;
49.268 - }
49.269 -
49.270 - if (when == WHEN_BEFORE) {
49.271 - writtenBefore.add(name);
49.272 - } else if (when == WHEN_DURING) {
49.273 - writtenDuring.add(name);
49.274 - if (ifs == 0 && !readDuring.contains(name)) {
49.275 - writtenBeforeReadDuring.add(name);
49.276 - }
49.277 - } else if (when == WHEN_AFTER) {
49.278 - if (ifs == 0 && !readAfter.contains(name)) {
49.279 - writtenAfter.add(name);
49.280 - }
49.281 - }
49.282 - }
49.283 -
49.284 - private void merge(UsageScope other) {
49.285 - writtenBefore.addAll(other.writtenBefore);
49.286 - readDuring.addAll(other.readDuring);
49.287 - writtenDuring.addAll(other.writtenDuring);
49.288 - writtenBeforeReadDuring.addAll(other.writtenBeforeReadDuring);
49.289 - writtenAfter.addAll(other.writtenAfter);
49.290 - readAfter.addAll(other.readAfter);
49.291 - }
49.292 - /** Block, or null if it's the local method */
49.293 - private PythonTree block;
49.294 - /** Variables that exist in scope before the code fragment */
49.295 - private final Set<String> writtenBefore = new HashSet<>();
49.296 - /** Variables that are read during the code fragment */
49.297 - private final Set<String> readDuring = new HashSet<>(); // rename readBeforeWrittenDuring
49.298 - /** Variables that are written to during the code fragment */
49.299 - private final Set<String> writtenDuring = new HashSet<>();
49.300 - /** Variables that are written to during the code fragment */
49.301 - private final Set<String> writtenBeforeReadDuring = new HashSet<>();
49.302 - /** Variables that are written PRIOR TO A READ OF THE SAME VAR after the code fragment */
49.303 - private final Set<String> writtenAfter = new HashSet<>(); // rename writtenBeforeReadAfter
49.304 - /** Variables that are read (prior to a write) after the code fragment */
49.305 - private final Set<String> readAfter = new HashSet<>(); // rename readBeforeWrittenAfter
49.306 - }
49.307 -}
50.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/NameRule.java Fri Sep 18 16:20:24 2015 -0500
50.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50.3 @@ -1,523 +0,0 @@
50.4 -/*
50.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
50.6 - *
50.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
50.8 - *
50.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
50.10 - * Other names may be trademarks of their respective owners.
50.11 - *
50.12 - * The contents of this file are subject to the terms of either the GNU
50.13 - * General Public License Version 2 only ("GPL") or the Common
50.14 - * Development and Distribution License("CDDL") (collectively, the
50.15 - * "License"). You may not use this file except in compliance with the
50.16 - * License. You can obtain a copy of the License at
50.17 - * http://www.netbeans.org/cddl-gplv2.html
50.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
50.19 - * specific language governing permissions and limitations under the
50.20 - * License. When distributing the software, include this License Header
50.21 - * Notice in each file and include the License file at
50.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
50.23 - * particular file as subject to the "Classpath" exception as provided
50.24 - * by Oracle in the GPL Version 2 section of the License file that
50.25 - * accompanied this code. If applicable, add the following below the
50.26 - * License Header, with the fields enclosed by brackets [] replaced by
50.27 - * your own identifying information:
50.28 - * "Portions Copyrighted [year] [name of copyright owner]"
50.29 - *
50.30 - * Contributor(s):
50.31 - *
50.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
50.33 - */
50.34 -package org.netbeans.modules.python.editor.hints;
50.35 -
50.36 -import java.util.ArrayList;
50.37 -import java.util.Collections;
50.38 -import java.util.HashSet;
50.39 -import java.util.List;
50.40 -import java.util.Set;
50.41 -import java.util.prefs.Preferences;
50.42 -import javax.swing.JComponent;
50.43 -import org.netbeans.editor.BaseDocument;
50.44 -import org.netbeans.editor.Utilities;
50.45 -import org.netbeans.modules.csl.api.EditList;
50.46 -import org.netbeans.modules.csl.api.Hint;
50.47 -import org.netbeans.modules.csl.api.HintFix;
50.48 -import org.netbeans.modules.csl.api.HintSeverity;
50.49 -import org.netbeans.modules.csl.api.OffsetRange;
50.50 -import org.netbeans.modules.csl.api.PreviewableFix;
50.51 -import org.netbeans.modules.csl.api.RuleContext;
50.52 -import org.netbeans.modules.python.editor.PythonAstUtils;
50.53 -import org.netbeans.modules.python.editor.PythonParserResult;
50.54 -import org.netbeans.modules.python.editor.PythonUtils;
50.55 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
50.56 -import org.openide.util.NbBundle;
50.57 -import org.python.antlr.PythonTree;
50.58 -import org.python.antlr.ast.ClassDef;
50.59 -import org.python.antlr.ast.FunctionDef;
50.60 -import org.python.antlr.ast.Module;
50.61 -import org.python.antlr.ast.arguments;
50.62 -
50.63 -import static org.netbeans.modules.python.editor.hints.NameStyle.*;
50.64 -
50.65 -/**
50.66 - * Check names to see if they conform to standard Python conventions.
50.67 - * These are documented here:
50.68 - * http://www.python.org/dev/peps/pep-0008/
50.69 - *
50.70 - * @todo Add fix to rename!
50.71 - * @todo Implement variable name checking!
50.72 - *
50.73 - *
50.74 - * @author Tor Norbye
50.75 - */
50.76 -public class NameRule extends PythonAstRule {
50.77 - private static final String CLASS_STYLE_NAME = "classStyle"; // NOI18N
50.78 - private static final String IGNORED_NAMES = "ignoredNames"; // NOI18N
50.79 - private static final String MODULE_STYLE_NAME = "moduleStyle"; // NOI18N
50.80 - private static final String FUNCTION_STYLE_NAME = "functionStyle"; // NOI18N
50.81 - private static final String SELF_REQUIRED_NAME = "selfRequired"; // NOI18N
50.82 - private static final String VARIABLE_STYLE_NAME = "variableStyle"; // NOI18N
50.83 - private static NameStyle moduleStyle;
50.84 - private static NameStyle functionStyle;
50.85 - private static NameStyle classStyle;
50.86 - private static NameStyle variableStyle;
50.87 - private static String ignoredNames;
50.88 - private static boolean selfRequired;
50.89 -
50.90 - public NameRule() {
50.91 - }
50.92 -
50.93 - @Override
50.94 - public boolean appliesTo(RuleContext context) {
50.95 - moduleStyle = null; // Ensure lazy init
50.96 -
50.97 - return true;
50.98 - }
50.99 -
50.100 - private static void initializeFromPrefs(PythonRuleContext context, NameRule rule) {
50.101 - Preferences pref = context.manager.getPreferences(rule);
50.102 - moduleStyle = getModuleNameStyle(pref);
50.103 - classStyle = getClassNameStyle(pref);
50.104 - functionStyle = getFunctionNameStyle(pref);
50.105 - variableStyle = getVariableNameStyle(pref);
50.106 - ignoredNames = getIgnoredNames(pref);
50.107 - selfRequired = isSelfRequired(pref);
50.108 - }
50.109 -
50.110 - @Override
50.111 - public Set<Class> getKinds() {
50.112 - Set<Class> classes = new HashSet<>();
50.113 - classes.add(Module.class);
50.114 - classes.add(FunctionDef.class);
50.115 - classes.add(ClassDef.class);
50.116 -
50.117 - return classes;
50.118 - }
50.119 -
50.120 - @Override
50.121 - public void run(PythonRuleContext context, List<Hint> result) {
50.122 - if (moduleStyle == null) {
50.123 - initializeFromPrefs(context, this);
50.124 - }
50.125 -
50.126 - // TODO - check module name!!
50.127 -
50.128 - PythonTree node = context.node;
50.129 - if (node instanceof Module) {
50.130 - if (moduleStyle != NO_PREFERENCE) {
50.131 - String moduleName = PythonUtils.getModuleName(context.parserResult.getSnapshot().getSource().getFileObject());
50.132 - if (!moduleStyle.complies(moduleName) && !moduleStyle.complies(moduleName.substring(moduleName.lastIndexOf('.') + 1))) {
50.133 - String typeKey = "Module"; // NOI18N
50.134 - String message = NbBundle.getMessage(NameRule.class, "WrongStyle", moduleName,
50.135 - NbBundle.getMessage(NameRule.class, typeKey),
50.136 - moduleStyle.getDisplayName());
50.137 - List<HintFix> hintFixes = getNameStyleFixes(moduleName, context, moduleStyle, MODULE_STYLE_NAME, typeKey);
50.138 - addError(moduleName, context, message, node, result, hintFixes);
50.139 - }
50.140 - }
50.141 - } else if (node instanceof FunctionDef) {
50.142 - FunctionDef def = (FunctionDef)node;
50.143 - if (functionStyle != NO_PREFERENCE) {
50.144 - if (!functionStyle.complies(def.getInternalName())) {
50.145 - String typeKey = "Function"; // NOI18N
50.146 - String message = NbBundle.getMessage(NameRule.class, "WrongStyle", def.getInternalName(),
50.147 - NbBundle.getMessage(NameRule.class, typeKey),
50.148 - functionStyle.getDisplayName());
50.149 - List<HintFix> hintFixes = getNameStyleFixes(def.getInternalName(), context, functionStyle, FUNCTION_STYLE_NAME, typeKey);
50.150 - addError(def.getInternalName(), context, message, def, result, hintFixes);
50.151 - }
50.152 - }
50.153 -
50.154 - // Functions should have a first argument of name "self"
50.155 - if (selfRequired && !PythonAstUtils.isStaticMethod(def)) {
50.156 - arguments args = def.getInternalArgs();
50.157 - if (args.getInternalArgs().size() > 0) {
50.158 - String name = PythonAstUtils.getName(args.getInternalArgs().get(0));
50.159 - if (!("self".equals(name) || "cls".equals(name))) { // NOI18N
50.160 - // Make sure it's a class; other methods don't have to
50.161 - if (PythonAstUtils.isClassMethod(context.path, def)) {
50.162 - String message = NbBundle.getMessage(NameRule.class,
50.163 - // TODO - determine if it should be cls or def
50.164 - "NameRuleWrongArg", // NOI18N
50.165 - name);
50.166 - List<HintFix> fixList = new ArrayList<>(2);
50.167 - fixList.add(new SelfParamFix(context, true, def, null));
50.168 - List<String> parameters = PythonAstUtils.getParameters(def);
50.169 - if (parameters.size() > 0) {
50.170 - fixList.add(new SelfParamFix(context, false, def, parameters.get(0)));
50.171 - }
50.172 - addError(null, context, message, args, result, fixList);
50.173 - }
50.174 - }
50.175 - } else if (PythonAstUtils.isClassMethod(context.path, def)) {
50.176 - String message = NbBundle.getMessage(NameRule.class,
50.177 - // TODO - determine if it should be cls or def
50.178 - "NameRuleWrongNoArg"); // NOI18N
50.179 - List<HintFix> fixList = Collections.<HintFix>singletonList(new SelfParamFix(context, true, def, null));
50.180 - addError(null, context, message, args, result, fixList);
50.181 - }
50.182 - }
50.183 - } else if (node instanceof ClassDef) {
50.184 - if (functionStyle != NO_PREFERENCE) {
50.185 - ClassDef def = (ClassDef)node;
50.186 - if (!classStyle.complies(def.getInternalName())) {
50.187 - String typeKey = "Class"; // NOI18N
50.188 - String message = NbBundle.getMessage(NameRule.class, "WrongStyle", def.getInternalName(),
50.189 - NbBundle.getMessage(NameRule.class, typeKey),
50.190 - classStyle.getDisplayName());
50.191 - List<HintFix> hintFixes = getNameStyleFixes(def.getInternalName(), context, classStyle, CLASS_STYLE_NAME, typeKey);
50.192 - addError(def.getInternalName(), context, message, def, result, hintFixes);
50.193 - }
50.194 - }
50.195 - }
50.196 - }
50.197 -
50.198 - private List<HintFix> getNameStyleFixes(String name, PythonRuleContext context, NameStyle currentStyle, String key, String type) {
50.199 - List<HintFix> fixes = new ArrayList<>(5);
50.200 -
50.201 - fixes.add(new IgnoreWordFix(name, this, context));
50.202 -
50.203 - for (NameStyle style : NameStyle.values()) {
50.204 - if (style == currentStyle || style == NO_PREFERENCE) {
50.205 - continue;
50.206 - }
50.207 -
50.208 - if (style.complies(name)) {
50.209 - ChangeStyleFix cs = new ChangeStyleFix(this, context, style, key, type);
50.210 - fixes.add(cs);
50.211 - }
50.212 - }
50.213 -
50.214 - // No preference always last
50.215 - fixes.add(new ChangeStyleFix(this, context, NO_PREFERENCE, key, type));
50.216 -
50.217 - return fixes;
50.218 - }
50.219 -
50.220 - private void addError(String name, PythonRuleContext context, String message, PythonTree node, List<Hint> result, List<HintFix> fixList) {
50.221 - if (name != null && ignoredNames.length() > 0) {
50.222 - for (String ignoredName : ignoredNames.split(",")) { // NOI18N
50.223 - ignoredName = ignoredName.trim();
50.224 - if (name.equals(ignoredName)) {
50.225 - return;
50.226 - }
50.227 - }
50.228 - }
50.229 -
50.230 - PythonParserResult info = (PythonParserResult)context.parserResult;
50.231 - OffsetRange range;
50.232 - if (node instanceof Module) {
50.233 - range = new OffsetRange(0, 0);
50.234 - } else {
50.235 -
50.236 - range = PythonAstUtils.getNameRange(info, node);
50.237 - }
50.238 - range = PythonLexerUtils.getLexerOffsets(info, range);
50.239 - if (range != OffsetRange.NONE) {
50.240 - if (fixList == null) {
50.241 - fixList = Collections.emptyList();
50.242 - }
50.243 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 1500);
50.244 - result.add(desc);
50.245 - }
50.246 - }
50.247 -
50.248 - @Override
50.249 - public String getId() {
50.250 - return "NameRule"; // NOI18N
50.251 - }
50.252 -
50.253 - @Override
50.254 - public String getDisplayName() {
50.255 - return NbBundle.getMessage(NameRule.class, "NameRule");
50.256 - }
50.257 -
50.258 - @Override
50.259 - public String getDescription() {
50.260 - return NbBundle.getMessage(NameRule.class, "NameRuleDesc");
50.261 - }
50.262 -
50.263 - @Override
50.264 - public boolean getDefaultEnabled() {
50.265 - return true;
50.266 - }
50.267 -
50.268 - @Override
50.269 - public boolean showInTasklist() {
50.270 - return true;
50.271 - }
50.272 -
50.273 - @Override
50.274 - public HintSeverity getDefaultSeverity() {
50.275 - return HintSeverity.WARNING;
50.276 - }
50.277 -
50.278 - @Override
50.279 - public JComponent getCustomizer(Preferences node) {
50.280 - moduleStyle = null; // Ensure lazy init after this
50.281 - return new NameRulePrefs(this, node);
50.282 - }
50.283 -
50.284 - static NameStyle getNameStyle(String key, NameStyle deflt, Preferences pref) {
50.285 - String value = pref.get(key, deflt.name());
50.286 -
50.287 - return NameStyle.valueOf(value);
50.288 - }
50.289 -
50.290 - static NameStyle getModuleNameStyle(Preferences pref) {
50.291 - return getNameStyle(MODULE_STYLE_NAME, NameStyle.NO_PREFERENCE, pref);
50.292 - }
50.293 -
50.294 - static NameStyle getClassNameStyle(Preferences pref) {
50.295 - return getNameStyle(CLASS_STYLE_NAME, NameStyle.CAPITALIZED_WORDS, pref);
50.296 - }
50.297 -
50.298 - static NameStyle getVariableNameStyle(Preferences pref) {
50.299 - return getNameStyle(VARIABLE_STYLE_NAME, NameStyle.LOWERCASE_WITH_UNDERSCORES, pref);
50.300 - }
50.301 -
50.302 - static NameStyle getFunctionNameStyle(Preferences pref) {
50.303 - return getNameStyle(FUNCTION_STYLE_NAME, NameStyle.LOWERCASE_WITH_UNDERSCORES, pref);
50.304 - }
50.305 -
50.306 - static boolean isSelfRequired(Preferences pref) {
50.307 - return pref.getBoolean(SELF_REQUIRED_NAME, true);
50.308 - }
50.309 -
50.310 - static String getIgnoredNames(Preferences pref) {
50.311 - return pref.get(IGNORED_NAMES, "");
50.312 - }
50.313 -
50.314 - void setModuleNameStyle(Preferences pref, NameStyle style) {
50.315 - pref.put(MODULE_STYLE_NAME, style.name());
50.316 - }
50.317 -
50.318 - void setClassNameStyle(Preferences pref, NameStyle style) {
50.319 - pref.put(CLASS_STYLE_NAME, style.name());
50.320 - }
50.321 -
50.322 - void setFunctionNameStyle(Preferences pref, NameStyle style) {
50.323 - pref.put(FUNCTION_STYLE_NAME, style.name());
50.324 - }
50.325 -
50.326 - void setVariableNameStyle(Preferences pref, NameStyle style) {
50.327 - pref.put(VARIABLE_STYLE_NAME, style.name());
50.328 - }
50.329 -
50.330 - void setIgnoredNames(Preferences pref, String ignoredNames) {
50.331 - pref.put(IGNORED_NAMES, ignoredNames);
50.332 - }
50.333 -
50.334 - void setSelfRequired(Preferences pref, boolean requireSelf) {
50.335 - pref.putBoolean(SELF_REQUIRED_NAME, requireSelf);
50.336 - }
50.337 -
50.338 - private static class IgnoreWordFix implements HintFix {
50.339 - private String name;
50.340 - private NameRule rule;
50.341 - private PythonRuleContext context;
50.342 -
50.343 - public IgnoreWordFix(String name, NameRule rule, PythonRuleContext context) {
50.344 - this.name = name;
50.345 - this.rule = rule;
50.346 - this.context = context;
50.347 - }
50.348 -
50.349 - @Override
50.350 - public String getDescription() {
50.351 - return NbBundle.getMessage(NameRule.class, "IgnoreWord", name);
50.352 - }
50.353 -
50.354 - @Override
50.355 - public void implement() throws Exception {
50.356 - Preferences pref = context.manager.getPreferences(rule);
50.357 - String ignored = getIgnoredNames(pref);
50.358 - if (ignored.length() > 0) {
50.359 - ignored = ignored + "," + name; // NOI18N
50.360 - } else {
50.361 - ignored = name;
50.362 - }
50.363 - pref.put(IGNORED_NAMES, ignored);
50.364 -
50.365 - context.manager.refreshHints(context);
50.366 - }
50.367 -
50.368 - @Override
50.369 - public boolean isSafe() {
50.370 - return true;
50.371 - }
50.372 -
50.373 - @Override
50.374 - public boolean isInteractive() {
50.375 - return true;
50.376 - }
50.377 - }
50.378 -
50.379 - private static class ChangeStyleFix implements HintFix {
50.380 - private NameRule rule;
50.381 - private PythonRuleContext context;
50.382 - private NameStyle style;
50.383 - private String key;
50.384 - private String typeKey;
50.385 -
50.386 - public ChangeStyleFix(NameRule rule, PythonRuleContext context, NameStyle style, String key, String type) {
50.387 - this.rule = rule;
50.388 - this.context = context;
50.389 - this.style = style;
50.390 - this.key = key;
50.391 - this.typeKey = type;
50.392 - }
50.393 -
50.394 - @Override
50.395 - public String getDescription() {
50.396 - if (style == NO_PREFERENCE) {
50.397 - return NbBundle.getMessage(NameRule.class, "ChangeNoStyle", NbBundle.getMessage(NameRule.class, typeKey));
50.398 - } else {
50.399 - return NbBundle.getMessage(NameRule.class, "ChangeStyle", NbBundle.getMessage(NameRule.class, typeKey), style.getDisplayName());
50.400 - }
50.401 - }
50.402 -
50.403 - @Override
50.404 - public void implement() throws Exception {
50.405 - Preferences pref = context.manager.getPreferences(rule);
50.406 - pref.put(key, style.name());
50.407 -
50.408 - context.manager.refreshHints(context);
50.409 - }
50.410 -
50.411 - @Override
50.412 - public boolean isSafe() {
50.413 - return true;
50.414 - }
50.415 -
50.416 - @Override
50.417 - public boolean isInteractive() {
50.418 - return true;
50.419 - }
50.420 - }
50.421 -
50.422 - /**
50.423 - * Fix to insert self argument or rename first argument to self
50.424 - */
50.425 - private static class SelfParamFix implements PreviewableFix {
50.426 - private final PythonRuleContext context;
50.427 - private final FunctionDef func;
50.428 - private final boolean insert;
50.429 - private final String first;
50.430 -
50.431 - private SelfParamFix(PythonRuleContext context, boolean insert, FunctionDef func, String first) {
50.432 - this.context = context;
50.433 - this.insert = insert;
50.434 - this.func = func;
50.435 - this.first = first;
50.436 -
50.437 - assert insert || first != null;
50.438 - }
50.439 -
50.440 - @Override
50.441 - public String getDescription() {
50.442 - if (insert) {
50.443 - return NbBundle.getMessage(CreateDocString.class, "InsertSelf");
50.444 - } else {
50.445 - return NbBundle.getMessage(CreateDocString.class, "RenameSelf", first);
50.446 - }
50.447 - }
50.448 -
50.449 - @Override
50.450 - public boolean canPreview() {
50.451 - return true;
50.452 - }
50.453 -
50.454 - @Override
50.455 - public EditList getEditList() throws Exception {
50.456 - return getEditList(true);
50.457 - }
50.458 -
50.459 - private EditList getEditList(boolean previewOnly) throws Exception {
50.460 - BaseDocument doc = context.doc;
50.461 - EditList edits = new EditList(doc);
50.462 -
50.463 - OffsetRange astRange = PythonAstUtils.getNameRange((PythonParserResult) context.parserResult, func);
50.464 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
50.465 - if (lexRange == OffsetRange.NONE) {
50.466 - return edits;
50.467 - }
50.468 - int paramStart = lexRange.getEnd();
50.469 - if (insert) {
50.470 - String missing;
50.471 - int lineEnd = Utilities.getRowEnd(doc, paramStart);
50.472 - int offset = paramStart;
50.473 - if (lineEnd > paramStart) {
50.474 - String line = doc.getText(paramStart, lineEnd - paramStart);
50.475 - int paren = line.indexOf('(');
50.476 - int colon = line.indexOf(':');
50.477 - if (paren != -1) {
50.478 - offset = paramStart + paren + 1;
50.479 - missing = "self"; // NOI18N
50.480 - List<String> parameters = PythonAstUtils.getParameters(func);
50.481 - if (parameters.size() > 0) {
50.482 - missing = "self, "; // NOI18N
50.483 - } else {
50.484 - missing = "self"; // NOI18N
50.485 - }
50.486 - } else if (colon != -1) {
50.487 - offset = paramStart + colon;
50.488 - missing = "(self)"; // NOI18N
50.489 - } else {
50.490 - return edits;
50.491 - }
50.492 - } else {
50.493 - missing = "(self)"; // NOI18N
50.494 - }
50.495 - edits.replace(offset, 0, missing, false, 0);
50.496 - } else {
50.497 - String text = doc.getText(paramStart, doc.getLength() - paramStart);
50.498 - int offset = text.indexOf(first);
50.499 - if (offset != -1) {
50.500 - offset += paramStart;
50.501 - edits.replace(offset, first.length(), "self", false, 0); // NOI18N
50.502 - }
50.503 - }
50.504 -
50.505 -
50.506 - return edits;
50.507 - }
50.508 -
50.509 - @Override
50.510 - public void implement() throws Exception {
50.511 - EditList edits = getEditList(true);
50.512 -
50.513 - edits.apply();
50.514 - }
50.515 -
50.516 - @Override
50.517 - public boolean isSafe() {
50.518 - return true;
50.519 - }
50.520 -
50.521 - @Override
50.522 - public boolean isInteractive() {
50.523 - return false;
50.524 - }
50.525 - }
50.526 -}
51.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/NameRulePrefs.form Fri Sep 18 16:20:24 2015 -0500
51.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3 @@ -1,182 +0,0 @@
51.4 -<?xml version="1.0" encoding="UTF-8" ?>
51.5 -
51.6 -<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
51.7 - <AuxValues>
51.8 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
51.9 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
51.10 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
51.11 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
51.12 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
51.13 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
51.14 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
51.15 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
51.16 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
51.17 - </AuxValues>
51.18 -
51.19 - <Layout>
51.20 - <DimensionLayout dim="0">
51.21 - <Group type="103" groupAlignment="0" attributes="0">
51.22 - <Group type="102" attributes="0">
51.23 - <Group type="103" groupAlignment="0" attributes="0">
51.24 - <Group type="102" alignment="0" attributes="0">
51.25 - <Group type="103" groupAlignment="0" attributes="0">
51.26 - <Component id="moduleLabel" alignment="0" min="-2" max="-2" attributes="0"/>
51.27 - <Component id="classLabel" alignment="0" min="-2" max="-2" attributes="0"/>
51.28 - <Component id="functionLabel" alignment="0" min="-2" max="-2" attributes="0"/>
51.29 - <Component id="variableLabel" alignment="0" min="-2" max="-2" attributes="0"/>
51.30 - </Group>
51.31 - <EmptySpace max="-2" attributes="0"/>
51.32 - <Group type="103" groupAlignment="1" max="-2" attributes="0">
51.33 - <Component id="variableCombo" alignment="0" max="32767" attributes="1"/>
51.34 - <Component id="classCombo" alignment="0" max="32767" attributes="1"/>
51.35 - <Component id="moduleCombo" alignment="0" pref="234" max="32767" attributes="1"/>
51.36 - <Component id="functionCombo" alignment="1" max="32767" attributes="1"/>
51.37 - </Group>
51.38 - </Group>
51.39 - <Component id="parameterLabel" alignment="0" min="-2" max="-2" attributes="0"/>
51.40 - <Component id="selfCb" alignment="0" min="-2" max="-2" attributes="0"/>
51.41 - <Group type="102" alignment="0" attributes="0">
51.42 - <Component id="ignoreLabel" min="-2" max="-2" attributes="0"/>
51.43 - <EmptySpace max="-2" attributes="0"/>
51.44 - <Component id="ignoredText" max="32767" attributes="0"/>
51.45 - </Group>
51.46 - </Group>
51.47 - <EmptySpace max="-2" attributes="0"/>
51.48 - </Group>
51.49 - </Group>
51.50 - </DimensionLayout>
51.51 - <DimensionLayout dim="1">
51.52 - <Group type="103" groupAlignment="0" attributes="0">
51.53 - <Group type="102" alignment="0" attributes="0">
51.54 - <Group type="103" groupAlignment="3" attributes="0">
51.55 - <Component id="moduleLabel" alignment="3" min="-2" max="-2" attributes="0"/>
51.56 - <Component id="moduleCombo" alignment="3" min="-2" max="-2" attributes="0"/>
51.57 - </Group>
51.58 - <EmptySpace max="-2" attributes="0"/>
51.59 - <Group type="103" groupAlignment="3" attributes="0">
51.60 - <Component id="classLabel" alignment="3" min="-2" max="-2" attributes="0"/>
51.61 - <Component id="classCombo" alignment="3" min="-2" max="-2" attributes="0"/>
51.62 - </Group>
51.63 - <EmptySpace max="-2" attributes="0"/>
51.64 - <Group type="103" groupAlignment="3" attributes="0">
51.65 - <Component id="functionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
51.66 - <Component id="functionCombo" alignment="3" min="-2" max="-2" attributes="0"/>
51.67 - </Group>
51.68 - <EmptySpace max="-2" attributes="0"/>
51.69 - <Group type="103" groupAlignment="3" attributes="0">
51.70 - <Component id="variableLabel" alignment="3" min="-2" max="-2" attributes="0"/>
51.71 - <Component id="variableCombo" alignment="3" min="-2" max="-2" attributes="0"/>
51.72 - </Group>
51.73 - <EmptySpace type="separate" max="-2" attributes="0"/>
51.74 - <Component id="parameterLabel" min="-2" max="-2" attributes="0"/>
51.75 - <EmptySpace max="-2" attributes="0"/>
51.76 - <Component id="selfCb" min="-2" max="-2" attributes="0"/>
51.77 - <EmptySpace type="separate" max="-2" attributes="0"/>
51.78 - <Group type="103" groupAlignment="3" attributes="0">
51.79 - <Component id="ignoreLabel" alignment="3" min="-2" max="-2" attributes="0"/>
51.80 - <Component id="ignoredText" alignment="3" min="-2" max="-2" attributes="0"/>
51.81 - </Group>
51.82 - <EmptySpace max="32767" attributes="0"/>
51.83 - </Group>
51.84 - </Group>
51.85 - </DimensionLayout>
51.86 - </Layout>
51.87 - <SubComponents>
51.88 - <Component class="javax.swing.JLabel" name="classLabel">
51.89 - <Properties>
51.90 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.91 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.classLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.92 - </Property>
51.93 - </Properties>
51.94 - </Component>
51.95 - <Component class="javax.swing.JLabel" name="functionLabel">
51.96 - <Properties>
51.97 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.98 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.functionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.99 - </Property>
51.100 - </Properties>
51.101 - </Component>
51.102 - <Component class="javax.swing.JLabel" name="moduleLabel">
51.103 - <Properties>
51.104 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.105 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.moduleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.106 - </Property>
51.107 - </Properties>
51.108 - </Component>
51.109 - <Component class="javax.swing.JLabel" name="parameterLabel">
51.110 - <Properties>
51.111 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.112 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.parameterLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.113 - </Property>
51.114 - </Properties>
51.115 - </Component>
51.116 - <Component class="javax.swing.JCheckBox" name="selfCb">
51.117 - <Properties>
51.118 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.119 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.selfCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.120 - </Property>
51.121 - </Properties>
51.122 - <Events>
51.123 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
51.124 - </Events>
51.125 - </Component>
51.126 - <Component class="javax.swing.JComboBox" name="moduleCombo">
51.127 - <Properties>
51.128 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
51.129 - <Connection code="getNameStyleModel()" type="code"/>
51.130 - </Property>
51.131 - </Properties>
51.132 - <Events>
51.133 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
51.134 - </Events>
51.135 - </Component>
51.136 - <Component class="javax.swing.JComboBox" name="classCombo">
51.137 - <Properties>
51.138 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
51.139 - <Connection code="getNameStyleModel()" type="code"/>
51.140 - </Property>
51.141 - </Properties>
51.142 - <Events>
51.143 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
51.144 - </Events>
51.145 - </Component>
51.146 - <Component class="javax.swing.JComboBox" name="functionCombo">
51.147 - <Properties>
51.148 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
51.149 - <Connection code="getNameStyleModel()" type="code"/>
51.150 - </Property>
51.151 - </Properties>
51.152 - <Events>
51.153 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
51.154 - </Events>
51.155 - </Component>
51.156 - <Component class="javax.swing.JLabel" name="variableLabel">
51.157 - <Properties>
51.158 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.159 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.variableLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.160 - </Property>
51.161 - <Property name="enabled" type="boolean" value="false"/>
51.162 - </Properties>
51.163 - </Component>
51.164 - <Component class="javax.swing.JComboBox" name="variableCombo">
51.165 - <Properties>
51.166 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
51.167 - <Connection code="getNameStyleModel()" type="code"/>
51.168 - </Property>
51.169 - <Property name="enabled" type="boolean" value="false"/>
51.170 - </Properties>
51.171 - <Events>
51.172 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
51.173 - </Events>
51.174 - </Component>
51.175 - <Component class="javax.swing.JLabel" name="ignoreLabel">
51.176 - <Properties>
51.177 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
51.178 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.ignoreLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
51.179 - </Property>
51.180 - </Properties>
51.181 - </Component>
51.182 - <Component class="javax.swing.JTextField" name="ignoredText">
51.183 - </Component>
51.184 - </SubComponents>
51.185 -</Form>
52.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/NameRulePrefs.java Fri Sep 18 16:20:24 2015 -0500
52.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
52.3 @@ -1,291 +0,0 @@
52.4 -/*
52.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
52.6 - *
52.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
52.8 - *
52.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
52.10 - * Other names may be trademarks of their respective owners.
52.11 - *
52.12 - * The contents of this file are subject to the terms of either the GNU
52.13 - * General Public License Version 2 only ("GPL") or the Common
52.14 - * Development and Distribution License("CDDL") (collectively, the
52.15 - * "License"). You may not use this file except in compliance with the
52.16 - * License. You can obtain a copy of the License at
52.17 - * http://www.netbeans.org/cddl-gplv2.html
52.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
52.19 - * specific language governing permissions and limitations under the
52.20 - * License. When distributing the software, include this License Header
52.21 - * Notice in each file and include the License file at
52.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
52.23 - * particular file as subject to the "Classpath" exception as provided
52.24 - * by Oracle in the GPL Version 2 section of the License file that
52.25 - * accompanied this code. If applicable, add the following below the
52.26 - * License Header, with the fields enclosed by brackets [] replaced by
52.27 - * your own identifying information:
52.28 - * "Portions Copyrighted [year] [name of copyright owner]"
52.29 - *
52.30 - * If you wish your version of this file to be governed by only the CDDL
52.31 - * or only the GPL Version 2, indicate your decision by adding
52.32 - * "[Contributor] elects to include this software in this distribution
52.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
52.34 - * single choice of license, a recipient has the option to distribute
52.35 - * your version of this file under either the CDDL, the GPL Version 2 or
52.36 - * to extend the choice of license to its licensees as provided above.
52.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
52.38 - * Version 2 license, then the option applies only if the new code is
52.39 - * made subject to such option by the copyright holder.
52.40 - *
52.41 - * Contributor(s):
52.42 - *
52.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
52.44 - */
52.45 -package org.netbeans.modules.python.editor.hints;
52.46 -
52.47 -import java.awt.Component;
52.48 -import java.util.prefs.Preferences;
52.49 -import javax.swing.ComboBoxModel;
52.50 -import javax.swing.DefaultComboBoxModel;
52.51 -import javax.swing.JLabel;
52.52 -import javax.swing.JList;
52.53 -import javax.swing.ListCellRenderer;
52.54 -
52.55 -/**
52.56 - *
52.57 - * @author Tor Norbye
52.58 - */
52.59 -public class NameRulePrefs extends javax.swing.JPanel {
52.60 - private NameRule rule;
52.61 - private Preferences prefs;
52.62 -
52.63 - /** Creates new form NameRulePrefs */
52.64 - public NameRulePrefs(NameRule rule, Preferences prefs) {
52.65 - this.rule = rule;
52.66 - this.prefs = prefs;
52.67 -
52.68 - initComponents();
52.69 -
52.70 - ListCellRenderer renderer = new NameStyleRenderer();
52.71 - moduleCombo.setRenderer(renderer);
52.72 - functionCombo.setRenderer(renderer);
52.73 - classCombo.setRenderer(renderer);
52.74 - variableCombo.setRenderer(renderer);
52.75 -
52.76 - moduleCombo.setSelectedItem(NameRule.getModuleNameStyle(prefs));
52.77 - functionCombo.setSelectedItem(NameRule.getFunctionNameStyle(prefs));
52.78 - classCombo.setSelectedItem(NameRule.getClassNameStyle(prefs));
52.79 - variableCombo.setSelectedItem(NameRule.getVariableNameStyle(prefs));
52.80 -
52.81 - selfCb.setSelected(NameRule.isSelfRequired(prefs));
52.82 - ignoredText.setText(NameRule.getIgnoredNames(prefs));
52.83 - }
52.84 -
52.85 - private ComboBoxModel getNameStyleModel() {
52.86 - return new DefaultComboBoxModel(NameStyle.values());
52.87 - }
52.88 -
52.89 - private static class NameStyleRenderer extends JLabel implements ListCellRenderer/*, UIResource*/ {
52.90 - public NameStyleRenderer() {
52.91 - setOpaque(true);
52.92 - }
52.93 -
52.94 - @Override
52.95 - public Component getListCellRendererComponent(JList list, Object value,
52.96 - int index, boolean isSelected, boolean cellHasFocus) {
52.97 - // #93658: GTK needs name to render cell renderer "natively"
52.98 - setName("ComboBox.listRenderer"); // NOI18N
52.99 -
52.100 - if (isSelected) {
52.101 - setBackground(list.getSelectionBackground());
52.102 - setForeground(list.getSelectionForeground());
52.103 - } else {
52.104 - setBackground(list.getBackground());
52.105 - setForeground(list.getForeground());
52.106 - }
52.107 -
52.108 - if (value instanceof NameStyle) {
52.109 - setText(((NameStyle)value).getDisplayName());
52.110 - }
52.111 -
52.112 - return this;
52.113 - }
52.114 -
52.115 - // #93658: GTK needs name to render cell renderer "natively"
52.116 - public
52.117 - @Override
52.118 - String getName() {
52.119 - String name = super.getName();
52.120 - return name == null ? "ComboBox.renderer" : name; // NOI18N
52.121 - }
52.122 - }
52.123 -
52.124 - /** This method is called from within the constructor to
52.125 - * initialize the form.
52.126 - * WARNING: Do NOT modify this code. The content of this method is
52.127 - * always regenerated by the Form Editor.
52.128 - */
52.129 - @SuppressWarnings("unchecked")
52.130 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
52.131 - private void initComponents() {
52.132 -
52.133 - classLabel = new javax.swing.JLabel();
52.134 - functionLabel = new javax.swing.JLabel();
52.135 - moduleLabel = new javax.swing.JLabel();
52.136 - parameterLabel = new javax.swing.JLabel();
52.137 - selfCb = new javax.swing.JCheckBox();
52.138 - moduleCombo = new javax.swing.JComboBox();
52.139 - classCombo = new javax.swing.JComboBox();
52.140 - functionCombo = new javax.swing.JComboBox();
52.141 - variableLabel = new javax.swing.JLabel();
52.142 - variableCombo = new javax.swing.JComboBox();
52.143 - ignoreLabel = new javax.swing.JLabel();
52.144 - ignoredText = new javax.swing.JTextField();
52.145 -
52.146 - classLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.classLabel.text")); // NOI18N
52.147 -
52.148 - functionLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.functionLabel.text")); // NOI18N
52.149 -
52.150 - moduleLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.moduleLabel.text")); // NOI18N
52.151 -
52.152 - parameterLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.parameterLabel.text")); // NOI18N
52.153 -
52.154 - selfCb.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.selfCb.text")); // NOI18N
52.155 - selfCb.addActionListener(new java.awt.event.ActionListener() {
52.156 - public void actionPerformed(java.awt.event.ActionEvent evt) {
52.157 - changed(evt);
52.158 - }
52.159 - });
52.160 -
52.161 - moduleCombo.setModel(getNameStyleModel());
52.162 - moduleCombo.addActionListener(new java.awt.event.ActionListener() {
52.163 - public void actionPerformed(java.awt.event.ActionEvent evt) {
52.164 - changed(evt);
52.165 - }
52.166 - });
52.167 -
52.168 - classCombo.setModel(getNameStyleModel());
52.169 - classCombo.addActionListener(new java.awt.event.ActionListener() {
52.170 - public void actionPerformed(java.awt.event.ActionEvent evt) {
52.171 - changed(evt);
52.172 - }
52.173 - });
52.174 -
52.175 - functionCombo.setModel(getNameStyleModel());
52.176 - functionCombo.addActionListener(new java.awt.event.ActionListener() {
52.177 - public void actionPerformed(java.awt.event.ActionEvent evt) {
52.178 - changed(evt);
52.179 - }
52.180 - });
52.181 -
52.182 - variableLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.variableLabel.text")); // NOI18N
52.183 - variableLabel.setEnabled(false);
52.184 -
52.185 - variableCombo.setModel(getNameStyleModel());
52.186 - variableCombo.setEnabled(false);
52.187 - variableCombo.addActionListener(new java.awt.event.ActionListener() {
52.188 - public void actionPerformed(java.awt.event.ActionEvent evt) {
52.189 - changed(evt);
52.190 - }
52.191 - });
52.192 -
52.193 - ignoreLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.ignoreLabel.text")); // NOI18N
52.194 -
52.195 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
52.196 - this.setLayout(layout);
52.197 - layout.setHorizontalGroup(
52.198 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
52.199 - .addGroup(layout.createSequentialGroup()
52.200 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
52.201 - .addGroup(layout.createSequentialGroup()
52.202 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
52.203 - .addComponent(moduleLabel)
52.204 - .addComponent(classLabel)
52.205 - .addComponent(functionLabel)
52.206 - .addComponent(variableLabel))
52.207 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
52.208 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
52.209 - .addComponent(variableCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
52.210 - .addComponent(classCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
52.211 - .addComponent(moduleCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, 234, Short.MAX_VALUE)
52.212 - .addComponent(functionCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
52.213 - .addComponent(parameterLabel)
52.214 - .addComponent(selfCb)
52.215 - .addGroup(layout.createSequentialGroup()
52.216 - .addComponent(ignoreLabel)
52.217 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
52.218 - .addComponent(ignoredText)))
52.219 - .addContainerGap())
52.220 - );
52.221 - layout.setVerticalGroup(
52.222 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
52.223 - .addGroup(layout.createSequentialGroup()
52.224 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
52.225 - .addComponent(moduleLabel)
52.226 - .addComponent(moduleCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
52.227 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
52.228 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
52.229 - .addComponent(classLabel)
52.230 - .addComponent(classCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
52.231 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
52.232 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
52.233 - .addComponent(functionLabel)
52.234 - .addComponent(functionCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
52.235 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
52.236 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
52.237 - .addComponent(variableLabel)
52.238 - .addComponent(variableCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
52.239 - .addGap(18, 18, 18)
52.240 - .addComponent(parameterLabel)
52.241 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
52.242 - .addComponent(selfCb)
52.243 - .addGap(18, 18, 18)
52.244 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
52.245 - .addComponent(ignoreLabel)
52.246 - .addComponent(ignoredText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
52.247 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
52.248 - );
52.249 - }// </editor-fold>//GEN-END:initComponents
52.250 -
52.251 - private void changed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changed
52.252 - Object source = evt.getSource();
52.253 -
52.254 - if (source == moduleCombo) {
52.255 - NameStyle style = (NameStyle)moduleCombo.getSelectedItem();
52.256 - if (style != null) {
52.257 - rule.setModuleNameStyle(prefs, style);
52.258 - }
52.259 - } else if (source == functionCombo) {
52.260 - NameStyle style = (NameStyle)functionCombo.getSelectedItem();
52.261 - if (style != null) {
52.262 - rule.setFunctionNameStyle(prefs, style);
52.263 - }
52.264 - } else if (source == classCombo) {
52.265 - NameStyle style = (NameStyle)classCombo.getSelectedItem();
52.266 - if (style != null) {
52.267 - rule.setClassNameStyle(prefs, style);
52.268 - }
52.269 - } else if (source == variableCombo) {
52.270 - NameStyle style = (NameStyle)variableCombo.getSelectedItem();
52.271 - if (style != null) {
52.272 - rule.setVariableNameStyle(prefs, style);
52.273 - }
52.274 - } else if (source == ignoredText) {
52.275 - rule.setIgnoredNames(prefs, ignoredText.getText().trim());
52.276 - } else if (source == selfCb) {
52.277 - rule.setSelfRequired(prefs, selfCb.isSelected());
52.278 - }
52.279 - }//GEN-LAST:event_changed
52.280 - // Variables declaration - do not modify//GEN-BEGIN:variables
52.281 - private javax.swing.JComboBox classCombo;
52.282 - private javax.swing.JLabel classLabel;
52.283 - private javax.swing.JComboBox functionCombo;
52.284 - private javax.swing.JLabel functionLabel;
52.285 - private javax.swing.JLabel ignoreLabel;
52.286 - private javax.swing.JTextField ignoredText;
52.287 - private javax.swing.JComboBox moduleCombo;
52.288 - private javax.swing.JLabel moduleLabel;
52.289 - private javax.swing.JLabel parameterLabel;
52.290 - private javax.swing.JCheckBox selfCb;
52.291 - private javax.swing.JComboBox variableCombo;
52.292 - private javax.swing.JLabel variableLabel;
52.293 - // End of variables declaration//GEN-END:variables
52.294 -}
53.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/NameStyle.java Fri Sep 18 16:20:24 2015 -0500
53.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
53.3 @@ -1,169 +0,0 @@
53.4 -/*
53.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
53.6 - *
53.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
53.8 - *
53.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
53.10 - * Other names may be trademarks of their respective owners.
53.11 - *
53.12 - * The contents of this file are subject to the terms of either the GNU
53.13 - * General Public License Version 2 only ("GPL") or the Common
53.14 - * Development and Distribution License("CDDL") (collectively, the
53.15 - * "License"). You may not use this file except in compliance with the
53.16 - * License. You can obtain a copy of the License at
53.17 - * http://www.netbeans.org/cddl-gplv2.html
53.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
53.19 - * specific language governing permissions and limitations under the
53.20 - * License. When distributing the software, include this License Header
53.21 - * Notice in each file and include the License file at
53.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
53.23 - * particular file as subject to the "Classpath" exception as provided
53.24 - * by Oracle in the GPL Version 2 section of the License file that
53.25 - * accompanied this code. If applicable, add the following below the
53.26 - * License Header, with the fields enclosed by brackets [] replaced by
53.27 - * your own identifying information:
53.28 - * "Portions Copyrighted [year] [name of copyright owner]"
53.29 - *
53.30 - * If you wish your version of this file to be governed by only the CDDL
53.31 - * or only the GPL Version 2, indicate your decision by adding
53.32 - * "[Contributor] elects to include this software in this distribution
53.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
53.34 - * single choice of license, a recipient has the option to distribute
53.35 - * your version of this file under either the CDDL, the GPL Version 2 or
53.36 - * to extend the choice of license to its licensees as provided above.
53.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
53.38 - * Version 2 license, then the option applies only if the new code is
53.39 - * made subject to such option by the copyright holder.
53.40 - *
53.41 - * Contributor(s):
53.42 - *
53.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
53.44 - */
53.45 -
53.46 -package org.netbeans.modules.python.editor.hints;
53.47 -
53.48 -import org.openide.util.NbBundle;
53.49 -
53.50 -/**
53.51 - *
53.52 - * @author Tor Norbye
53.53 - */
53.54 -public enum NameStyle {
53.55 - NO_PREFERENCE(NbBundle.getMessage(NameStyle.class, "NoPreference")),
53.56 - LOWERCASE("lowercase"),
53.57 - LOWERCASE_WITH_UNDERSCORES("lowercase_with_underscores"),
53.58 - UPPERCASE("UPPERCASE"),
53.59 - UPPERCASE_WITH_UNDERSCORES("UPPERCASE_WITH_UNDERSCORES"),
53.60 - CAPITALIZED_WORDS("CapitalizedWords"),
53.61 - MIXED_CASE("mixedCase"),
53.62 - CAPITALIZED_WITH_UNDERSCORES("Capitalized_With_Underscores");
53.63 -
53.64 - private String displayName;
53.65 -
53.66 - NameStyle(String displayName) {
53.67 - this.displayName = displayName;
53.68 - }
53.69 -
53.70 - String getDisplayName() {
53.71 - return displayName;
53.72 - }
53.73 -
53.74 - public boolean complies(String name) {
53.75 - if (name.length() == 0) {
53.76 - return true;
53.77 - }
53.78 -
53.79 - // Always allow one or two "_" at the beginning and end of the name since
53.80 - // these are used to indicate private, builtin, etc.
53.81 - int start = 0;
53.82 - int end = name.length();
53.83 - if (name.startsWith("__")) { // NOI18N
53.84 - start = 2;
53.85 - } else if (name.startsWith("_")) { // NOI18N
53.86 - start = 1;
53.87 - }
53.88 -
53.89 - if (name.endsWith("__")) { // NOI18N
53.90 - end -= 2;
53.91 - } else if (name.endsWith("_")) { // NOI18N
53.92 - end -= 1;
53.93 - }
53.94 -
53.95 - if (start >= end) {
53.96 - return false;
53.97 - }
53.98 -
53.99 - switch (this) {
53.100 - case NO_PREFERENCE:
53.101 - return true;
53.102 -
53.103 - case LOWERCASE_WITH_UNDERSCORES:
53.104 - case LOWERCASE:
53.105 - for (int i = start; i < end; i++) {
53.106 - char c = name.charAt(i);
53.107 - if (c == '_') {
53.108 - if (this != LOWERCASE_WITH_UNDERSCORES) {
53.109 - return false;
53.110 - }
53.111 - } else if (Character.isDigit(c)) {
53.112 - } else if (!Character.isLowerCase(c)) {
53.113 - return false;
53.114 - }
53.115 - }
53.116 -
53.117 - return true;
53.118 -
53.119 -
53.120 - case UPPERCASE:
53.121 - case UPPERCASE_WITH_UNDERSCORES:
53.122 - for (int i = start; i < end; i++) {
53.123 - char c = name.charAt(i);
53.124 - if (c == '_') {
53.125 - if (this != UPPERCASE_WITH_UNDERSCORES) {
53.126 - return false;
53.127 - }
53.128 - } else if (Character.isDigit(c)) {
53.129 - } else if (!Character.isUpperCase(c)) {
53.130 - return false;
53.131 - }
53.132 - }
53.133 -
53.134 - return true;
53.135 -
53.136 - case MIXED_CASE:
53.137 - // TODO - require that characters after _ are capitalized?
53.138 - case CAPITALIZED_WORDS:
53.139 - case CAPITALIZED_WITH_UNDERSCORES:
53.140 - if (this == MIXED_CASE) {
53.141 - // Must begin with lowercase
53.142 - if (!Character.isLowerCase(name.charAt(start))) {
53.143 - return false;
53.144 - }
53.145 - } else if (this == CAPITALIZED_WORDS || this == CAPITALIZED_WITH_UNDERSCORES) {
53.146 - // Must begin with uppercase
53.147 - if (!Character.isUpperCase(name.charAt(start))) {
53.148 - return false;
53.149 - }
53.150 - }
53.151 - for (int i = start+1; i < end; i++) {
53.152 - char c = name.charAt(i);
53.153 - if (c == '_') {
53.154 - if (this != CAPITALIZED_WITH_UNDERSCORES) {
53.155 - return false;
53.156 - }
53.157 - } else if (Character.isDigit(c)) {
53.158 - } else if (!Character.isUpperCase(c) && !Character.isLowerCase(c)) {
53.159 - return false;
53.160 - }
53.161 -
53.162 - // What about digits?
53.163 - }
53.164 -
53.165 - return true;
53.166 - default:
53.167 - assert false : this;
53.168 - }
53.169 -
53.170 - return true;
53.171 - }
53.172 -}
54.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/PythonAstRule.java Fri Sep 18 16:20:24 2015 -0500
54.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
54.3 @@ -1,51 +0,0 @@
54.4 -/*
54.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
54.6 - *
54.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
54.8 - *
54.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
54.10 - * Other names may be trademarks of their respective owners.
54.11 - *
54.12 - * The contents of this file are subject to the terms of either the GNU
54.13 - * General Public License Version 2 only ("GPL") or the Common
54.14 - * Development and Distribution License("CDDL") (collectively, the
54.15 - * "License"). You may not use this file except in compliance with the
54.16 - * License. You can obtain a copy of the License at
54.17 - * http://www.netbeans.org/cddl-gplv2.html
54.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
54.19 - * specific language governing permissions and limitations under the
54.20 - * License. When distributing the software, include this License Header
54.21 - * Notice in each file and include the License file at
54.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
54.23 - * particular file as subject to the "Classpath" exception as provided
54.24 - * by Oracle in the GPL Version 2 section of the License file that
54.25 - * accompanied this code. If applicable, add the following below the
54.26 - * License Header, with the fields enclosed by brackets [] replaced by
54.27 - * your own identifying information:
54.28 - * "Portions Copyrighted [year] [name of copyright owner]"
54.29 - *
54.30 - * Contributor(s):
54.31 - *
54.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
54.33 - */
54.34 -package org.netbeans.modules.python.editor.hints;
54.35 -
54.36 -import java.util.List;
54.37 -import java.util.Set;
54.38 -import org.netbeans.modules.csl.api.Hint;
54.39 -import org.netbeans.modules.csl.api.Rule.AstRule;
54.40 -
54.41 -public abstract class PythonAstRule implements AstRule {
54.42 - /**
54.43 - * Get the ElementKinds this rule should run on.
54.44 - * The integers should correspond to values in {@link org.mozilla.javascript.Token}
54.45 - */
54.46 - @Override
54.47 - public abstract Set<Class> getKinds();
54.48 -
54.49 - /**
54.50 - * Run the test on given CompilationUnit and return list of Errors or
54.51 - * warrnings to be shown in the editor.
54.52 - */
54.53 - public abstract void run(PythonRuleContext context, List<Hint> result);
54.54 -}
55.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/PythonHintsProvider.java Fri Sep 18 16:20:24 2015 -0500
55.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
55.3 @@ -1,433 +0,0 @@
55.4 -/*
55.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
55.6 - *
55.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
55.8 - *
55.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
55.10 - * Other names may be trademarks of their respective owners.
55.11 - *
55.12 - * The contents of this file are subject to the terms of either the GNU
55.13 - * General Public License Version 2 only ("GPL") or the Common
55.14 - * Development and Distribution License("CDDL") (collectively, the
55.15 - * "License"). You may not use this file except in compliance with the
55.16 - * License. You can obtain a copy of the License at
55.17 - * http://www.netbeans.org/cddl-gplv2.html
55.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
55.19 - * specific language governing permissions and limitations under the
55.20 - * License. When distributing the software, include this License Header
55.21 - * Notice in each file and include the License file at
55.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
55.23 - * particular file as subject to the "Classpath" exception as provided
55.24 - * by Oracle in the GPL Version 2 section of the License file that
55.25 - * accompanied this code. If applicable, add the following below the
55.26 - * License Header, with the fields enclosed by brackets [] replaced by
55.27 - * your own identifying information:
55.28 - * "Portions Copyrighted [year] [name of copyright owner]"
55.29 - *
55.30 - * Contributor(s):
55.31 - *
55.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
55.33 - */
55.34 -package org.netbeans.modules.python.editor.hints;
55.35 -
55.36 -import java.util.Collections;
55.37 -import java.util.HashMap;
55.38 -import java.util.Iterator;
55.39 -import java.util.LinkedList;
55.40 -import java.util.List;
55.41 -import java.util.Map;
55.42 -import java.util.Map.Entry;
55.43 -import java.util.Set;
55.44 -import org.netbeans.modules.csl.api.Error;
55.45 -import org.netbeans.modules.csl.api.Hint;
55.46 -import org.netbeans.modules.csl.api.HintFix;
55.47 -import org.netbeans.modules.csl.api.HintSeverity;
55.48 -import org.netbeans.modules.csl.api.HintsProvider;
55.49 -import org.netbeans.modules.csl.api.HintsProvider.HintsManager;
55.50 -import org.netbeans.modules.csl.api.OffsetRange;
55.51 -import org.netbeans.modules.csl.api.Rule;
55.52 -import org.netbeans.modules.csl.api.RuleContext;
55.53 -import org.netbeans.modules.csl.spi.GsfUtilities;
55.54 -import org.netbeans.modules.csl.spi.ParserResult;
55.55 -import org.netbeans.modules.python.editor.AstPath;
55.56 -import org.netbeans.modules.python.editor.PythonAstUtils;
55.57 -import org.netbeans.modules.python.editor.PythonParserResult;
55.58 -import org.openide.util.Exceptions;
55.59 -import org.python.antlr.PythonTree;
55.60 -import org.python.antlr.Visitor;
55.61 -
55.62 -/**
55.63 - *
55.64 - * @todo Write rules based on the PythonChecker ideas:
55.65 - * http://pychecker.sourceforge.net/
55.66 - * @todo Write rules based on the PyLint ideas:
55.67 - * http://www.logilab.org/projects/pylint
55.68 - * http://www.logilab.org/card/pylintfeatures
55.69 - *
55.70 - * @author Tor Norbye
55.71 - */
55.72 -public class PythonHintsProvider implements HintsProvider {
55.73 - private boolean cancelled;
55.74 -
55.75 - public PythonHintsProvider() {
55.76 - }
55.77 -
55.78 - private static class ScopeRule implements Rule {
55.79 - @Override
55.80 - public boolean appliesTo(RuleContext context) {
55.81 - return true;
55.82 - }
55.83 -
55.84 - @Override
55.85 - public String getDisplayName() {
55.86 - return "";
55.87 - }
55.88 -
55.89 - @Override
55.90 - public boolean showInTasklist() {
55.91 - return true;
55.92 - }
55.93 -
55.94 - @Override
55.95 - public HintSeverity getDefaultSeverity() {
55.96 - return HintSeverity.ERROR;
55.97 - }
55.98 - }
55.99 -
55.100 - @Override
55.101 - public void computeErrors(HintsManager manager, RuleContext context, List<Hint> result, List<Error> unhandled) {
55.102 - ParserResult parserResult = context.parserResult;
55.103 - if (parserResult == null) {
55.104 - return;
55.105 - }
55.106 -
55.107 - PythonParserResult pr = (PythonParserResult)parserResult;
55.108 - List<Error> scopeErrors = pr.getSymbolTable().getErrors();
55.109 - if (scopeErrors.size() > 0) {
55.110 - List<HintFix> fixList = Collections.emptyList();
55.111 - Rule rule = new ScopeRule(); // HACK! Just need a rule that will return a severity!
55.112 - for (Error error : scopeErrors) {
55.113 - Hint desc = new Hint(rule, error.getDisplayName(), error.getFile(),
55.114 - new OffsetRange(error.getStartPosition(), error.getEndPosition()), fixList, 10);
55.115 - result.add(desc);
55.116 - }
55.117 - }
55.118 -
55.119 - List<? extends Error> errors = parserResult.getDiagnostics();
55.120 - if (errors == null || errors.size() == 0) {
55.121 - return;
55.122 - }
55.123 -//
55.124 -// cancelled = false;
55.125 -//
55.126 -// @SuppressWarnings("unchecked")
55.127 -// Map<String,List<JsErrorRule>> hints = (Map)manager.getErrors();
55.128 -//
55.129 -// if (hints.isEmpty() || isCancelled()) {
55.130 - unhandled.addAll(errors);
55.131 -// return;
55.132 -// }
55.133 -//
55.134 -// for (Error error : errors) {
55.135 -// if (!applyErrorRules(manager, context, error, hints, result)) {
55.136 -// unhandled.add(error);
55.137 -// }
55.138 -// }
55.139 - }
55.140 -
55.141 - @Override
55.142 - public void computeSelectionHints(HintsManager manager, RuleContext context, List<Hint> result, int start, int end) {
55.143 - cancelled = false;
55.144 -
55.145 - if (GsfUtilities.isCodeTemplateEditing(context.doc)) {
55.146 - return;
55.147 - }
55.148 -
55.149 - ParserResult parserResult = context.parserResult;
55.150 - if (parserResult == null) {
55.151 - return;
55.152 - }
55.153 - PythonTree root = PythonAstUtils.getRoot(context.parserResult);
55.154 -
55.155 - if (root == null) {
55.156 - return;
55.157 - }
55.158 - @SuppressWarnings("unchecked")
55.159 - List<? extends Rule.SelectionRule> hints = manager.getSelectionHints();
55.160 -
55.161 - if (hints.isEmpty()) {
55.162 - return;
55.163 - }
55.164 -
55.165 - if (isCancelled()) {
55.166 - return;
55.167 - }
55.168 -
55.169 - try {
55.170 - context.doc.readLock();
55.171 - applySelectionRules(manager, context, hints, result);
55.172 - } finally {
55.173 - context.doc.readUnlock();
55.174 - }
55.175 -}
55.176 -
55.177 - private void applySelectionRules(HintsManager manager, RuleContext context, List<? extends Rule.SelectionRule> rules, List<Hint> result) {
55.178 -
55.179 - PythonRuleContext pythonContext = (PythonRuleContext)context;
55.180 -
55.181 - for (Rule.SelectionRule rule : rules) {
55.182 - if (!rule.appliesTo(context)) {
55.183 - continue;
55.184 - }
55.185 -
55.186 - if(!(rule instanceof PythonSelectionRule)) {
55.187 - continue;
55.188 - }
55.189 -
55.190 - if (!manager.isEnabled((PythonSelectionRule)rule)) {
55.191 - continue;
55.192 - }
55.193 -
55.194 - try {
55.195 - context.doc.readLock();
55.196 - ((PythonSelectionRule)rule).run(pythonContext, result);
55.197 - } finally {
55.198 - context.doc.readUnlock();
55.199 - }
55.200 - }
55.201 - }
55.202 -
55.203 - @Override
55.204 - public void computeHints(HintsManager manager, RuleContext context, List<Hint> result) {
55.205 - cancelled = false;
55.206 -
55.207 - if (context.parserResult == null) {
55.208 - return;
55.209 - }
55.210 - PythonTree root = PythonAstUtils.getRoot(context.parserResult);
55.211 -
55.212 - if (root == null) {
55.213 - return;
55.214 - }
55.215 - @SuppressWarnings("unchecked")
55.216 - Map<Class, List<PythonAstRule>> hints = (Map)manager.getHints(false, context);
55.217 -
55.218 - if (hints.isEmpty()) {
55.219 - return;
55.220 - }
55.221 -
55.222 - if (isCancelled()) {
55.223 - return;
55.224 - }
55.225 -
55.226 -// AstPath path = new AstPath();
55.227 -// path.descend(root);
55.228 -//
55.229 -// //applyRules(manager, NodeTypes.ROOTNODE, root, path, info, hints, descriptions);
55.230 -// applyHints(manager, context, -1, root, path, hints, result);
55.231 -//
55.232 -// scan(manager, context, root, path, hints, result);
55.233 -// path.ascend();
55.234 -
55.235 -
55.236 - RuleApplicator finder = new RuleApplicator(manager, context, hints, result);
55.237 - try {
55.238 - context.doc.readLock();
55.239 - finder.visit(root);
55.240 - } catch (Exception ex) {
55.241 - Exceptions.printStackTrace(ex);
55.242 - } finally {
55.243 - context.doc.readUnlock();
55.244 - }
55.245 - }
55.246 -
55.247 - @SuppressWarnings("unchecked")
55.248 - @Override
55.249 - public void computeSuggestions(HintsManager manager, RuleContext context, List<Hint> result, int caretOffset) {
55.250 - cancelled = false;
55.251 - if (context.parserResult == null) {
55.252 - return;
55.253 - }
55.254 -
55.255 - PythonTree root = PythonAstUtils.getRoot(context.parserResult);
55.256 -
55.257 - if (root == null) {
55.258 - return;
55.259 - }
55.260 -
55.261 - Map<Class, List<PythonAstRule>> suggestions = new HashMap<>();
55.262 - suggestions.putAll((Map)manager.getHints(true, context));
55.263 -
55.264 - Set<Entry<Class, List<PythonAstRule>>> entrySet = (Set)manager.getSuggestions().entrySet();
55.265 - for (Entry<Class, List<PythonAstRule>> e : entrySet) {
55.266 - List<PythonAstRule> rules = suggestions.get(e.getKey());
55.267 -
55.268 - if (rules != null) {
55.269 - List<PythonAstRule> res = new LinkedList<>();
55.270 -
55.271 - res.addAll(rules);
55.272 - res.addAll(e.getValue());
55.273 -
55.274 - suggestions.put(e.getKey(), res);
55.275 - } else {
55.276 - suggestions.put(e.getKey(), e.getValue());
55.277 - }
55.278 - }
55.279 -
55.280 - if (suggestions.isEmpty()) {
55.281 - return;
55.282 - }
55.283 -
55.284 -
55.285 - if (isCancelled()) {
55.286 - return;
55.287 - }
55.288 -
55.289 - try {
55.290 - context.doc.readLock();
55.291 -
55.292 - PythonParserResult info = (PythonParserResult)context.parserResult;
55.293 - int astOffset = PythonAstUtils.getAstOffset(info, caretOffset);
55.294 - AstPath path = AstPath.get(root, astOffset);
55.295 - Iterator<PythonTree> it = path.leafToRoot();
55.296 - while (it.hasNext()) {
55.297 - if (isCancelled()) {
55.298 - return;
55.299 - }
55.300 -
55.301 - PythonTree node = it.next();
55.302 -
55.303 - applySuggestions(manager, context, node.getClass(), node, path, suggestions, result);
55.304 - }
55.305 - } finally {
55.306 - context.doc.readUnlock();
55.307 - }
55.308 -
55.309 - //applyRules(NodeTypes.ROOTNODE, path, info, suggestions, caretOffset, result);
55.310 - }
55.311 -
55.312 - private void applySuggestions(HintsManager manager, RuleContext context, Class nodeType, PythonTree node, AstPath path, Map<Class, List<PythonAstRule>> hints,
55.313 - List<Hint> result) {
55.314 - List<PythonAstRule> rules = hints.get(nodeType);
55.315 -
55.316 - if (rules != null) {
55.317 - PythonRuleContext pyCtx = (PythonRuleContext)context;
55.318 - pyCtx.node = node;
55.319 - pyCtx.path = path;
55.320 -
55.321 - try {
55.322 - context.doc.readLock();
55.323 - for (PythonAstRule rule : rules) {
55.324 - if (manager.isEnabled(rule)) {
55.325 - rule.run(pyCtx, result);
55.326 - }
55.327 - }
55.328 - } finally {
55.329 - context.doc.readUnlock();
55.330 - }
55.331 - }
55.332 - }
55.333 -
55.334 -// /** Apply error rules and return true iff somebody added an error description for it */
55.335 -// private boolean applyErrorRules(HintsManager manager, RuleContext context, Error error, Map<String,List<JsErrorRule>> hints,
55.336 -// List<Hint> result) {
55.337 -// String code = error.getKey();
55.338 -// if (code != null) {
55.339 -// List<JsErrorRule> rules = hints.get(code);
55.340 -//
55.341 -// if (rules != null) {
55.342 -// int countBefore = result.size();
55.343 -// PythonRuleContext jsContext = (PythonRuleContext)context;
55.344 -//
55.345 -// boolean disabled = false;
55.346 -// for (JsErrorRule rule : rules) {
55.347 -// if (!manager.isEnabled(rule)) {
55.348 -// disabled = true;
55.349 -// } else if (rule.appliesTo(context)) {
55.350 -// rule.run(jsContext, error, result);
55.351 -// }
55.352 -// }
55.353 -//
55.354 -// return disabled || countBefore < result.size() || jsContext.remove;
55.355 -// }
55.356 -// }
55.357 -//
55.358 -// return false;
55.359 -// }
55.360 -//
55.361 -// private void applySelectionRules(HintsManager manager, RuleContext context, List<JsSelectionRule> rules,
55.362 -// List<Hint> result) {
55.363 -//
55.364 -// for (JsSelectionRule rule : rules) {
55.365 -// if (!rule.appliesTo(context)) {
55.366 -// continue;
55.367 -// }
55.368 -//
55.369 -// //if (!manager.isEnabled(rule)) {
55.370 -// // continue;
55.371 -// //}
55.372 -//
55.373 -// rule.run(context, result);
55.374 -// }
55.375 -// }
55.376 -//
55.377 - @Override
55.378 - public void cancel() {
55.379 - cancelled = true;
55.380 - }
55.381 -
55.382 - private boolean isCancelled() {
55.383 - return cancelled;
55.384 - }
55.385 -
55.386 - @Override
55.387 - public RuleContext createRuleContext() {
55.388 - return new PythonRuleContext();
55.389 - }
55.390 -
55.391 - @Override
55.392 - public List<Rule> getBuiltinRules() {
55.393 - return Collections.emptyList();
55.394 - }
55.395 -
55.396 - private static class RuleApplicator extends Visitor {
55.397 - private HintsManager manager;
55.398 - private RuleContext context;
55.399 - private AstPath path;
55.400 - private Map<Class, List<PythonAstRule>> hints;
55.401 - private List<Hint> result;
55.402 -
55.403 - public RuleApplicator(HintsManager manager, RuleContext context, Map<Class, List<PythonAstRule>> hints, List<Hint> result) {
55.404 - this.manager = manager;
55.405 - this.context = context;
55.406 - this.hints = hints;
55.407 - this.result = result;
55.408 -
55.409 - path = new AstPath();
55.410 - }
55.411 -
55.412 - @Override
55.413 - public void traverse(PythonTree node) throws Exception {
55.414 - path.descend(node);
55.415 - applyHints(node);
55.416 - super.traverse(node);
55.417 - path.ascend();
55.418 - }
55.419 -
55.420 - private void applyHints(PythonTree node) {
55.421 - List<PythonAstRule> rules = hints.get(node.getClass());
55.422 -
55.423 - if (rules != null) {
55.424 - PythonRuleContext jsContext = (PythonRuleContext)context;
55.425 - jsContext.node = node;
55.426 - jsContext.path = path;
55.427 -
55.428 - for (PythonAstRule rule : rules) {
55.429 - if (manager.isEnabled(rule)) {
55.430 - rule.run(jsContext, result);
55.431 - }
55.432 - }
55.433 - }
55.434 - }
55.435 - }
55.436 -}
56.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/PythonRuleContext.java Fri Sep 18 16:20:24 2015 -0500
56.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
56.3 @@ -1,45 +0,0 @@
56.4 -/*
56.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
56.6 - *
56.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
56.8 - *
56.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
56.10 - * Other names may be trademarks of their respective owners.
56.11 - *
56.12 - * The contents of this file are subject to the terms of either the GNU
56.13 - * General Public License Version 2 only ("GPL") or the Common
56.14 - * Development and Distribution License("CDDL") (collectively, the
56.15 - * "License"). You may not use this file except in compliance with the
56.16 - * License. You can obtain a copy of the License at
56.17 - * http://www.netbeans.org/cddl-gplv2.html
56.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
56.19 - * specific language governing permissions and limitations under the
56.20 - * License. When distributing the software, include this License Header
56.21 - * Notice in each file and include the License file at
56.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
56.23 - * particular file as subject to the "Classpath" exception as provided
56.24 - * by Oracle in the GPL Version 2 section of the License file that
56.25 - * accompanied this code. If applicable, add the following below the
56.26 - * License Header, with the fields enclosed by brackets [] replaced by
56.27 - * your own identifying information:
56.28 - * "Portions Copyrighted [year] [name of copyright owner]"
56.29 - *
56.30 - * Contributor(s):
56.31 - *
56.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
56.33 - */
56.34 -package org.netbeans.modules.python.editor.hints;
56.35 -
56.36 -import org.netbeans.modules.python.editor.AstPath;
56.37 -import org.python.antlr.PythonTree;
56.38 -
56.39 -/**
56.40 - * Information about the current context a rule is being asked to evaluate.
56.41 - *
56.42 - * @author Tor Norbye
56.43 - */
56.44 -public class PythonRuleContext extends org.netbeans.modules.csl.api.RuleContext {
56.45 - public AstPath path;
56.46 - public PythonTree node;
56.47 - public boolean remove;
56.48 -}
57.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/PythonSelectionRule.java Fri Sep 18 16:20:24 2015 -0500
57.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
57.3 @@ -1,128 +0,0 @@
57.4 -/*
57.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
57.6 - *
57.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
57.8 - *
57.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
57.10 - * Other names may be trademarks of their respective owners.
57.11 - *
57.12 - * The contents of this file are subject to the terms of either the GNU
57.13 - * General Public License Version 2 only ("GPL") or the Common
57.14 - * Development and Distribution License("CDDL") (collectively, the
57.15 - * "License"). You may not use this file except in compliance with the
57.16 - * License. You can obtain a copy of the License at
57.17 - * http://www.netbeans.org/cddl-gplv2.html
57.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
57.19 - * specific language governing permissions and limitations under the
57.20 - * License. When distributing the software, include this License Header
57.21 - * Notice in each file and include the License file at
57.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
57.23 - * particular file as subject to the "Classpath" exception as provided
57.24 - * by Oracle in the GPL Version 2 section of the License file that
57.25 - * accompanied this code. If applicable, add the following below the
57.26 - * License Header, with the fields enclosed by brackets [] replaced by
57.27 - * your own identifying information:
57.28 - * "Portions Copyrighted [year] [name of copyright owner]"
57.29 - *
57.30 - * Contributor(s):
57.31 - *
57.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
57.33 - */
57.34 -package org.netbeans.modules.python.editor.hints;
57.35 -
57.36 -import javax.swing.text.BadLocationException;
57.37 -import java.util.List;
57.38 -import org.netbeans.modules.python.editor.PythonAstUtils;
57.39 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
57.40 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
57.41 -import org.netbeans.api.lexer.Token;
57.42 -import org.netbeans.api.lexer.TokenId;
57.43 -import org.netbeans.editor.BaseDocument;
57.44 -import org.netbeans.editor.Utilities;
57.45 -import org.netbeans.modules.csl.api.Hint;
57.46 -import org.netbeans.modules.csl.api.OffsetRange;
57.47 -import org.netbeans.modules.csl.api.Rule.SelectionRule;
57.48 -import org.netbeans.modules.csl.api.Rule.UserConfigurableRule;
57.49 -import org.openide.util.Exceptions;
57.50 -import org.python.antlr.PythonTree;
57.51 -
57.52 -/**
57.53 - * Represents a rule to be run on text selection
57.54 - *
57.55 - * @author Tor Norbye
57.56 - */
57.57 -public abstract class PythonSelectionRule implements SelectionRule, UserConfigurableRule {
57.58 - protected abstract int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange);
57.59 -
57.60 - //public abstract void run(PythonRuleContext context, List<Hint> result);
57.61 - public void run(PythonRuleContext context, List<Hint> result) {
57.62 - // TODO - decide if this code represents a complete statement...
57.63 - // For now - that's true iff there's no code to the left on the
57.64 - // start line and code to the right on the end line
57.65 - BaseDocument doc = context.doc;
57.66 - int originalStart = context.selectionStart;
57.67 - int originalEnd = context.selectionEnd;
57.68 - int docLength = doc.getLength();
57.69 -
57.70 - if (originalEnd > docLength) {
57.71 - return;
57.72 - }
57.73 - OffsetRange narrowed = PythonLexerUtils.narrow(doc, new OffsetRange(originalStart, originalEnd), false);
57.74 - if (narrowed == OffsetRange.NONE) {
57.75 - return;
57.76 - }
57.77 -
57.78 - int start = narrowed.getStart();
57.79 - int end = narrowed.getEnd();
57.80 - try {
57.81 - if (start > Utilities.getRowFirstNonWhite(doc, Math.min(docLength, start))) {
57.82 - return;
57.83 - }
57.84 - if (end < Utilities.getRowLastNonWhite(doc, Math.min(docLength, end)) + 1) {
57.85 - return;
57.86 - }
57.87 - } catch (BadLocationException ex) {
57.88 - Exceptions.printStackTrace(ex);
57.89 - }
57.90 -
57.91 - PythonTree root = PythonAstUtils.getRoot(context.parserResult);
57.92 - if (root == null) {
57.93 - return;
57.94 - }
57.95 -
57.96 - OffsetRange astRange = PythonAstUtils.getAstOffsets(context.parserResult, new OffsetRange(start, end));
57.97 - if (astRange == OffsetRange.NONE) {
57.98 - return;
57.99 - }
57.100 -
57.101 - int applicability = getApplicability(context, root, astRange);
57.102 - if (applicability == 0) {
57.103 - return;
57.104 - }
57.105 - // Don't allow extract with if you're inside strings or comments
57.106 - Token<? extends PythonTokenId> startToken = PythonLexerUtils.getToken(doc, start);
57.107 - Token<? extends PythonTokenId> endToken = PythonLexerUtils.getToken(doc, end);
57.108 - if (startToken == null || endToken == null) {
57.109 - return;
57.110 - }
57.111 - TokenId startId = startToken.id();
57.112 - if (startId == PythonTokenId.STRING_LITERAL ||
57.113 - (startId == PythonTokenId.COMMENT && start > 0 && startToken == PythonLexerUtils.getToken(doc, start - 1))) {
57.114 - return;
57.115 - }
57.116 - TokenId endId = endToken.id();
57.117 - if (endId == PythonTokenId.STRING_LITERAL) {
57.118 - return;
57.119 - }
57.120 -
57.121 - // TODO - don't enable inside comments or strings!!
57.122 - // TODO - if you are including functions or classes it should probably
57.123 - // be disabled!
57.124 -
57.125 - OffsetRange range = new OffsetRange(originalStart, originalEnd);
57.126 -
57.127 - run(context, result, range, applicability);
57.128 - }
57.129 -
57.130 - public abstract void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability);
57.131 -}
58.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/RelativeImports.java Fri Sep 18 16:20:24 2015 -0500
58.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
58.3 @@ -1,246 +0,0 @@
58.4 -/*
58.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
58.6 - *
58.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
58.8 - *
58.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
58.10 - * Other names may be trademarks of their respective owners.
58.11 - *
58.12 - * The contents of this file are subject to the terms of either the GNU
58.13 - * General Public License Version 2 only ("GPL") or the Common
58.14 - * Development and Distribution License("CDDL") (collectively, the
58.15 - * "License"). You may not use this file except in compliance with the
58.16 - * License. You can obtain a copy of the License at
58.17 - * http://www.netbeans.org/cddl-gplv2.html
58.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
58.19 - * specific language governing permissions and limitations under the
58.20 - * License. When distributing the software, include this License Header
58.21 - * Notice in each file and include the License file at
58.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
58.23 - * particular file as subject to the "Classpath" exception as provided
58.24 - * by Oracle in the GPL Version 2 section of the License file that
58.25 - * accompanied this code. If applicable, add the following below the
58.26 - * License Header, with the fields enclosed by brackets [] replaced by
58.27 - * your own identifying information:
58.28 - * "Portions Copyrighted [year] [name of copyright owner]"
58.29 - *
58.30 - * If you wish your version of this file to be governed by only the CDDL
58.31 - * or only the GPL Version 2, indicate your decision by adding
58.32 - * "[Contributor] elects to include this software in this distribution
58.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
58.34 - * single choice of license, a recipient has the option to distribute
58.35 - * your version of this file under either the CDDL, the GPL Version 2 or
58.36 - * to extend the choice of license to its licensees as provided above.
58.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
58.38 - * Version 2 license, then the option applies only if the new code is
58.39 - * made subject to such option by the copyright holder.
58.40 - *
58.41 - * Contributor(s):
58.42 - *
58.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
58.44 - */
58.45 -package org.netbeans.modules.python.editor.hints;
58.46 -
58.47 -import java.util.ArrayList;
58.48 -import java.util.Collections;
58.49 -import java.util.List;
58.50 -import java.util.Set;
58.51 -import java.util.prefs.Preferences;
58.52 -import javax.swing.JComponent;
58.53 -import javax.swing.text.BadLocationException;
58.54 -import org.netbeans.modules.python.editor.PythonAstUtils;
58.55 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
58.56 -import org.netbeans.editor.BaseDocument;
58.57 -import org.netbeans.editor.Utilities;
58.58 -import org.netbeans.modules.csl.api.EditList;
58.59 -import org.netbeans.modules.csl.api.Hint;
58.60 -import org.netbeans.modules.csl.api.HintFix;
58.61 -import org.netbeans.modules.csl.api.HintSeverity;
58.62 -import org.netbeans.modules.csl.api.OffsetRange;
58.63 -import org.netbeans.modules.csl.api.PreviewableFix;
58.64 -import org.netbeans.modules.csl.api.RuleContext;
58.65 -import org.netbeans.modules.csl.spi.ParserResult;
58.66 -import org.netbeans.modules.python.editor.PythonParserResult;
58.67 -import org.openide.filesystems.FileObject;
58.68 -import org.openide.util.Exceptions;
58.69 -import org.openide.util.NbBundle;
58.70 -import org.python.antlr.PythonTree;
58.71 -import org.python.antlr.ast.ImportFrom;
58.72 -
58.73 -/**
58.74 - * Import statements should be one per line. This quickfix
58.75 - * offers to make it so.
58.76 - *
58.77 - * @todo Ensure that
58.78 - * {@code from __future__ import absolute_import}
58.79 - * is present, at least until Python 2.7
58.80 - *
58.81 - * @author Tor Norbye
58.82 - */
58.83 -public class RelativeImports extends PythonAstRule {
58.84 - @Override
58.85 - public Set<Class> getKinds() {
58.86 - return Collections.singleton((Class)ImportFrom.class);
58.87 - }
58.88 -
58.89 - @Override
58.90 - public void run(PythonRuleContext context, List<Hint> result) {
58.91 - ImportFrom imp = (ImportFrom)context.node;
58.92 - if (imp.getInternalModule() != null && imp.getInternalModule().startsWith(".")) {
58.93 - PythonTree node = context.node;
58.94 - PythonParserResult info = (PythonParserResult) context.parserResult;
58.95 - OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
58.96 - OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
58.97 - BaseDocument doc = context.doc;
58.98 - try {
58.99 - if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
58.100 - (context.caretOffset == -1 ||
58.101 - Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
58.102 - List<HintFix> fixList = new ArrayList<>();
58.103 - fixList.add(new RelativeImportsFix(context, imp));
58.104 - String displayName = getDisplayName();
58.105 - Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
58.106 - result.add(desc);
58.107 - }
58.108 - } catch (BadLocationException ex) {
58.109 - Exceptions.printStackTrace(ex);
58.110 - }
58.111 - }
58.112 - }
58.113 -
58.114 - @Override
58.115 - public String getId() {
58.116 - return "RelativeImports"; // NOI18N
58.117 - }
58.118 -
58.119 - @Override
58.120 - public String getDisplayName() {
58.121 - return NbBundle.getMessage(RelativeImports.class, "RelativeImports");
58.122 - }
58.123 -
58.124 - @Override
58.125 - public String getDescription() {
58.126 - return NbBundle.getMessage(RelativeImports.class, "RelativeImportsDesc");
58.127 - }
58.128 -
58.129 - @Override
58.130 - public boolean getDefaultEnabled() {
58.131 - return true;
58.132 - }
58.133 -
58.134 - @Override
58.135 - public JComponent getCustomizer(Preferences node) {
58.136 - return null;
58.137 - }
58.138 -
58.139 - @Override
58.140 - public boolean appliesTo(RuleContext context) {
58.141 - return true;
58.142 - }
58.143 -
58.144 - @Override
58.145 - public boolean showInTasklist() {
58.146 - return true;
58.147 - }
58.148 -
58.149 - @Override
58.150 - public HintSeverity getDefaultSeverity() {
58.151 - return HintSeverity.WARNING;
58.152 - }
58.153 -
58.154 - private static class RelativeImportsFix implements PreviewableFix {
58.155 - private final PythonRuleContext context;
58.156 - private final ImportFrom imp;
58.157 -
58.158 - private RelativeImportsFix(PythonRuleContext context, ImportFrom imp) {
58.159 - this.context = context;
58.160 - this.imp = imp;
58.161 - }
58.162 -
58.163 - @Override
58.164 - public String getDescription() {
58.165 - return NbBundle.getMessage(RelativeImports.class, "RelativeImportsFix");
58.166 - }
58.167 -
58.168 - @Override
58.169 - public boolean canPreview() {
58.170 - return true;
58.171 - }
58.172 -
58.173 - @Override
58.174 - public EditList getEditList() throws Exception {
58.175 - BaseDocument doc = context.doc;
58.176 - EditList edits = new EditList(doc);
58.177 -
58.178 - // Algorithm:
58.179 - // (1) Figure out which package we are in
58.180 - // (2) Subtrack package elements per dot
58.181 - // (3) Replace relative reference
58.182 -
58.183 - OffsetRange astRange = PythonAstUtils.getRange(imp);
58.184 - if (astRange != OffsetRange.NONE) {
58.185 - PythonParserResult info = (PythonParserResult)context.parserResult;
58.186 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
58.187 - if (lexRange != OffsetRange.NONE) {
58.188 - FileObject fo = info.getSnapshot().getSource().getFileObject();
58.189 - if (fo != null) {
58.190 - String path = imp.getInternalModule();
58.191 - int i = 0;
58.192 - for (; i < path.length(); i++) {
58.193 - if (path.charAt(i) != '.') {
58.194 - break;
58.195 - }
58.196 - }
58.197 - int levels = i;
58.198 - path = path.substring(levels);
58.199 -
58.200 - for (int j = 0; j < levels; j++) {
58.201 - if (fo != null) {
58.202 - fo = fo.getParent();
58.203 - }
58.204 - }
58.205 -
58.206 - // Finally, find out the absolute path we are in
58.207 - // Hopefully, I will have access to the python load path
58.208 - // here. But in the mean time, I can just see which
58.209 - // packages I am in...
58.210 - while (fo != null) {
58.211 - if (fo.getFileObject("__init__.py") != null) { // NOI18N
58.212 - // Yep, we're still in a package
58.213 - if (path.length() > 0) {
58.214 - path = fo.getName() + "." + path; // NOI18N
58.215 - } else {
58.216 - path = fo.getName();
58.217 - }
58.218 - }
58.219 - fo = fo.getParent();
58.220 - }
58.221 - String text = doc.getText(lexRange.getStart(), lexRange.getLength());
58.222 - int relativePos = text.indexOf(imp.getInternalModule());
58.223 - if (relativePos != -1) {
58.224 - edits.replace(lexRange.getStart() + relativePos, imp.getInternalModule().length(), path, false, 0);
58.225 - }
58.226 - }
58.227 - }
58.228 - }
58.229 -
58.230 - return edits;
58.231 - }
58.232 -
58.233 - @Override
58.234 - public void implement() throws Exception {
58.235 - EditList edits = getEditList();
58.236 - edits.apply();
58.237 - }
58.238 -
58.239 - @Override
58.240 - public boolean isSafe() {
58.241 - return true;
58.242 - }
58.243 -
58.244 - @Override
58.245 - public boolean isInteractive() {
58.246 - return false;
58.247 - }
58.248 - }
58.249 -}
59.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/SplitImports.java Fri Sep 18 16:20:24 2015 -0500
59.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
59.3 @@ -1,222 +0,0 @@
59.4 -/*
59.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
59.6 - *
59.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
59.8 - *
59.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
59.10 - * Other names may be trademarks of their respective owners.
59.11 - *
59.12 - * The contents of this file are subject to the terms of either the GNU
59.13 - * General Public License Version 2 only ("GPL") or the Common
59.14 - * Development and Distribution License("CDDL") (collectively, the
59.15 - * "License"). You may not use this file except in compliance with the
59.16 - * License. You can obtain a copy of the License at
59.17 - * http://www.netbeans.org/cddl-gplv2.html
59.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
59.19 - * specific language governing permissions and limitations under the
59.20 - * License. When distributing the software, include this License Header
59.21 - * Notice in each file and include the License file at
59.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
59.23 - * particular file as subject to the "Classpath" exception as provided
59.24 - * by Oracle in the GPL Version 2 section of the License file that
59.25 - * accompanied this code. If applicable, add the following below the
59.26 - * License Header, with the fields enclosed by brackets [] replaced by
59.27 - * your own identifying information:
59.28 - * "Portions Copyrighted [year] [name of copyright owner]"
59.29 - *
59.30 - * If you wish your version of this file to be governed by only the CDDL
59.31 - * or only the GPL Version 2, indicate your decision by adding
59.32 - * "[Contributor] elects to include this software in this distribution
59.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
59.34 - * single choice of license, a recipient has the option to distribute
59.35 - * your version of this file under either the CDDL, the GPL Version 2 or
59.36 - * to extend the choice of license to its licensees as provided above.
59.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
59.38 - * Version 2 license, then the option applies only if the new code is
59.39 - * made subject to such option by the copyright holder.
59.40 - *
59.41 - * Contributor(s):
59.42 - *
59.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
59.44 - */
59.45 -package org.netbeans.modules.python.editor.hints;
59.46 -
59.47 -import java.util.ArrayList;
59.48 -import java.util.Collections;
59.49 -import java.util.List;
59.50 -import java.util.Set;
59.51 -import java.util.prefs.Preferences;
59.52 -import javax.swing.JComponent;
59.53 -import javax.swing.text.BadLocationException;
59.54 -import org.netbeans.modules.python.editor.PythonAstUtils;
59.55 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
59.56 -import org.netbeans.editor.BaseDocument;
59.57 -import org.netbeans.editor.Utilities;
59.58 -import org.netbeans.modules.csl.api.EditList;
59.59 -import org.netbeans.modules.csl.api.Hint;
59.60 -import org.netbeans.modules.csl.api.HintFix;
59.61 -import org.netbeans.modules.csl.api.HintSeverity;
59.62 -import org.netbeans.modules.csl.api.OffsetRange;
59.63 -import org.netbeans.modules.csl.api.PreviewableFix;
59.64 -import org.netbeans.modules.csl.api.RuleContext;
59.65 -import org.netbeans.modules.csl.spi.GsfUtilities;
59.66 -import org.netbeans.modules.editor.indent.api.IndentUtils;
59.67 -import org.netbeans.modules.python.editor.PythonParserResult;
59.68 -import org.netbeans.modules.python.editor.options.CodeStyle;
59.69 -import org.openide.util.Exceptions;
59.70 -import org.openide.util.NbBundle;
59.71 -import org.python.antlr.PythonTree;
59.72 -import org.python.antlr.ast.Import;
59.73 -import org.python.antlr.ast.alias;
59.74 -
59.75 -/**
59.76 - * Import statements should be one per line. This quickfix
59.77 - * offers to make it so.
59.78 - *
59.79 - * @author Tor Norbye
59.80 - */
59.81 -public class SplitImports extends PythonAstRule {
59.82 - @Override
59.83 - public Set<Class> getKinds() {
59.84 - return Collections.singleton((Class)Import.class);
59.85 - }
59.86 -
59.87 - @Override
59.88 - public void run(PythonRuleContext context, List<Hint> result) {
59.89 - Import imp = (Import)context.node;
59.90 - List<alias> names = imp.getInternalNames();
59.91 - if (names != null && names.size() > 1) {
59.92 - PythonTree node = context.node;
59.93 - PythonParserResult info = (PythonParserResult)context.parserResult;
59.94 - OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
59.95 - OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
59.96 - BaseDocument doc = context.doc;
59.97 - try {
59.98 - if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
59.99 - (context.caretOffset == -1 ||
59.100 - Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
59.101 - List<HintFix> fixList = new ArrayList<>();
59.102 - fixList.add(new SplitImportsFix(context, imp));
59.103 - String displayName = getDisplayName();
59.104 - Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
59.105 - result.add(desc);
59.106 - }
59.107 - } catch (BadLocationException ex) {
59.108 - Exceptions.printStackTrace(ex);
59.109 - }
59.110 - }
59.111 - }
59.112 -
59.113 - @Override
59.114 - public String getId() {
59.115 - return "SplitImports"; // NOI18N
59.116 - }
59.117 -
59.118 - @Override
59.119 - public String getDisplayName() {
59.120 - return NbBundle.getMessage(SplitImports.class, "SplitImports");
59.121 - }
59.122 -
59.123 - @Override
59.124 - public String getDescription() {
59.125 - return NbBundle.getMessage(SplitImports.class, "SplitImportsDesc");
59.126 - }
59.127 -
59.128 - @Override
59.129 - public boolean getDefaultEnabled() {
59.130 - return true;
59.131 - }
59.132 -
59.133 - @Override
59.134 - public JComponent getCustomizer(Preferences node) {
59.135 - return null;
59.136 - }
59.137 -
59.138 - @Override
59.139 - public boolean appliesTo(RuleContext context) {
59.140 - CodeStyle codeStyle = CodeStyle.getDefault(context.doc);
59.141 - return codeStyle == null || codeStyle.oneImportPerLine();
59.142 - }
59.143 -
59.144 - @Override
59.145 - public boolean showInTasklist() {
59.146 - return true;
59.147 - }
59.148 -
59.149 - @Override
59.150 - public HintSeverity getDefaultSeverity() {
59.151 - return HintSeverity.WARNING;
59.152 - }
59.153 -
59.154 - private static class SplitImportsFix implements PreviewableFix {
59.155 - private final PythonRuleContext context;
59.156 - private final Import imp;
59.157 -
59.158 - private SplitImportsFix(PythonRuleContext context, Import imp) {
59.159 - this.context = context;
59.160 - this.imp = imp;
59.161 - }
59.162 -
59.163 - @Override
59.164 - public String getDescription() {
59.165 - return NbBundle.getMessage(SplitImports.class, "SplitImportsFix");
59.166 - }
59.167 -
59.168 - @Override
59.169 - public boolean canPreview() {
59.170 - return true;
59.171 - }
59.172 -
59.173 - @Override
59.174 - public EditList getEditList() throws Exception {
59.175 - BaseDocument doc = context.doc;
59.176 - EditList edits = new EditList(doc);
59.177 -
59.178 - OffsetRange astRange = PythonAstUtils.getRange(imp);
59.179 - if (astRange != OffsetRange.NONE) {
59.180 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
59.181 - if (lexRange != OffsetRange.NONE) {
59.182 - int indent = GsfUtilities.getLineIndent(doc, lexRange.getStart());
59.183 - StringBuilder sb = new StringBuilder();
59.184 - List<alias> names = imp.getInternalNames();
59.185 - if (names != null) {
59.186 - for (alias at : names) {
59.187 - if (indent > 0 && sb.length() > 0) {
59.188 - sb.append(IndentUtils.createIndentString(doc, indent));
59.189 - }
59.190 - sb.append("import "); // NOI18N
59.191 - sb.append(at.getInternalName());
59.192 - if (at.getInternalAsname() != null && at.getInternalAsname().length() > 0) {
59.193 - sb.append(" as "); // NOI18N
59.194 - sb.append(at.getInternalAsname());
59.195 - }
59.196 - sb.append("\n");
59.197 - }
59.198 - }
59.199 - // Remove the final newline since Import doesn't include it
59.200 - sb.setLength(sb.length() - 1);
59.201 -
59.202 - edits.replace(lexRange.getStart(), lexRange.getLength(), sb.toString(), false, 0);
59.203 - }
59.204 - }
59.205 -
59.206 - return edits;
59.207 - }
59.208 -
59.209 - @Override
59.210 - public void implement() throws Exception {
59.211 - EditList edits = getEditList();
59.212 - edits.apply();
59.213 - }
59.214 -
59.215 - @Override
59.216 - public boolean isSafe() {
59.217 - return true;
59.218 - }
59.219 -
59.220 - @Override
59.221 - public boolean isInteractive() {
59.222 - return false;
59.223 - }
59.224 - }
59.225 -}
60.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/SurroundWith.java Fri Sep 18 16:20:24 2015 -0500
60.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
60.3 @@ -1,377 +0,0 @@
60.4 -/*
60.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
60.6 - *
60.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
60.8 - *
60.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
60.10 - * Other names may be trademarks of their respective owners.
60.11 - *
60.12 - * The contents of this file are subject to the terms of either the GNU
60.13 - * General Public License Version 2 only ("GPL") or the Common
60.14 - * Development and Distribution License("CDDL") (collectively, the
60.15 - * "License"). You may not use this file except in compliance with the
60.16 - * License. You can obtain a copy of the License at
60.17 - * http://www.netbeans.org/cddl-gplv2.html
60.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
60.19 - * specific language governing permissions and limitations under the
60.20 - * License. When distributing the software, include this License Header
60.21 - * Notice in each file and include the License file at
60.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
60.23 - * particular file as subject to the "Classpath" exception as provided
60.24 - * by Oracle in the GPL Version 2 section of the License file that
60.25 - * accompanied this code. If applicable, add the following below the
60.26 - * License Header, with the fields enclosed by brackets [] replaced by
60.27 - * your own identifying information:
60.28 - * "Portions Copyrighted [year] [name of copyright owner]"
60.29 - *
60.30 - * Contributor(s):
60.31 - *
60.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
60.33 - */
60.34 -package org.netbeans.modules.python.editor.hints;
60.35 -
60.36 -import java.util.ArrayList;
60.37 -import java.util.List;
60.38 -import java.util.prefs.Preferences;
60.39 -import javax.swing.JComponent;
60.40 -import javax.swing.text.JTextComponent;
60.41 -import javax.swing.text.Position;
60.42 -import org.netbeans.editor.BaseDocument;
60.43 -import org.netbeans.editor.Utilities;
60.44 -import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
60.45 -import org.netbeans.modules.csl.api.EditList;
60.46 -import org.netbeans.modules.csl.api.Hint;
60.47 -import org.netbeans.modules.csl.api.HintFix;
60.48 -import org.netbeans.modules.csl.api.HintSeverity;
60.49 -import org.netbeans.modules.csl.api.OffsetRange;
60.50 -import org.netbeans.modules.csl.api.PreviewableFix;
60.51 -import org.netbeans.modules.csl.api.RuleContext;
60.52 -import org.netbeans.modules.csl.spi.GsfUtilities;
60.53 -import org.netbeans.modules.editor.indent.api.IndentUtils;
60.54 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
60.55 -import org.openide.util.Exceptions;
60.56 -import org.openide.util.NbBundle;
60.57 -import org.python.antlr.PythonTree;
60.58 -import org.python.antlr.Visitor;
60.59 -import org.python.antlr.ast.ClassDef;
60.60 -import org.python.antlr.ast.FunctionDef;
60.61 -import org.python.antlr.ast.Import;
60.62 -import org.python.antlr.ast.ImportFrom;
60.63 -
60.64 -/**
60.65 - * Offer to surround code with for example try/except/finally
60.66 - *
60.67 - * @author Tor Norbye
60.68 - */
60.69 -public class SurroundWith extends PythonSelectionRule {
60.70 - @Override
60.71 - protected int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange) {
60.72 - if (!ApplicabilityVisitor.applies(root, astRange)) {
60.73 - return 0;
60.74 - }
60.75 -
60.76 - return 1;
60.77 - }
60.78 -
60.79 - @Override
60.80 - public void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability) {
60.81 - int start = range.getStart();
60.82 - int end = range.getEnd();
60.83 -
60.84 - // Adjust the fix range to be right around the dot so that the light bulb ends up
60.85 - // on the same line as the caret and alt-enter works
60.86 - JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
60.87 - if (target != null) {
60.88 - int dot = target.getCaret().getDot();
60.89 - range = new OffsetRange(dot, dot);
60.90 - }
60.91 -
60.92 - List<HintFix> fixList = new ArrayList<>(3);
60.93 - fixList.add(new SurroundWithFix(context, start, end, false, true));
60.94 - fixList.add(new SurroundWithFix(context, start, end, true, true));
60.95 - fixList.add(new SurroundWithFix(context, start, end, true, false));
60.96 - String displayName = getDisplayName();
60.97 - Hint desc = new Hint(this, displayName, context.parserResult.getSnapshot().getSource().getFileObject(),
60.98 - range, fixList, 1500);
60.99 - result.add(desc);
60.100 - }
60.101 -
60.102 - @Override
60.103 - public boolean appliesTo(RuleContext context) {
60.104 - return true;
60.105 - }
60.106 -
60.107 - @Override
60.108 - public String getDisplayName() {
60.109 - return NbBundle.getMessage(SurroundWith.class, "SurroundWith");
60.110 - }
60.111 -
60.112 - @Override
60.113 - public boolean showInTasklist() {
60.114 - return false;
60.115 - }
60.116 -
60.117 - @Override
60.118 - public HintSeverity getDefaultSeverity() {
60.119 - return HintSeverity.CURRENT_LINE_WARNING;
60.120 - }
60.121 -
60.122 - @Override
60.123 - public String getId() {
60.124 - return "SurroundWith"; // NOI18N
60.125 - }
60.126 -
60.127 - @Override
60.128 - public String getDescription() {
60.129 - return "";
60.130 - }
60.131 -
60.132 - @Override
60.133 - public boolean getDefaultEnabled() {
60.134 - return true;
60.135 - }
60.136 -
60.137 - @Override
60.138 - public JComponent getCustomizer(Preferences node) {
60.139 - return null;
60.140 - }
60.141 -
60.142 - private static class SurroundWithFix implements PreviewableFix {
60.143 - private final PythonRuleContext context;
60.144 - private final boolean includeFinally;
60.145 - private final boolean includeExcept;
60.146 - private Position startPos;
60.147 - private Position endPos;
60.148 - private Position codeTemplatePos;
60.149 - private String codeTemplateText;
60.150 - private final int start;
60.151 - private final int end;
60.152 -
60.153 - private SurroundWithFix(PythonRuleContext context,
60.154 - int start, int end,
60.155 - boolean includeFinally, boolean includeExcept) {
60.156 - assert includeExcept || includeFinally;
60.157 -
60.158 - this.context = context;
60.159 -
60.160 - OffsetRange range = PythonLexerUtils.narrow(context.doc, new OffsetRange(start, end), false);
60.161 - this.start = range.getStart();
60.162 - this.end = range.getEnd();
60.163 - this.includeFinally = includeFinally;
60.164 - this.includeExcept = includeExcept;
60.165 - }
60.166 -
60.167 - @Override
60.168 - public String getDescription() {
60.169 - if (includeExcept && includeFinally) {
60.170 - return NbBundle.getMessage(CreateDocString.class, "SurroundWithTEF");
60.171 - } else if (includeExcept) {
60.172 - return NbBundle.getMessage(CreateDocString.class, "SurroundWithTE");
60.173 - } else {
60.174 - assert includeFinally;
60.175 - return NbBundle.getMessage(CreateDocString.class, "SurroundWithTF");
60.176 - }
60.177 - }
60.178 -
60.179 - @Override
60.180 - public boolean canPreview() {
60.181 - return true;
60.182 - }
60.183 -
60.184 - @Override
60.185 - public EditList getEditList() throws Exception {
60.186 - return getEditList(true);
60.187 - }
60.188 -
60.189 - private EditList getEditList(boolean previewOnly) throws Exception {
60.190 - BaseDocument doc = context.doc;
60.191 - EditList edits = new EditList(doc);
60.192 -
60.193 - int indentSize = IndentUtils.indentLevelSize(doc);
60.194 - String oneIndent = IndentUtils.createIndentString(doc, indentSize);
60.195 - //int initialIndent = GsfUtilities.getLineIndent(doc, start);
60.196 - int lineStart = Utilities.getRowStart(doc, start);
60.197 - String initialIndentStr = IndentUtils.createIndentString(doc, IndentUtils.lineIndent(doc, lineStart));
60.198 - int nextLine = Utilities.getRowEnd(doc, end) + 1;
60.199 - if (nextLine > doc.getLength()) {
60.200 - nextLine = doc.getLength();
60.201 - edits.replace(nextLine, 0, "\n", false, 1);
60.202 - }
60.203 -
60.204 - // Indent the selected lines
60.205 - edits.replace(lineStart, 0, initialIndentStr + "try:\n", false, 1);
60.206 - for (int offset = start; offset < end; offset = Utilities.getRowEnd(doc, offset) + 1) {
60.207 - edits.replace(offset, 0, oneIndent, false, 1);
60.208 - }
60.209 -
60.210 - StringBuilder sb = new StringBuilder();
60.211 - if (includeExcept) {
60.212 - sb.append(initialIndentStr);
60.213 - sb.append("except ");
60.214 - if (!previewOnly) {
60.215 - sb.append("${except default=\"");
60.216 - }
60.217 - sb.append("Exception, e");
60.218 - if (!previewOnly) {
60.219 - sb.append("\"}");
60.220 - }
60.221 - sb.append(":\n");
60.222 - sb.append(initialIndentStr);
60.223 - sb.append(oneIndent);
60.224 - int caretDelta = sb.length();
60.225 - startPos = edits.createPosition(nextLine + caretDelta);
60.226 - if (!previewOnly) {
60.227 - sb.append("${action default=\"");
60.228 - }
60.229 - sb.append("print \"Exception: \", e");
60.230 - if (!previewOnly) {
60.231 - sb.append("\"}");
60.232 - }
60.233 - caretDelta = sb.length();
60.234 - endPos = edits.createPosition(nextLine + caretDelta);
60.235 - sb.append("\n");
60.236 - if (!previewOnly && !includeExcept) {
60.237 - sb.append("${cursor}");
60.238 - }
60.239 - }
60.240 - if (includeFinally) {
60.241 - sb.append(initialIndentStr);
60.242 - sb.append("finally:\n");
60.243 - sb.append(initialIndentStr);
60.244 - sb.append(oneIndent);
60.245 - if (!previewOnly) {
60.246 - sb.append("${finally default=\"\"}\n${cursor}");
60.247 - }
60.248 - int caretDelta = sb.length();
60.249 - if (!includeExcept) {
60.250 - endPos = startPos = edits.createPosition(nextLine + caretDelta);
60.251 - }
60.252 - sb.append("\n");
60.253 - }
60.254 - if (previewOnly) {
60.255 - edits.replace(nextLine, 0, sb.toString(), false, 1);
60.256 - } else {
60.257 - codeTemplatePos = edits.createPosition(nextLine, Position.Bias.Backward);
60.258 - codeTemplateText = sb.toString();
60.259 - }
60.260 -
60.261 - return edits;
60.262 - }
60.263 -
60.264 - @Override
60.265 - public void implement() throws Exception {
60.266 - EditList edits = getEditList(true);
60.267 -
60.268 - JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
60.269 - edits.apply();
60.270 - if (target != null) {
60.271 - if (codeTemplateText != null && codeTemplatePos != null) {
60.272 - final CodeTemplateManager ctm = CodeTemplateManager.get(context.doc);
60.273 - if (ctm != null) {
60.274 - target.getCaret().setDot(codeTemplatePos.getOffset());
60.275 - ctm.createTemporary(codeTemplateText).insert(target);
60.276 - }
60.277 - } else if (startPos != null && endPos != null) {
60.278 - target.setSelectionStart(startPos.getOffset());
60.279 - target.setSelectionEnd(endPos.getOffset());
60.280 - }
60.281 - }
60.282 - }
60.283 -
60.284 - @Override
60.285 - public boolean isSafe() {
60.286 - return true;
60.287 - }
60.288 -
60.289 - @Override
60.290 - public boolean isInteractive() {
60.291 - return false;
60.292 - }
60.293 - }
60.294 -
60.295 - /** @todo Prune search in traverse, ala AstPath.
60.296 - * @todo Build up start and end AstPaths.
60.297 - */
60.298 - private static class ApplicabilityVisitor extends Visitor {
60.299 - private boolean applies = true;
60.300 - private final int start;
60.301 - private final int end;
60.302 -
60.303 - static boolean applies(PythonTree root, OffsetRange astRange) {
60.304 - ApplicabilityVisitor visitor = new ApplicabilityVisitor(astRange);
60.305 - try {
60.306 - visitor.visit(root);
60.307 - } catch (Exception ex) {
60.308 - Exceptions.printStackTrace(ex);
60.309 - return false;
60.310 - }
60.311 - return visitor.isApplicable();
60.312 - }
60.313 -
60.314 - ApplicabilityVisitor(OffsetRange astRange) {
60.315 - this.start = astRange.getStart();
60.316 - this.end = astRange.getEnd();
60.317 - }
60.318 -
60.319 - public boolean isApplicable() {
60.320 - return applies;
60.321 - }
60.322 -
60.323 - private void maybeBail(PythonTree node) {
60.324 - int nodeStart = node.getCharStartIndex();
60.325 - int nodeEnd = node.getCharStopIndex();
60.326 - if (nodeStart >= start && nodeStart < end) {
60.327 - applies = false;
60.328 - }
60.329 - if (nodeEnd > start && nodeEnd < end) {
60.330 - applies = false;
60.331 - }
60.332 - }
60.333 -
60.334 - @Override
60.335 - public void traverse(PythonTree node) throws Exception {
60.336 - if (!applies) {
60.337 - return;
60.338 - }
60.339 -
60.340 - int nodeStart = node.getCharStartIndex();
60.341 - int nodeStop = node.getCharStopIndex();
60.342 - //if (!(nodeStop < start || nodeStart > end)) {
60.343 - if (nodeStop >= start && nodeStart <= end) {
60.344 - super.traverse(node);
60.345 - }
60.346 - }
60.347 -
60.348 - @Override
60.349 - public Object visitClassDef(ClassDef node) throws Exception {
60.350 - maybeBail(node);
60.351 - return super.visitClassDef(node);
60.352 - }
60.353 -
60.354 - @Override
60.355 - public Object visitFunctionDef(FunctionDef node) throws Exception {
60.356 - maybeBail(node);
60.357 - return super.visitFunctionDef(node);
60.358 - }
60.359 -
60.360 - @Override
60.361 - public Object visitImport(Import node) throws Exception {
60.362 - maybeBail(node);
60.363 - return super.visitImport(node);
60.364 - }
60.365 -
60.366 - @Override
60.367 - public Object visitImportFrom(ImportFrom node) throws Exception {
60.368 - maybeBail(node);
60.369 - return super.visitImportFrom(node);
60.370 - }
60.371 -
60.372 - // Module is okay - you get this when you select all text in a simple "script" file
60.373 - // with only statements
60.374 - //@Override
60.375 - //public Object visitModule(Module node) throws Exception {
60.376 - // maybeBail(node);
60.377 - // return super.visitModule(node);
60.378 - //}
60.379 - }
60.380 -}
61.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnresolvedClassComponents.java Fri Sep 18 16:20:24 2015 -0500
61.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
61.3 @@ -1,207 +0,0 @@
61.4 -/*
61.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
61.6 - *
61.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
61.8 - *
61.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
61.10 - * Other names may be trademarks of their respective owners.
61.11 - *
61.12 - * The contents of this file are subject to the terms of either the GNU
61.13 - * General Public License Version 2 only ("GPL") or the Common
61.14 - * Development and Distribution License("CDDL") (collectively, the
61.15 - * "License"). You may not use this file except in compliance with the
61.16 - * License. You can obtain a copy of the License at
61.17 - * http://www.netbeans.org/cddl-gplv2.html
61.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
61.19 - * specific language governing permissions and limitations under the
61.20 - * License. When distributing the software, include this License Header
61.21 - * Notice in each file and include the License file at
61.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
61.23 - * particular file as subject to the "Classpath" exception as provided
61.24 - * by Oracle in the GPL Version 2 section of the License file that
61.25 - * accompanied this code. If applicable, add the following below the
61.26 - * License Header, with the fields enclosed by brackets [] replaced by
61.27 - * your own identifying information:
61.28 - * "Portions Copyrighted [year] [name of copyright owner]"
61.29 - *
61.30 - * If you wish your version of this file to be governed by only the CDDL
61.31 - * or only the GPL Version 2, indicate your decision by adding
61.32 - * "[Contributor] elects to include this software in this distribution
61.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
61.34 - * single choice of license, a recipient has the option to distribute
61.35 - * your version of this file under either the CDDL, the GPL Version 2 or
61.36 - * to extend the choice of license to its licensees as provided above.
61.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
61.38 - * Version 2 license, then the option applies only if the new code is
61.39 - * made subject to such option by the copyright holder.
61.40 - *
61.41 - * Contributor(s):
61.42 - *
61.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
61.44 - */
61.45 -package org.netbeans.modules.python.editor.hints;
61.46 -
61.47 -import java.util.Collections;
61.48 -import java.util.List;
61.49 -import java.util.Set;
61.50 -import java.util.prefs.Preferences;
61.51 -import javax.swing.JComponent;
61.52 -import org.netbeans.modules.csl.api.Hint;
61.53 -import org.netbeans.modules.csl.api.HintFix;
61.54 -import org.netbeans.modules.csl.api.HintSeverity;
61.55 -import org.netbeans.modules.csl.api.OffsetRange;
61.56 -import org.netbeans.modules.csl.api.RuleContext;
61.57 -import org.netbeans.modules.python.editor.PythonAstUtils;
61.58 -import org.netbeans.modules.python.editor.PythonParserResult;
61.59 -import org.netbeans.modules.python.editor.imports.ImportManager;
61.60 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
61.61 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
61.62 -import org.openide.util.NbBundle;
61.63 -import org.python.antlr.PythonTree;
61.64 -import org.python.antlr.ast.Module;
61.65 -
61.66 -/**
61.67 - * Detect Unresolved class attributes
61.68 - *
61.69 - * @author Jean-Yves Mengant
61.70 - */
61.71 -public class UnresolvedClassComponents extends PythonAstRule {
61.72 -
61.73 - private final static String CLASS_UNRESOLVED_ATTRIBUTES = "UnresolvedAttributes";
61.74 - private final static String CLASS_UNRESOLVED_INHERITANCE_VAR = "UnresolvedInheritanceVariable";
61.75 - private final static String CLASS_UNRESOLVED_ATTRIBUTES_VAR = "UnresolvedAttributesVariable";
61.76 - private final static String CLASS_UNRESOLVED_ATTRIBUTES_DESC = "UnresolvedAttributesDesc";
61.77 -
61.78 -
61.79 -
61.80 - public UnresolvedClassComponents() {
61.81 - }
61.82 -
61.83 - @Override
61.84 - public boolean appliesTo(RuleContext context) {
61.85 - return true;
61.86 - }
61.87 -
61.88 - @Override
61.89 - public Set<Class> getKinds() {
61.90 - return Collections.<Class>singleton(Module.class);
61.91 - }
61.92 -
61.93 - private void populateMessages( PythonParserResult info, List<PythonTree> unresolved , List<Hint> result ,boolean isClass ) {
61.94 - if (unresolved.size() > 0) {
61.95 -
61.96 - for (PythonTree node : unresolved) {
61.97 - // Compute suggestions
61.98 - String name = PythonAstUtils.getName(node);
61.99 - if (name == null) {
61.100 - name = "";
61.101 - }
61.102 - List<HintFix> fixList = Collections.emptyList();
61.103 - String message ;
61.104 - if ( isClass)
61.105 - message = NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_INHERITANCE_VAR, name);
61.106 - else
61.107 - message = NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES_VAR, name);
61.108 - OffsetRange range = PythonAstUtils.getRange( node);
61.109 - range = PythonLexerUtils.getLexerOffsets(info, range);
61.110 - if (range != OffsetRange.NONE) {
61.111 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
61.112 - result.add(desc);
61.113 - }
61.114 - }
61.115 - }
61.116 - }
61.117 -
61.118 -
61.119 - @Override
61.120 - public void run(PythonRuleContext context, List<Hint> result) {
61.121 - PythonParserResult info = (PythonParserResult) context.parserResult;
61.122 - SymbolTable symbolTable = info.getSymbolTable();
61.123 -
61.124 - List<PythonTree> unresolvedAttributes = symbolTable.getUnresolvedAttributes(info);
61.125 - populateMessages(info,unresolvedAttributes,result,false) ;
61.126 - List<PythonTree> unresolvedParents = symbolTable.getUnresolvedParents(info);
61.127 - populateMessages(info,unresolvedParents,result,true) ;
61.128 - }
61.129 -
61.130 - @Override
61.131 - public String getId() {
61.132 - return CLASS_UNRESOLVED_ATTRIBUTES; // NOI18N
61.133 - }
61.134 -
61.135 - @Override
61.136 - public String getDisplayName() {
61.137 - return NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES);
61.138 - }
61.139 -
61.140 - @Override
61.141 - public String getDescription() {
61.142 - return NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES_DESC);
61.143 - }
61.144 -
61.145 - @Override
61.146 - public boolean getDefaultEnabled() {
61.147 - return false;
61.148 - }
61.149 -
61.150 - @Override
61.151 - public boolean showInTasklist() {
61.152 - return true;
61.153 - }
61.154 -
61.155 - @Override
61.156 - public HintSeverity getDefaultSeverity() {
61.157 - return HintSeverity.ERROR;
61.158 - }
61.159 -
61.160 - @Override
61.161 - public JComponent getCustomizer(Preferences node) {
61.162 - return null;
61.163 - }
61.164 -
61.165 - private static class ImportFix implements HintFix {
61.166 - private final PythonRuleContext context;
61.167 - private final PythonTree node;
61.168 - private final String module;
61.169 -
61.170 - private ImportFix(PythonRuleContext context, PythonTree node, String module) {
61.171 - this.context = context;
61.172 - this.node = node;
61.173 - this.module = module;
61.174 - }
61.175 -
61.176 - @Override
61.177 - public String getDescription() {
61.178 - return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
61.179 - }
61.180 -
61.181 - @Override
61.182 - public void implement() throws Exception {
61.183 - String mod = this.module;
61.184 - String symbol = null;
61.185 - int colon = mod.indexOf(':');
61.186 - if (colon != -1) {
61.187 - int end = mod.indexOf('(', colon + 1);
61.188 - if (end == -1) {
61.189 - end = mod.indexOf(';', colon + 1);
61.190 - if (end == -1) {
61.191 - end = mod.length();
61.192 - }
61.193 - }
61.194 - symbol = mod.substring(colon + 1, end).trim();
61.195 - mod = mod.substring(0, colon).trim();
61.196 - }
61.197 - new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
61.198 - }
61.199 -
61.200 - @Override
61.201 - public boolean isSafe() {
61.202 - return true;
61.203 - }
61.204 -
61.205 - @Override
61.206 - public boolean isInteractive() {
61.207 - return false;
61.208 - }
61.209 - }
61.210 -}
62.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnresolvedDetector.java Fri Sep 18 16:20:24 2015 -0500
62.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
62.3 @@ -1,233 +0,0 @@
62.4 -/*
62.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
62.6 - *
62.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
62.8 - *
62.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
62.10 - * Other names may be trademarks of their respective owners.
62.11 - *
62.12 - * The contents of this file are subject to the terms of either the GNU
62.13 - * General Public License Version 2 only ("GPL") or the Common
62.14 - * Development and Distribution License("CDDL") (collectively, the
62.15 - * "License"). You may not use this file except in compliance with the
62.16 - * License. You can obtain a copy of the License at
62.17 - * http://www.netbeans.org/cddl-gplv2.html
62.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
62.19 - * specific language governing permissions and limitations under the
62.20 - * License. When distributing the software, include this License Header
62.21 - * Notice in each file and include the License file at
62.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
62.23 - * particular file as subject to the "Classpath" exception as provided
62.24 - * by Oracle in the GPL Version 2 section of the License file that
62.25 - * accompanied this code. If applicable, add the following below the
62.26 - * License Header, with the fields enclosed by brackets [] replaced by
62.27 - * your own identifying information:
62.28 - * "Portions Copyrighted [year] [name of copyright owner]"
62.29 - *
62.30 - * If you wish your version of this file to be governed by only the CDDL
62.31 - * or only the GPL Version 2, indicate your decision by adding
62.32 - * "[Contributor] elects to include this software in this distribution
62.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
62.34 - * single choice of license, a recipient has the option to distribute
62.35 - * your version of this file under either the CDDL, the GPL Version 2 or
62.36 - * to extend the choice of license to its licensees as provided above.
62.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
62.38 - * Version 2 license, then the option applies only if the new code is
62.39 - * made subject to such option by the copyright holder.
62.40 - *
62.41 - * Contributor(s):
62.42 - *
62.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
62.44 - */
62.45 -package org.netbeans.modules.python.editor.hints;
62.46 -
62.47 -import java.util.ArrayList;
62.48 -import java.util.Collections;
62.49 -import java.util.List;
62.50 -import java.util.Set;
62.51 -import java.util.prefs.Preferences;
62.52 -import javax.swing.JComponent;
62.53 -import org.netbeans.modules.csl.api.Hint;
62.54 -import org.netbeans.modules.csl.api.HintFix;
62.55 -import org.netbeans.modules.csl.api.HintSeverity;
62.56 -import org.netbeans.modules.csl.api.OffsetRange;
62.57 -import org.netbeans.modules.csl.api.RuleContext;
62.58 -import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
62.59 -import org.netbeans.modules.python.editor.PythonAstUtils;
62.60 -import org.netbeans.modules.python.editor.PythonIndex;
62.61 -import org.netbeans.modules.python.editor.PythonParserResult;
62.62 -import org.netbeans.modules.python.editor.elements.IndexedElement;
62.63 -import org.netbeans.modules.python.editor.imports.ImportManager;
62.64 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
62.65 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
62.66 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
62.67 -import org.openide.util.NbBundle;
62.68 -import org.python.antlr.PythonTree;
62.69 -import org.python.antlr.ast.Attribute;
62.70 -import org.python.antlr.ast.Call;
62.71 -import org.python.antlr.ast.Module;
62.72 -
62.73 -/**
62.74 - * Detect Unresolved variables
62.75 - *
62.76 - * @author Tor Norbye
62.77 - */
62.78 -public class UnresolvedDetector extends PythonAstRule {
62.79 - public UnresolvedDetector() {
62.80 - }
62.81 -
62.82 - @Override
62.83 - public boolean appliesTo(RuleContext context) {
62.84 - return true;
62.85 - }
62.86 -
62.87 - @Override
62.88 - public Set<Class> getKinds() {
62.89 - return Collections.<Class>singleton(Module.class);
62.90 - }
62.91 -
62.92 - @Override
62.93 - public void run(PythonRuleContext context, List<Hint> result) {
62.94 - PythonParserResult info = (PythonParserResult) context.parserResult;
62.95 - SymbolTable symbolTable = info.getSymbolTable();
62.96 -
62.97 - List<PythonTree> unresolvedNames = symbolTable.getUnresolved(info);
62.98 - if (unresolvedNames.size() > 0) {
62.99 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
62.100 -
62.101 - for (PythonTree node : unresolvedNames) {
62.102 - // Compute suggestions
62.103 - String name = PythonAstUtils.getName(node);
62.104 - if (name == null) {
62.105 - name = "";
62.106 - }
62.107 - // Ignore keywords and builtin
62.108 - if (PythonLexerUtils.isKeywordOrBuiltin(name)) {
62.109 - continue;
62.110 - }
62.111 -
62.112 - List<HintFix> fixList = new ArrayList<>(3);
62.113 - // Is is a reference to a module?
62.114 - boolean tryModule = false;
62.115 - if (node.getParent() instanceof Call) {
62.116 - Call call = (Call)node.getParent();
62.117 - PythonTree t = call.getInternalFunc();
62.118 - if (t instanceof Attribute) {
62.119 - tryModule = true;
62.120 - }
62.121 - }
62.122 - String message = NbBundle.getMessage(NameRule.class, "UnresolvedVariable", name);
62.123 - if (name.equals("true")) { // NOI18N
62.124 - // Help for new language converts...
62.125 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "True"); // NOI18N
62.126 - } else if (name.equals("false")) {
62.127 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "False"); // NOI18N
62.128 - } else if (name.equals("nil") || name.equals("null")) {
62.129 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "None"); // NOI18N
62.130 - } else if (name.equals("this")) {
62.131 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "self"); // NOI18N
62.132 - } else if (tryModule) {
62.133 - Set<IndexedElement> moduleElements = index.getModules(name, QuerySupport.Kind.EXACT);
62.134 - if (moduleElements.size() > 0) {
62.135 - fixList.add(new ImportFix(context, node, name));
62.136 - }
62.137 - } else {
62.138 - Set<String> modules = index.getImportsFor(name, true);
62.139 - if (modules.size() > 0) {
62.140 - for (String module : modules) {
62.141 - fixList.add(new ImportFix(context, node, module));
62.142 - }
62.143 - }
62.144 - }
62.145 -
62.146 - OffsetRange range = PythonAstUtils.getNameRange(info, node);
62.147 - range = PythonLexerUtils.getLexerOffsets(info, range);
62.148 - if (range != OffsetRange.NONE) {
62.149 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
62.150 - result.add(desc);
62.151 - }
62.152 - }
62.153 - }
62.154 - }
62.155 -
62.156 - @Override
62.157 - public String getId() {
62.158 - return "Unresolved"; // NOI18N
62.159 - }
62.160 -
62.161 - @Override
62.162 - public String getDisplayName() {
62.163 - return NbBundle.getMessage(NameRule.class, "Unresolved");
62.164 - }
62.165 -
62.166 - @Override
62.167 - public String getDescription() {
62.168 - return NbBundle.getMessage(NameRule.class, "UnresolvedDesc");
62.169 - }
62.170 -
62.171 - @Override
62.172 - public boolean getDefaultEnabled() {
62.173 - return false;
62.174 - }
62.175 -
62.176 - @Override
62.177 - public boolean showInTasklist() {
62.178 - return true;
62.179 - }
62.180 -
62.181 - @Override
62.182 - public HintSeverity getDefaultSeverity() {
62.183 - return HintSeverity.ERROR;
62.184 - }
62.185 -
62.186 - @Override
62.187 - public JComponent getCustomizer(Preferences node) {
62.188 - return null;
62.189 - }
62.190 -
62.191 - private static class ImportFix implements HintFix {
62.192 - private final PythonRuleContext context;
62.193 - private final PythonTree node;
62.194 - private final String module;
62.195 -
62.196 - private ImportFix(PythonRuleContext context, PythonTree node, String module) {
62.197 - this.context = context;
62.198 - this.node = node;
62.199 - this.module = module;
62.200 - }
62.201 -
62.202 - @Override
62.203 - public String getDescription() {
62.204 - return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
62.205 - }
62.206 -
62.207 - @Override
62.208 - public void implement() throws Exception {
62.209 - String mod = this.module;
62.210 - String symbol = null;
62.211 - int colon = mod.indexOf(':');
62.212 - if (colon != -1) {
62.213 - int end = mod.indexOf('(', colon + 1);
62.214 - if (end == -1) {
62.215 - end = mod.indexOf(';', colon + 1);
62.216 - if (end == -1) {
62.217 - end = mod.length();
62.218 - }
62.219 - }
62.220 - symbol = mod.substring(colon + 1, end).trim();
62.221 - mod = mod.substring(0, colon).trim();
62.222 - }
62.223 - new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
62.224 - }
62.225 -
62.226 - @Override
62.227 - public boolean isSafe() {
62.228 - return true;
62.229 - }
62.230 -
62.231 - @Override
62.232 - public boolean isInteractive() {
62.233 - return false;
62.234 - }
62.235 - }
62.236 -}
63.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnusedDetector.java Fri Sep 18 16:20:24 2015 -0500
63.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
63.3 @@ -1,244 +0,0 @@
63.4 -/*
63.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
63.6 - *
63.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
63.8 - *
63.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
63.10 - * Other names may be trademarks of their respective owners.
63.11 - *
63.12 - * The contents of this file are subject to the terms of either the GNU
63.13 - * General Public License Version 2 only ("GPL") or the Common
63.14 - * Development and Distribution License("CDDL") (collectively, the
63.15 - * "License"). You may not use this file except in compliance with the
63.16 - * License. You can obtain a copy of the License at
63.17 - * http://www.netbeans.org/cddl-gplv2.html
63.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
63.19 - * specific language governing permissions and limitations under the
63.20 - * License. When distributing the software, include this License Header
63.21 - * Notice in each file and include the License file at
63.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
63.23 - * particular file as subject to the "Classpath" exception as provided
63.24 - * by Oracle in the GPL Version 2 section of the License file that
63.25 - * accompanied this code. If applicable, add the following below the
63.26 - * License Header, with the fields enclosed by brackets [] replaced by
63.27 - * your own identifying information:
63.28 - * "Portions Copyrighted [year] [name of copyright owner]"
63.29 - *
63.30 - * If you wish your version of this file to be governed by only the CDDL
63.31 - * or only the GPL Version 2, indicate your decision by adding
63.32 - * "[Contributor] elects to include this software in this distribution
63.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
63.34 - * single choice of license, a recipient has the option to distribute
63.35 - * your version of this file under either the CDDL, the GPL Version 2 or
63.36 - * to extend the choice of license to its licensees as provided above.
63.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
63.38 - * Version 2 license, then the option applies only if the new code is
63.39 - * made subject to such option by the copyright holder.
63.40 - *
63.41 - * Contributor(s):
63.42 - *
63.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
63.44 - */
63.45 -package org.netbeans.modules.python.editor.hints;
63.46 -
63.47 -import java.util.ArrayList;
63.48 -import java.util.Collections;
63.49 -import java.util.HashSet;
63.50 -import java.util.List;
63.51 -import java.util.Set;
63.52 -import java.util.prefs.Preferences;
63.53 -import javax.swing.JComponent;
63.54 -import org.netbeans.modules.csl.api.Hint;
63.55 -import org.netbeans.modules.csl.api.HintFix;
63.56 -import org.netbeans.modules.csl.api.HintSeverity;
63.57 -import org.netbeans.modules.csl.api.OffsetRange;
63.58 -import org.netbeans.modules.csl.api.RuleContext;
63.59 -import org.netbeans.modules.python.editor.PythonAstUtils;
63.60 -import org.netbeans.modules.python.editor.PythonParserResult;
63.61 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
63.62 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
63.63 -import org.openide.util.NbBundle;
63.64 -import org.python.antlr.PythonTree;
63.65 -import org.python.antlr.ast.Assign;
63.66 -import org.python.antlr.ast.For;
63.67 -import org.python.antlr.ast.Module;
63.68 -import org.python.antlr.ast.Tuple;
63.69 -import org.python.antlr.base.expr;
63.70 -
63.71 -/**
63.72 - * Detect unused variables
63.73 - *
63.74 - * @todo Find a more reliable way of detecting return tuples without relying on the
63.75 - * parent reference
63.76 - *
63.77 - * @author Tor Norbye
63.78 - */
63.79 -public class UnusedDetector extends PythonAstRule {
63.80 - /** Default names ignored */
63.81 - private static final String DEFAULT_IGNORED_NAMES = "_, dummy";
63.82 - private static final String PARAMS_KEY = "params"; // NOI18N
63.83 - private static final String SKIP_TUPLE_ASSIGN_KEY = "skipTuples"; // NOI18N
63.84 - private static final String IGNORED_KEY = "ignorednames"; // NOI18N
63.85 -
63.86 - public UnusedDetector() {
63.87 - }
63.88 -
63.89 - @Override
63.90 - public boolean appliesTo(RuleContext context) {
63.91 - return true;
63.92 - }
63.93 -
63.94 - @Override
63.95 - public Set<Class> getKinds() {
63.96 - return Collections.<Class>singleton(Module.class);
63.97 - }
63.98 -
63.99 - @Override
63.100 - public void run(PythonRuleContext context, List<Hint> result) {
63.101 - PythonParserResult info = (PythonParserResult) context.parserResult;
63.102 - SymbolTable symbolTable = info.getSymbolTable();
63.103 -
63.104 - boolean skipParams = true;
63.105 - Preferences pref = context.manager.getPreferences(this);
63.106 - if (pref != null) {
63.107 - skipParams = getSkipParameters(pref);
63.108 - }
63.109 -
63.110 - List<PythonTree> unusedNames = symbolTable.getUnused(true, skipParams);
63.111 - if (unusedNames.size() == 0) {
63.112 - return;
63.113 - }
63.114 -
63.115 - boolean skipTupleAssigns = true;
63.116 - Set<String> ignoreNames = Collections.emptySet();
63.117 - if (pref != null) {
63.118 - skipParams = getSkipParameters(pref);
63.119 - skipTupleAssigns = getSkipTupleAssignments(pref);
63.120 - String ignoreNamesStr = getIgnoreNames(pref);
63.121 - if (ignoreNamesStr.length() > 0) {
63.122 - ignoreNames = new HashSet<>();
63.123 - for (String s : ignoreNamesStr.split(",")) { // NOI18N
63.124 - ignoreNames.add(s.trim());
63.125 - }
63.126 - }
63.127 - }
63.128 -
63.129 - for (PythonTree node : unusedNames) {
63.130 - if (skipTupleAssigns && isTupleAssignment(node)) {
63.131 - continue;
63.132 - }
63.133 - String name = PythonAstUtils.getName(node);
63.134 - if (name == null) {
63.135 - name = "";
63.136 - }
63.137 - if (ignoreNames.contains(name)) {
63.138 - continue;
63.139 - }
63.140 - OffsetRange range = PythonAstUtils.getNameRange(info, node);
63.141 - range = PythonLexerUtils.getLexerOffsets(info, range);
63.142 - if (range != OffsetRange.NONE) {
63.143 - List<HintFix> fixList = new ArrayList<>(3);
63.144 - String message = NbBundle.getMessage(NameRule.class, "UnusedVariable", name);
63.145 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
63.146 - result.add(desc);
63.147 - }
63.148 - }
63.149 - }
63.150 -
63.151 - private boolean isTupleAssignment(PythonTree node) {
63.152 - // This may not work right since the parent pointers often aren't set right;
63.153 - // find a more efficient way to do it correctly than a path search for each node
63.154 - if (node.getParent() instanceof Tuple) {
63.155 - // Allow tuples in tuples
63.156 - PythonTree parentParent = node.getParent().getParent();
63.157 - while (parentParent instanceof Tuple) {
63.158 - parentParent = parentParent.getParent();
63.159 - node = node.getParent();
63.160 - }
63.161 - if (parentParent instanceof Assign) {
63.162 - Assign assign = (Assign)parentParent;
63.163 - List<expr> targets = assign.getInternalTargets();
63.164 - if (targets != null && targets.size() > 0 && targets.get(0) == node.getParent()) {
63.165 - return true;
63.166 - }
63.167 - }
63.168 - if (parentParent instanceof For &&
63.169 - ((For)parentParent).getInternalTarget() == node.getParent()) {
63.170 - return true;
63.171 - }
63.172 - }
63.173 -
63.174 - return false;
63.175 - }
63.176 -
63.177 - @Override
63.178 - public String getId() {
63.179 - return "Unused"; // NOI18N
63.180 - }
63.181 -
63.182 - @Override
63.183 - public String getDisplayName() {
63.184 - return NbBundle.getMessage(NameRule.class, "Unused");
63.185 - }
63.186 -
63.187 - @Override
63.188 - public String getDescription() {
63.189 - return NbBundle.getMessage(NameRule.class, "UnusedDesc");
63.190 - }
63.191 -
63.192 - @Override
63.193 - public boolean getDefaultEnabled() {
63.194 - return true;
63.195 - }
63.196 -
63.197 - @Override
63.198 - public boolean showInTasklist() {
63.199 - return true;
63.200 - }
63.201 -
63.202 - @Override
63.203 - public HintSeverity getDefaultSeverity() {
63.204 - return HintSeverity.WARNING;
63.205 - }
63.206 -
63.207 - @Override
63.208 - public JComponent getCustomizer(Preferences node) {
63.209 - return new UnusedDetectorPrefs(node);
63.210 - }
63.211 -
63.212 - static boolean getSkipParameters(Preferences prefs) {
63.213 - return prefs.getBoolean(PARAMS_KEY, true);
63.214 - }
63.215 -
63.216 - static void setSkipParameters(Preferences prefs, boolean skipParams) {
63.217 - if (skipParams) {
63.218 - prefs.remove(PARAMS_KEY);
63.219 - } else {
63.220 - prefs.putBoolean(PARAMS_KEY, false);
63.221 - }
63.222 - }
63.223 -
63.224 - static boolean getSkipTupleAssignments(Preferences prefs) {
63.225 - return prefs.getBoolean(SKIP_TUPLE_ASSIGN_KEY, true);
63.226 - }
63.227 -
63.228 - static void setSkipTupleAssignments(Preferences prefs, boolean skipTupleAssigns) {
63.229 - if (skipTupleAssigns) {
63.230 - prefs.remove(SKIP_TUPLE_ASSIGN_KEY);
63.231 - } else {
63.232 - prefs.putBoolean(SKIP_TUPLE_ASSIGN_KEY, false);
63.233 - }
63.234 - }
63.235 -
63.236 - static String getIgnoreNames(Preferences prefs) {
63.237 - return prefs.get(IGNORED_KEY, DEFAULT_IGNORED_NAMES);
63.238 - }
63.239 -
63.240 - static void setIgnoreNames(Preferences prefs, String ignoredNames) {
63.241 - if (ignoredNames.length() == 0) {
63.242 - prefs.remove(IGNORED_KEY);
63.243 - } else {
63.244 - prefs.put(IGNORED_KEY, ignoredNames);
63.245 - }
63.246 - }
63.247 -}
64.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnusedDetectorPrefs.form Fri Sep 18 16:20:24 2015 -0500
64.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
64.3 @@ -1,84 +0,0 @@
64.4 -<?xml version="1.0" encoding="UTF-8" ?>
64.5 -
64.6 -<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
64.7 - <AuxValues>
64.8 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
64.9 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
64.10 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
64.11 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
64.12 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
64.13 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
64.14 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="2"/>
64.15 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
64.16 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
64.17 - </AuxValues>
64.18 -
64.19 - <Layout>
64.20 - <DimensionLayout dim="0">
64.21 - <Group type="103" groupAlignment="0" attributes="0">
64.22 - <Component id="skipParams" min="-2" max="-2" attributes="0"/>
64.23 - <Component id="skipTupleAssignments" alignment="0" min="-2" max="-2" attributes="0"/>
64.24 - <Group type="102" alignment="0" attributes="0">
64.25 - <Component id="ignoredLabel" min="-2" max="-2" attributes="0"/>
64.26 - <EmptySpace max="-2" attributes="0"/>
64.27 - <Component id="ignoredNames" min="-2" max="-2" attributes="0"/>
64.28 - </Group>
64.29 - </Group>
64.30 - </DimensionLayout>
64.31 - <DimensionLayout dim="1">
64.32 - <Group type="103" groupAlignment="0" attributes="0">
64.33 - <Group type="102" attributes="0">
64.34 - <Component id="skipParams" min="-2" max="-2" attributes="0"/>
64.35 - <EmptySpace max="-2" attributes="0"/>
64.36 - <Component id="skipTupleAssignments" min="-2" max="-2" attributes="0"/>
64.37 - <EmptySpace max="-2" attributes="0"/>
64.38 - <Group type="103" groupAlignment="3" attributes="0">
64.39 - <Component id="ignoredLabel" alignment="3" min="-2" max="-2" attributes="0"/>
64.40 - <Component id="ignoredNames" alignment="3" min="-2" max="-2" attributes="0"/>
64.41 - </Group>
64.42 - <EmptySpace max="32767" attributes="0"/>
64.43 - </Group>
64.44 - </Group>
64.45 - </DimensionLayout>
64.46 - </Layout>
64.47 - <SubComponents>
64.48 - <Component class="javax.swing.JCheckBox" name="skipParams">
64.49 - <Properties>
64.50 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
64.51 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.skipParams.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
64.52 - </Property>
64.53 - </Properties>
64.54 - <Events>
64.55 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
64.56 - </Events>
64.57 - </Component>
64.58 - <Component class="javax.swing.JCheckBox" name="skipTupleAssignments">
64.59 - <Properties>
64.60 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
64.61 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.skipTupleAssignments.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
64.62 - </Property>
64.63 - </Properties>
64.64 - <Events>
64.65 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
64.66 - </Events>
64.67 - </Component>
64.68 - <Component class="javax.swing.JTextField" name="ignoredNames">
64.69 - <Properties>
64.70 - <Property name="columns" type="int" value="25"/>
64.71 - </Properties>
64.72 - <Events>
64.73 - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
64.74 - </Events>
64.75 - </Component>
64.76 - <Component class="javax.swing.JLabel" name="ignoredLabel">
64.77 - <Properties>
64.78 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
64.79 - <ComponentRef name="ignoredNames"/>
64.80 - </Property>
64.81 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
64.82 - <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.ignoredLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
64.83 - </Property>
64.84 - </Properties>
64.85 - </Component>
64.86 - </SubComponents>
64.87 -</Form>
65.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnusedDetectorPrefs.java Fri Sep 18 16:20:24 2015 -0500
65.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
65.3 @@ -1,152 +0,0 @@
65.4 -/*
65.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
65.6 - *
65.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
65.8 - *
65.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
65.10 - * Other names may be trademarks of their respective owners.
65.11 - *
65.12 - * The contents of this file are subject to the terms of either the GNU
65.13 - * General Public License Version 2 only ("GPL") or the Common
65.14 - * Development and Distribution License("CDDL") (collectively, the
65.15 - * "License"). You may not use this file except in compliance with the
65.16 - * License. You can obtain a copy of the License at
65.17 - * http://www.netbeans.org/cddl-gplv2.html
65.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
65.19 - * specific language governing permissions and limitations under the
65.20 - * License. When distributing the software, include this License Header
65.21 - * Notice in each file and include the License file at
65.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
65.23 - * particular file as subject to the "Classpath" exception as provided
65.24 - * by Oracle in the GPL Version 2 section of the License file that
65.25 - * accompanied this code. If applicable, add the following below the
65.26 - * License Header, with the fields enclosed by brackets [] replaced by
65.27 - * your own identifying information:
65.28 - * "Portions Copyrighted [year] [name of copyright owner]"
65.29 - *
65.30 - * If you wish your version of this file to be governed by only the CDDL
65.31 - * or only the GPL Version 2, indicate your decision by adding
65.32 - * "[Contributor] elects to include this software in this distribution
65.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
65.34 - * single choice of license, a recipient has the option to distribute
65.35 - * your version of this file under either the CDDL, the GPL Version 2 or
65.36 - * to extend the choice of license to its licensees as provided above.
65.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
65.38 - * Version 2 license, then the option applies only if the new code is
65.39 - * made subject to such option by the copyright holder.
65.40 - *
65.41 - * Contributor(s):
65.42 - *
65.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
65.44 - */
65.45 -
65.46 -/*
65.47 - * UnusedDetectorPrefs.java
65.48 - *
65.49 - * Created on Nov 10, 2008, 9:48:35 AM
65.50 - */
65.51 -package org.netbeans.modules.python.editor.hints;
65.52 -
65.53 -import java.awt.event.ActionListener;
65.54 -import java.util.prefs.Preferences;
65.55 -
65.56 -/**
65.57 - * Preferences where users can configure the unused detector rules
65.58 - *
65.59 - * @author Tor Norbye
65.60 - */
65.61 -public class UnusedDetectorPrefs extends javax.swing.JPanel implements ActionListener {
65.62 - private Preferences prefs;
65.63 -
65.64 - /** Creates new form UnusedDetectorPrefs */
65.65 - public UnusedDetectorPrefs(Preferences prefs) {
65.66 - initComponents();
65.67 - this.prefs = prefs;
65.68 - skipParams.setSelected(UnusedDetector.getSkipParameters(prefs));
65.69 - skipTupleAssignments.setSelected(UnusedDetector.getSkipTupleAssignments(prefs));
65.70 - String ignore = UnusedDetector.getIgnoreNames(prefs);
65.71 - if (ignore == null) {
65.72 - ignore = "";
65.73 - }
65.74 - ignoredNames.setText(ignore);
65.75 - }
65.76 -
65.77 - @SuppressWarnings("unchecked")
65.78 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
65.79 - private void initComponents() {
65.80 -
65.81 - skipParams = new javax.swing.JCheckBox();
65.82 - skipTupleAssignments = new javax.swing.JCheckBox();
65.83 - ignoredNames = new javax.swing.JTextField();
65.84 - ignoredLabel = new javax.swing.JLabel();
65.85 -
65.86 - skipParams.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.skipParams.text")); // NOI18N
65.87 - skipParams.addActionListener(this);
65.88 -
65.89 - skipTupleAssignments.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.skipTupleAssignments.text")); // NOI18N
65.90 - skipTupleAssignments.addActionListener(this);
65.91 -
65.92 - ignoredNames.setColumns(25);
65.93 - ignoredNames.addActionListener(this);
65.94 -
65.95 - ignoredLabel.setLabelFor(ignoredNames);
65.96 - ignoredLabel.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.ignoredLabel.text")); // NOI18N
65.97 -
65.98 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
65.99 - this.setLayout(layout);
65.100 - layout.setHorizontalGroup(
65.101 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
65.102 - .addComponent(skipParams)
65.103 - .addComponent(skipTupleAssignments)
65.104 - .addGroup(layout.createSequentialGroup()
65.105 - .addComponent(ignoredLabel)
65.106 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
65.107 - .addComponent(ignoredNames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
65.108 - );
65.109 - layout.setVerticalGroup(
65.110 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
65.111 - .addGroup(layout.createSequentialGroup()
65.112 - .addComponent(skipParams)
65.113 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
65.114 - .addComponent(skipTupleAssignments)
65.115 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
65.116 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
65.117 - .addComponent(ignoredLabel)
65.118 - .addComponent(ignoredNames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
65.119 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
65.120 - );
65.121 - }
65.122 -
65.123 - // Code for dispatching events from components to event handlers.
65.124 -
65.125 - public void actionPerformed(java.awt.event.ActionEvent evt) {
65.126 - if (evt.getSource() == skipParams) {
65.127 - UnusedDetectorPrefs.this.changed(evt);
65.128 - }
65.129 - else if (evt.getSource() == skipTupleAssignments) {
65.130 - UnusedDetectorPrefs.this.changed(evt);
65.131 - }
65.132 - else if (evt.getSource() == ignoredNames) {
65.133 - UnusedDetectorPrefs.this.changed(evt);
65.134 - }
65.135 - }// </editor-fold>//GEN-END:initComponents
65.136 -
65.137 - private void changed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changed
65.138 - Object source = evt.getSource();
65.139 - if (source == ignoredNames) {
65.140 - UnusedDetector.setIgnoreNames(prefs, ignoredNames.getText().trim());
65.141 - } else if (source == skipParams) {
65.142 - UnusedDetector.setSkipParameters(prefs, skipParams.isSelected());
65.143 - } else if (source == skipTupleAssignments) {
65.144 - UnusedDetector.setSkipTupleAssignments(prefs, skipTupleAssignments.isSelected());
65.145 - } else {
65.146 - assert false : source;
65.147 - }
65.148 - }//GEN-LAST:event_changed
65.149 - // Variables declaration - do not modify//GEN-BEGIN:variables
65.150 - private javax.swing.JLabel ignoredLabel;
65.151 - private javax.swing.JTextField ignoredNames;
65.152 - private javax.swing.JCheckBox skipParams;
65.153 - private javax.swing.JCheckBox skipTupleAssignments;
65.154 - // End of variables declaration//GEN-END:variables
65.155 -}
66.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnusedImports.java Fri Sep 18 16:20:24 2015 -0500
66.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
66.3 @@ -1,286 +0,0 @@
66.4 -/*
66.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
66.6 - *
66.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
66.8 - *
66.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
66.10 - * Other names may be trademarks of their respective owners.
66.11 - *
66.12 - * The contents of this file are subject to the terms of either the GNU
66.13 - * General Public License Version 2 only ("GPL") or the Common
66.14 - * Development and Distribution License("CDDL") (collectively, the
66.15 - * "License"). You may not use this file except in compliance with the
66.16 - * License. You can obtain a copy of the License at
66.17 - * http://www.netbeans.org/cddl-gplv2.html
66.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
66.19 - * specific language governing permissions and limitations under the
66.20 - * License. When distributing the software, include this License Header
66.21 - * Notice in each file and include the License file at
66.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
66.23 - * particular file as subject to the "Classpath" exception as provided
66.24 - * by Oracle in the GPL Version 2 section of the License file that
66.25 - * accompanied this code. If applicable, add the following below the
66.26 - * License Header, with the fields enclosed by brackets [] replaced by
66.27 - * your own identifying information:
66.28 - * "Portions Copyrighted [year] [name of copyright owner]"
66.29 - *
66.30 - * If you wish your version of this file to be governed by only the CDDL
66.31 - * or only the GPL Version 2, indicate your decision by adding
66.32 - * "[Contributor] elects to include this software in this distribution
66.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
66.34 - * single choice of license, a recipient has the option to distribute
66.35 - * your version of this file under either the CDDL, the GPL Version 2 or
66.36 - * to extend the choice of license to its licensees as provided above.
66.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
66.38 - * Version 2 license, then the option applies only if the new code is
66.39 - * made subject to such option by the copyright holder.
66.40 - *
66.41 - * Contributor(s):
66.42 - *
66.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
66.44 - */
66.45 -package org.netbeans.modules.python.editor.hints;
66.46 -
66.47 -import java.util.ArrayList;
66.48 -import java.util.Collections;
66.49 -import java.util.HashMap;
66.50 -import java.util.List;
66.51 -import java.util.Map;
66.52 -import java.util.Set;
66.53 -import java.util.prefs.Preferences;
66.54 -import javax.swing.JComponent;
66.55 -import org.netbeans.editor.BaseDocument;
66.56 -import org.netbeans.modules.csl.api.EditList;
66.57 -import org.netbeans.modules.csl.api.Hint;
66.58 -import org.netbeans.modules.csl.api.HintFix;
66.59 -import org.netbeans.modules.csl.api.HintSeverity;
66.60 -import org.netbeans.modules.csl.api.OffsetRange;
66.61 -import org.netbeans.modules.csl.api.RuleContext;
66.62 -import org.netbeans.modules.python.editor.PythonAstUtils;
66.63 -import org.netbeans.modules.python.editor.PythonParserResult;
66.64 -import org.netbeans.modules.python.editor.imports.ImportEntry;
66.65 -import org.netbeans.modules.python.editor.imports.ImportManager;
66.66 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
66.67 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
66.68 -import org.openide.filesystems.FileObject;
66.69 -import org.openide.util.NbBundle;
66.70 -import org.python.antlr.PythonTree;
66.71 -import org.python.antlr.ast.Import;
66.72 -import org.python.antlr.ast.ImportFrom;
66.73 -import org.python.antlr.ast.Module;
66.74 -import org.python.antlr.ast.alias;
66.75 -
66.76 -/**
66.77 - * Detect unused imports
66.78 - *
66.79 - * @author Tor Norbye
66.80 - */
66.81 -public class UnusedImports extends PythonAstRule {
66.82 - public UnusedImports() {
66.83 - }
66.84 -
66.85 - @Override
66.86 - public boolean appliesTo(RuleContext context) {
66.87 - FileObject fo = context.parserResult.getSnapshot().getSource().getFileObject();
66.88 - return fo == null || !fo.getName().equals("__init__"); // NOI18N
66.89 - }
66.90 -
66.91 - @Override
66.92 - public Set<Class> getKinds() {
66.93 - return Collections.<Class>singleton(Module.class);
66.94 - }
66.95 -
66.96 - @Override
66.97 - public void run(PythonRuleContext context, List<Hint> result) {
66.98 - computeUnusedImports(this, context, result, null);
66.99 - }
66.100 -
66.101 - private static void computeUnusedImports(UnusedImports detector, PythonRuleContext context, List<Hint> result, Map<PythonTree, List<String>> unused) {
66.102 - assert result == null || unused == null; // compute either results or set of unused
66.103 -
66.104 - PythonParserResult info = (PythonParserResult) context.parserResult;
66.105 - SymbolTable symbolTable = info.getSymbolTable();
66.106 - List<ImportEntry> unusedImports = symbolTable.getUnusedImports();
66.107 - if (unusedImports.isEmpty()) {
66.108 - return;
66.109 - }
66.110 - Map<PythonTree, List<String>> maps = new HashMap<>();
66.111 - for (ImportEntry entry : unusedImports) {
66.112 - maps.put(entry.node, new ArrayList<String>());
66.113 - }
66.114 - for (ImportEntry entry : unusedImports) {
66.115 - if (entry.isFromImport) {
66.116 - String name = entry.asName != null ? entry.asName : entry.symbol;
66.117 - maps.get(entry.node).add(name);
66.118 - } else {
66.119 - String name = entry.asName != null ? entry.asName : entry.module;
66.120 - maps.get(entry.node).add(name);
66.121 - }
66.122 - }
66.123 - for (Map.Entry<PythonTree, List<String>> entry : maps.entrySet()) {
66.124 - PythonTree node = entry.getKey();
66.125 - List<String> list = entry.getValue();
66.126 - if (node instanceof Import) {
66.127 - Import imp = (Import)node;
66.128 - List<alias> names = imp.getInternalNames();
66.129 - if (names != null && names.size() == list.size()) {
66.130 - list.clear();
66.131 - }
66.132 - } else {
66.133 - assert node instanceof ImportFrom;
66.134 - ImportFrom imp = (ImportFrom)node;
66.135 - List<alias> names = imp.getInternalNames();
66.136 - if (names != null && names.size() == list.size()) {
66.137 - list.clear();
66.138 - }
66.139 - }
66.140 - }
66.141 -
66.142 - for (Map.Entry<PythonTree, List<String>> entry : maps.entrySet()) {
66.143 - PythonTree node = entry.getKey();
66.144 - List<String> list = entry.getValue();
66.145 - if (list.size() == 0) {
66.146 - list = null;
66.147 - }
66.148 - if (unused != null) {
66.149 - unused.put(node, list);
66.150 - } else {
66.151 - addError(detector, context, node, list, result);
66.152 - }
66.153 - }
66.154 - }
66.155 -
66.156 - private static void addError(UnusedImports detector, PythonRuleContext context, PythonTree node, List<String> symbols, List<Hint> result) {
66.157 - PythonParserResult info = (PythonParserResult) context.parserResult;
66.158 - OffsetRange range = PythonAstUtils.getNameRange(info, node);
66.159 - range = PythonLexerUtils.getLexerOffsets(info, range);
66.160 - if (range != OffsetRange.NONE) {
66.161 - List<HintFix> fixList = new ArrayList<>(3);
66.162 - fixList.add(new UnusedFix(detector, context, node, symbols, false));
66.163 - fixList.add(new UnusedFix(detector, context, null, null, false)); // Remove All
66.164 - fixList.add(new UnusedFix(detector, context, null, null, true)); // Organize
66.165 - String message;
66.166 - if (symbols != null) {
66.167 - message = NbBundle.getMessage(NameRule.class, "UnusedImportSymbols", symbols);
66.168 - } else {
66.169 - message = NbBundle.getMessage(NameRule.class, "UnusedImport");
66.170 - }
66.171 - Hint desc = new Hint(detector, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2500);
66.172 - result.add(desc);
66.173 - }
66.174 - }
66.175 -
66.176 - @Override
66.177 - public String getId() {
66.178 - return "UnusedImports"; // NOI18N
66.179 - }
66.180 -
66.181 - @Override
66.182 - public String getDisplayName() {
66.183 - return NbBundle.getMessage(NameRule.class, "UnusedImports");
66.184 - }
66.185 -
66.186 - @Override
66.187 - public String getDescription() {
66.188 - return NbBundle.getMessage(NameRule.class, "UnusedImportsDesc");
66.189 - }
66.190 -
66.191 - @Override
66.192 - public boolean getDefaultEnabled() {
66.193 - return true;
66.194 - }
66.195 -
66.196 - @Override
66.197 - public boolean showInTasklist() {
66.198 - return false; // ? or maybe yes?
66.199 - }
66.200 -
66.201 - @Override
66.202 - public HintSeverity getDefaultSeverity() {
66.203 - return HintSeverity.WARNING;
66.204 - }
66.205 -
66.206 - @Override
66.207 - public JComponent getCustomizer(Preferences node) {
66.208 - return null;
66.209 - }
66.210 -
66.211 - /**
66.212 - * Fix to insert self argument or rename first argument to self
66.213 - */
66.214 - private static class UnusedFix implements /*PreviewableFix*/ HintFix { // Preview not particularly helpful and clutters menu
66.215 - private final UnusedImports detector;
66.216 - private final PythonRuleContext context;
66.217 - private final PythonTree node;
66.218 - private final List<String> symbols;
66.219 - private final boolean organizeOnly;
66.220 -
66.221 - private UnusedFix(UnusedImports detector, PythonRuleContext context, PythonTree node, List<String> symbols, boolean organizeOnly) {
66.222 - this.detector = detector;
66.223 - this.context = context;
66.224 - this.node = node;
66.225 - this.symbols = symbols;
66.226 - this.organizeOnly = organizeOnly;
66.227 - }
66.228 -
66.229 - @Override
66.230 - public String getDescription() {
66.231 - if (node == null) {
66.232 - if (organizeOnly) {
66.233 - return NbBundle.getMessage(CreateDocString.class, "OrganizeImports");
66.234 - } else {
66.235 - return NbBundle.getMessage(CreateDocString.class, "DeleteAllUnused");
66.236 - }
66.237 - } else if (symbols != null) {
66.238 - return NbBundle.getMessage(CreateDocString.class, "UnusedFixSymbols", symbols);
66.239 - } else {
66.240 - return NbBundle.getMessage(CreateDocString.class, "UnusedFix");
66.241 - }
66.242 - }
66.243 -
66.244 - public boolean canPreview() {
66.245 - return true;
66.246 - }
66.247 -
66.248 - public EditList getEditList() throws Exception {
66.249 - BaseDocument doc = context.doc;
66.250 - EditList edits = new EditList(doc);
66.251 -
66.252 - ImportManager importManager = new ImportManager((PythonParserResult) context.parserResult);
66.253 -
66.254 - if (node == null) {
66.255 - if (organizeOnly) {
66.256 - importManager.cleanup(edits, 0, doc.getLength(), true);
66.257 - } else {
66.258 - Map<PythonTree, List<String>> onlyNames = new HashMap<>();
66.259 - computeUnusedImports(detector, context, null, onlyNames);
66.260 - Set<PythonTree> candidates = onlyNames.keySet();
66.261 - importManager.removeImports(edits, candidates, false, onlyNames);
66.262 - }
66.263 - } else {
66.264 - Set<PythonTree> candidates = Collections.singleton(node);
66.265 - Map<PythonTree, List<String>> onlyNames = new HashMap<>();
66.266 - onlyNames.put(node, symbols);
66.267 - importManager.removeImports(edits, candidates, false, onlyNames);
66.268 - }
66.269 -
66.270 - return edits;
66.271 - }
66.272 -
66.273 - @Override
66.274 - public void implement() throws Exception {
66.275 - EditList edits = getEditList();
66.276 - edits.apply();
66.277 - }
66.278 -
66.279 - @Override
66.280 - public boolean isSafe() {
66.281 - return true;
66.282 - }
66.283 -
66.284 - @Override
66.285 - public boolean isInteractive() {
66.286 - return false;
66.287 - }
66.288 - }
66.289 -}
67.1 --- a/python.editor/src/org/netbeans/modules/python/editor/imports/FastImportAction.java Fri Sep 18 16:20:24 2015 -0500
67.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/imports/FastImportAction.java Mon Sep 21 13:01:16 2015 +0200
67.3 @@ -59,10 +59,10 @@
67.4 import org.netbeans.editor.BaseAction;
67.5 import org.netbeans.editor.Utilities;
67.6 import org.netbeans.modules.csl.spi.GsfUtilities;
67.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
67.8 -import org.netbeans.modules.python.editor.PythonIndex;
67.9 -import org.netbeans.modules.python.editor.PythonParserResult;
67.10 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
67.11 +import org.netbeans.modules.python.source.PythonAstUtils;
67.12 +import org.netbeans.modules.python.source.PythonIndex;
67.13 +import org.netbeans.modules.python.source.PythonParserResult;
67.14 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
67.15 import org.openide.ErrorManager;
67.16 import org.openide.filesystems.FileObject;
67.17 import org.openide.util.Exceptions;
68.1 --- a/python.editor/src/org/netbeans/modules/python/editor/imports/FixImportsAction.java Fri Sep 18 16:20:24 2015 -0500
68.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/imports/FixImportsAction.java Mon Sep 21 13:01:16 2015 +0200
68.3 @@ -41,6 +41,8 @@
68.4 */
68.5 package org.netbeans.modules.python.editor.imports;
68.6
68.7 +import org.netbeans.modules.python.source.ImportEntry;
68.8 +import org.netbeans.modules.python.source.ImportManager;
68.9 import java.awt.Dialog;
68.10 import java.awt.Toolkit;
68.11 import java.awt.event.ActionEvent;
68.12 @@ -62,9 +64,9 @@
68.13 import org.netbeans.modules.parsing.api.Source;
68.14 import org.netbeans.modules.parsing.api.UserTask;
68.15 import org.netbeans.modules.parsing.spi.ParseException;
68.16 -import org.netbeans.modules.python.editor.PythonAstUtils;
68.17 -import org.netbeans.modules.python.editor.PythonParserResult;
68.18 -import org.netbeans.modules.python.editor.options.CodeStyle.ImportCleanupStyle;
68.19 +import org.netbeans.modules.python.source.PythonAstUtils;
68.20 +import org.netbeans.modules.python.source.PythonParserResult;
68.21 +import org.netbeans.modules.python.source.CodeStyle.ImportCleanupStyle;
68.22 import org.openide.DialogDescriptor;
68.23 import org.openide.DialogDisplayer;
68.24 import org.openide.awt.StatusDisplayer;
68.25 @@ -100,6 +102,10 @@
68.26 * @author Tor Norbye
68.27 */
68.28 public class FixImportsAction extends BaseAction {
68.29 + private static final String PREFS_KEY = FixImportsAction.class.getName();
68.30 + // TODO - use document style instead!
68.31 + private static final String KEY_REMOVE_UNUSED_IMPORTS = "removeUnusedImports"; // NOI18N
68.32 +
68.33 public FixImportsAction() {
68.34 super("fix-imports", 0); // NOI18N
68.35 }
68.36 @@ -153,7 +159,7 @@
68.37 boolean fixImports = false;
68.38 String[] selections = null;
68.39 boolean removeUnusedImports;
68.40 - Preferences prefs = NbPreferences.forModule(FixImportsAction.class).node(ImportManager.PREFS_KEY);
68.41 + Preferences prefs = NbPreferences.forModule(FixImportsAction.class).node(PREFS_KEY);
68.42
68.43 List<String> ambiguousSymbols = new ArrayList<>();
68.44 Set<ImportEntry> unused = new HashSet<>();
68.45 @@ -199,7 +205,7 @@
68.46 FixDuplicateImportStmts panel = new FixDuplicateImportStmts();
68.47
68.48 panel.initPanel(names, variants, icons, defaults,
68.49 - prefs.getBoolean(ImportManager.KEY_REMOVE_UNUSED_IMPORTS, true));
68.50 + prefs.getBoolean(KEY_REMOVE_UNUSED_IMPORTS, true));
68.51
68.52 DialogDescriptor dd = new DialogDescriptor(panel, NbBundle.getMessage(FixImportsAction.class, "FixDupImportStmts_Title")); //NOI18N
68.53 Dialog d = DialogDisplayer.getDefault().createDialog(dd);
68.54 @@ -227,10 +233,10 @@
68.55 } else {
68.56 fixImports = true;
68.57 selections = defaults;
68.58 - removeUnusedImports = prefs.getBoolean(ImportManager.KEY_REMOVE_UNUSED_IMPORTS, true);
68.59 + removeUnusedImports = prefs.getBoolean(KEY_REMOVE_UNUSED_IMPORTS, true);
68.60 }
68.61 } else {
68.62 - removeUnusedImports = prefs.getBoolean(ImportManager.KEY_REMOVE_UNUSED_IMPORTS, true);
68.63 + removeUnusedImports = prefs.getBoolean(KEY_REMOVE_UNUSED_IMPORTS, true);
68.64 // Just clean up imports
68.65 fixImports = true;
68.66 selections = null;
68.67 @@ -238,7 +244,7 @@
68.68
68.69 if (fixImports) {
68.70 if (shouldShowImportsPanel) {
68.71 - prefs.putBoolean(ImportManager.KEY_REMOVE_UNUSED_IMPORTS, removeUnusedImports);
68.72 + prefs.putBoolean(KEY_REMOVE_UNUSED_IMPORTS, removeUnusedImports);
68.73 }
68.74
68.75 if (!removeUnusedImports) {
69.1 --- a/python.editor/src/org/netbeans/modules/python/editor/imports/ImportEntry.java Fri Sep 18 16:20:24 2015 -0500
69.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
69.3 @@ -1,171 +0,0 @@
69.4 -/*
69.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
69.6 - *
69.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
69.8 - *
69.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
69.10 - * Other names may be trademarks of their respective owners.
69.11 - *
69.12 - * The contents of this file are subject to the terms of either the GNU
69.13 - * General Public License Version 2 only ("GPL") or the Common
69.14 - * Development and Distribution License("CDDL") (collectively, the
69.15 - * "License"). You may not use this file except in compliance with the
69.16 - * License. You can obtain a copy of the License at
69.17 - * http://www.netbeans.org/cddl-gplv2.html
69.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
69.19 - * specific language governing permissions and limitations under the
69.20 - * License. When distributing the software, include this License Header
69.21 - * Notice in each file and include the License file at
69.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
69.23 - * particular file as subject to the "Classpath" exception as provided
69.24 - * by Oracle in the GPL Version 2 section of the License file that
69.25 - * accompanied this code. If applicable, add the following below the
69.26 - * License Header, with the fields enclosed by brackets [] replaced by
69.27 - * your own identifying information:
69.28 - * "Portions Copyrighted [year] [name of copyright owner]"
69.29 - *
69.30 - * Contributor(s):
69.31 - *
69.32 - * The Original Software is NetBeans. The Initial Developer of the Original
69.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
69.34 - * Microsystems, Inc. All Rights Reserved.
69.35 - *
69.36 - * If you wish your version of this file to be governed by only the CDDL
69.37 - * or only the GPL Version 2, indicate your decision by adding
69.38 - * "[Contributor] elects to include this software in this distribution
69.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
69.40 - * single choice of license, a recipient has the option to distribute
69.41 - * your version of this file under either the CDDL, the GPL Version 2 or
69.42 - * to extend the choice of license to its licensees as provided above.
69.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
69.44 - * Version 2 license, then the option applies only if the new code is
69.45 - * made subject to such option by the copyright holder.
69.46 - */
69.47 -package org.netbeans.modules.python.editor.imports;
69.48 -
69.49 -import org.python.antlr.PythonTree;
69.50 -
69.51 -/**
69.52 - * State about a single atomic import. (A single import statement in Python
69.53 - * can correspond to many atomic imports: one for each symbol or module
69.54 - * imported)
69.55 - *
69.56 - * @author Tor Norbye
69.57 - */
69.58 -public class ImportEntry implements Comparable<ImportEntry> {
69.59 - public final String module;
69.60 - public final String asName;
69.61 - public final String symbol;
69.62 - public final boolean isSystem;
69.63 - public final boolean isFromImport;
69.64 - /**
69.65 - * Natural order of import statements (in the source). This will be non zero if
69.66 - * we want to preserve the original order rather than the alphabetical order.
69.67 - */
69.68 - public int ordinal;
69.69 - /**
69.70 - * Corresponding import statement node. This will be non null if we want to consider
69.71 - * duplicate import statements as different
69.72 - */
69.73 - public PythonTree node;
69.74 - /**
69.75 - * Whether we have a symbol import AND we're sorting by symbol imports.
69.76 - * Will be false even for symbol imports when we're not sorting by symbols.
69.77 - */
69.78 - public boolean sortedFrom;
69.79 -
69.80 - public ImportEntry(String module, String symbol, String asName, boolean isSystem, PythonTree node, int ordinal) {
69.81 - super();
69.82 - this.module = module;
69.83 - this.symbol = symbol;
69.84 - this.asName = asName;
69.85 - this.isSystem = isSystem;
69.86 - this.isFromImport = symbol != null;
69.87 - this.node = node;
69.88 - this.ordinal = ordinal;
69.89 -
69.90 - this.sortedFrom = symbol != null;
69.91 - }
69.92 -
69.93 - public ImportEntry(String module, String asName, boolean isSystem, PythonTree node, int ordinal) {
69.94 - this(module, null, asName, isSystem, node, ordinal);
69.95 - }
69.96 -
69.97 - @Override
69.98 - public boolean equals(Object obj) {
69.99 - if (obj == null) {
69.100 - return false;
69.101 - }
69.102 - if (getClass() != obj.getClass()) {
69.103 - return false;
69.104 - }
69.105 - final ImportEntry other = (ImportEntry)obj;
69.106 - if (this.node != other.node) {
69.107 - return false;
69.108 - }
69.109 - if ((this.module == null) ? (other.module != null) : !this.module.equals(other.module)) {
69.110 - return false;
69.111 - }
69.112 - if ((this.asName == null) ? (other.asName != null) : !this.asName.equals(other.asName)) {
69.113 - return false;
69.114 - }
69.115 - if ((this.symbol == null) ? (other.symbol != null) : !this.symbol.equals(other.symbol)) {
69.116 - return false;
69.117 - }
69.118 - return true;
69.119 - }
69.120 -
69.121 - @Override
69.122 - public int hashCode() {
69.123 - int hash = 7;
69.124 - hash = 29 * hash + (this.module != null ? this.module.hashCode() : 0);
69.125 - return hash;
69.126 - }
69.127 -
69.128 - @Override
69.129 - public int compareTo(ImportEntry other) {
69.130 - boolean thisIsFuture = "__future__".equals(module); // NOI18N
69.131 - boolean otherIsFuture = "__future__".equals(other.module); // NOI18N
69.132 - if (thisIsFuture != otherIsFuture) {
69.133 - return thisIsFuture ? -1 : 1;
69.134 - }
69.135 - if (isSystem != other.isSystem) {
69.136 - return isSystem ? -1 : 1;
69.137 - }
69.138 - if (sortedFrom != other.sortedFrom) {
69.139 - return sortedFrom ? 1 : -1;
69.140 - }
69.141 - if (ordinal != other.ordinal) {
69.142 - return ordinal - other.ordinal;
69.143 - }
69.144 - // Then we sort by module name
69.145 - int result = module.compareTo(other.module);
69.146 - if (result != 0) {
69.147 - return result;
69.148 - }
69.149 - // And then, for each module, first the imports, then the from imports
69.150 - if (isFromImport != other.isFromImport) {
69.151 - return isFromImport ? 1 : -1;
69.152 - }
69.153 - if (symbol != null) {
69.154 - assert other.symbol != null;
69.155 - // since isFromImport==
69.156 - result = symbol.compareTo(other.symbol);
69.157 - if (result != 0) {
69.158 - return result;
69.159 - }
69.160 - }
69.161 - if (asName == null) {
69.162 - return (other.asName == null) ? 0 : 1;
69.163 - }
69.164 - if (other.asName == null) {
69.165 - return -1;
69.166 - }
69.167 - return asName.compareTo(other.asName);
69.168 - }
69.169 -
69.170 - @Override
69.171 - public String toString() {
69.172 - return "ImportEntry(" + module + ", " + symbol + ", " + asName + ")"; // NOI18N
69.173 - }
69.174 -}
70.1 --- a/python.editor/src/org/netbeans/modules/python/editor/imports/ImportManager.java Fri Sep 18 16:20:24 2015 -0500
70.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
70.3 @@ -1,1050 +0,0 @@
70.4 -/*
70.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
70.6 - *
70.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
70.8 - *
70.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
70.10 - * Other names may be trademarks of their respective owners.
70.11 - *
70.12 - * The contents of this file are subject to the terms of either the GNU
70.13 - * General Public License Version 2 only ("GPL") or the Common
70.14 - * Development and Distribution License("CDDL") (collectively, the
70.15 - * "License"). You may not use this file except in compliance with the
70.16 - * License. You can obtain a copy of the License at
70.17 - * http://www.netbeans.org/cddl-gplv2.html
70.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
70.19 - * specific language governing permissions and limitations under the
70.20 - * License. When distributing the software, include this License Header
70.21 - * Notice in each file and include the License file at
70.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
70.23 - * particular file as subject to the "Classpath" exception as provided
70.24 - * by Oracle in the GPL Version 2 section of the License file that
70.25 - * accompanied this code. If applicable, add the following below the
70.26 - * License Header, with the fields enclosed by brackets [] replaced by
70.27 - * your own identifying information:
70.28 - * "Portions Copyrighted [year] [name of copyright owner]"
70.29 - *
70.30 - * If you wish your version of this file to be governed by only the CDDL
70.31 - * or only the GPL Version 2, indicate your decision by adding
70.32 - * "[Contributor] elects to include this software in this distribution
70.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
70.34 - * single choice of license, a recipient has the option to distribute
70.35 - * your version of this file under either the CDDL, the GPL Version 2 or
70.36 - * to extend the choice of license to its licensees as provided above.
70.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
70.38 - * Version 2 license, then the option applies only if the new code is
70.39 - * made subject to such option by the copyright holder.
70.40 - *
70.41 - * Contributor(s):
70.42 - *
70.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
70.44 - */
70.45 -package org.netbeans.modules.python.editor.imports;
70.46 -
70.47 -import java.awt.Toolkit;
70.48 -import java.util.ArrayList;
70.49 -import java.util.Collection;
70.50 -import java.util.Collections;
70.51 -import java.util.HashMap;
70.52 -import java.util.HashSet;
70.53 -import java.util.List;
70.54 -import java.util.Map;
70.55 -import java.util.Set;
70.56 -import javax.swing.text.BadLocationException;
70.57 -import org.netbeans.api.editor.EditorRegistry;
70.58 -import org.netbeans.editor.BaseDocument;
70.59 -import org.netbeans.editor.Utilities;
70.60 -import org.netbeans.modules.csl.api.EditList;
70.61 -import org.netbeans.modules.csl.api.OffsetRange;
70.62 -import org.netbeans.modules.csl.spi.GsfUtilities;
70.63 -import org.netbeans.modules.editor.indent.api.IndentUtils;
70.64 -import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
70.65 -import org.netbeans.modules.python.editor.PythonAstUtils;
70.66 -import org.netbeans.modules.python.editor.PythonIndex;
70.67 -import org.netbeans.modules.python.editor.PythonParserResult;
70.68 -import org.netbeans.modules.python.editor.elements.IndexedElement;
70.69 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
70.70 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
70.71 -import org.netbeans.modules.python.editor.options.CodeStyle;
70.72 -import org.netbeans.modules.python.editor.options.CodeStyle.ImportCleanupStyle;
70.73 -import org.netbeans.modules.python.editor.scopes.SymbolTable;
70.74 -import org.netbeans.modules.python.editor.scopes.SymInfo;
70.75 -import org.openide.util.Exceptions;
70.76 -import org.openide.util.NbBundle;
70.77 -import org.python.antlr.PythonTree;
70.78 -import org.python.antlr.ast.Import;
70.79 -import org.python.antlr.ast.ImportFrom;
70.80 -import org.python.antlr.ast.Str;
70.81 -import org.python.antlr.ast.alias;
70.82 -
70.83 -/**
70.84 - * Computations regarding module imports.
70.85 - *
70.86 - * @todo Handle commenting out portions of imports
70.87 - * @todo If I can make this fast, consider highlighting unused imports.
70.88 - * @todo On code completion I should import the corresponding package+class (make the
70.89 - * class part optional)
70.90 - * @todo Watch out for commented out imports getting wiped out in organize imports
70.91 - * because it's between imports. These need to be moved to the end!!!
70.92 - * @todo Offer to group imports
70.93 - * @todo Don't import functions
70.94 - *
70.95 - * @author Tor Norbye
70.96 - */
70.97 -public final class ImportManager {
70.98 - static final String PREFS_KEY = FixImportsAction.class.getName();
70.99 - // TODO - use document style instead!
70.100 - static final String KEY_REMOVE_UNUSED_IMPORTS = "removeUnusedImports"; // NOI18N
70.101 - private PythonParserResult info;
70.102 - private List<Import> imports;
70.103 - private List<ImportFrom> importsFrom;
70.104 - private PythonTree root;
70.105 - private BaseDocument doc;
70.106 - private List<PythonTree> mainImports;
70.107 - private Set<PythonTree> topLevelImports;
70.108 -
70.109 - // Settings
70.110 - private boolean systemLibsFirst = true;
70.111 - private boolean splitImports = true;
70.112 - private boolean sortImports = true;
70.113 - private boolean separateFromImps = false;
70.114 - private ImportCleanupStyle cleanup = ImportCleanupStyle.COMMENT_OUT;
70.115 - private boolean removeDuplicates;
70.116 - private int rightMargin;
70.117 -
70.118 - public ImportManager(PythonParserResult info) {
70.119 - this(info, GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false), null);
70.120 - }
70.121 -
70.122 - public ImportManager(PythonParserResult info, BaseDocument doc) {
70.123 - this(info, doc, null);
70.124 - }
70.125 -
70.126 - public ImportManager(PythonParserResult info, BaseDocument doc, CodeStyle codeStyle) {
70.127 - this.info = info;
70.128 -
70.129 - root = PythonAstUtils.getRoot(info);
70.130 -
70.131 - SymbolTable symbolTable = PythonAstUtils.getParseResult(info).getSymbolTable();
70.132 - imports = symbolTable.getImports();
70.133 - importsFrom = symbolTable.getImportsFrom();
70.134 - topLevelImports = symbolTable.getTopLevelImports();
70.135 - mainImports = symbolTable.getMainImports();
70.136 -
70.137 - this.doc = doc;
70.138 -
70.139 - if (codeStyle == null) {
70.140 - codeStyle = CodeStyle.getDefault(doc);
70.141 - }
70.142 - systemLibsFirst = codeStyle.systemLibsFirst();
70.143 - splitImports = codeStyle.oneImportPerLine();
70.144 - cleanup = codeStyle.cleanupImports();
70.145 - sortImports = codeStyle.sortImports();
70.146 - separateFromImps = codeStyle.separateFromImps();
70.147 - if (separateFromImps) {
70.148 - sortImports = true;
70.149 - }
70.150 - removeDuplicates = codeStyle.removeDuplicates();
70.151 - rightMargin = codeStyle.getRightMargin();
70.152 -
70.153 - }
70.154 -
70.155 - public static boolean isFutureImport(ImportFrom fromStatement) {
70.156 - return "__future__".equals(fromStatement.getInternalModule()); // NOI18N
70.157 - }
70.158 -
70.159 - public void setCleanup(ImportCleanupStyle cleanup) {
70.160 - this.cleanup = cleanup;
70.161 - }
70.162 -
70.163 - public void cleanup(EditList edits, int startOffset, int endOffset, boolean force) {
70.164 - OffsetRange lexRange = getMainImportsRange();
70.165 - if (lexRange == OffsetRange.NONE ||
70.166 - !(new OffsetRange(startOffset, endOffset).overlaps(lexRange))) {
70.167 - // Not touching imports
70.168 - return;
70.169 - }
70.170 -
70.171 - if (cleanup != ImportCleanupStyle.LEAVE_ALONE) {
70.172 - List<String> ambiguousSymbols = new ArrayList<>();
70.173 - Map<String, String> defaultLists = new HashMap<>();
70.174 - Map<String, List<String>> alternatives = new HashMap<>();
70.175 - Set<ImportEntry> unused = new HashSet<>();
70.176 - Set<ImportEntry> duplicates = new HashSet<>();
70.177 -
70.178 - computeImports(ambiguousSymbols, defaultLists, alternatives, unused, duplicates);
70.179 - if (ambiguousSymbols.size() == 0 || force) {
70.180 - apply(edits, new String[0], unused, duplicates);
70.181 - return;
70.182 - }
70.183 - } else if (removeDuplicates) {
70.184 - Set<ImportEntry> duplicates = findDuplicates();
70.185 - apply(edits, new String[0], Collections.<ImportEntry>emptySet(), duplicates);
70.186 - return;
70.187 - }
70.188 -
70.189 - apply(edits, new String[0], Collections.<ImportEntry>emptySet(), Collections.<ImportEntry>emptySet());
70.190 - }
70.191 -
70.192 - public List<Import> getImports() {
70.193 - return imports;
70.194 - }
70.195 -
70.196 - public List<ImportFrom> getImportsFrom() {
70.197 - return importsFrom;
70.198 - }
70.199 -
70.200 - private Set<ImportEntry> findDuplicates() {
70.201 - Set<ImportEntry> duplicates = new HashSet<>();
70.202 - // TODO!
70.203 -
70.204 - return duplicates;
70.205 - }
70.206 -
70.207 - public boolean computeImports(
70.208 - List<String> ambiguousSymbols,
70.209 - Map<String, String> defaults,
70.210 - Map<String, List<String>> alternatives, Set<ImportEntry> unused, Set<ImportEntry> duplicates) {
70.211 -
70.212 - boolean ambiguous = false;
70.213 -
70.214 - SymbolTable symbolTable = new SymbolTable(PythonAstUtils.getRoot(info), info.getSnapshot().getSource().getFileObject());
70.215 - Map<String, SymInfo> unresolved = symbolTable.getUnresolvedNames(info);
70.216 -
70.217 - if (unresolved.size() > 0) {
70.218 - ambiguousSymbols.addAll(unresolved.keySet());
70.219 - Collections.sort(ambiguousSymbols);
70.220 -
70.221 - // Try to compute suggestions.
70.222 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
70.223 - Set<IndexedElement> modules = index.getModules("", QuerySupport.Kind.PREFIX);
70.224 - for (IndexedElement module : modules) {
70.225 - String name = module.getName();
70.226 - if (unresolved.containsKey(name)) {
70.227 - List<String> list = new ArrayList<>(4);
70.228 - list.add(name);
70.229 - defaults.put(name, name);
70.230 - alternatives.put(name, list);
70.231 - }
70.232 - }
70.233 -
70.234 - List<String> unresolvedList = new ArrayList<>(unresolved.keySet());
70.235 - Collections.sort(unresolvedList);
70.236 - for (String symbol : unresolvedList) {
70.237 - // TODO - determine if it's a call or variable
70.238 - // TODO - track import usages too!
70.239 - Collection<String> importsFor = index.getImportsFor(symbol, true);
70.240 - // TODO - insert symbols + " (whole module)"
70.241 - if (importsFor.size() > 0) {
70.242 - if (importsFor.size() > 1) {
70.243 - List<String> l = new ArrayList<>(importsFor);
70.244 - Collections.sort(l);
70.245 - importsFor = l;
70.246 - }
70.247 - List<String> list = alternatives.get(symbol);
70.248 - if (list == null) {
70.249 - list = new ArrayList<>();
70.250 - alternatives.put(symbol, list);
70.251 - }
70.252 - for (String s : importsFor) {
70.253 - if (!list.contains(s)) {
70.254 - list.add(s);
70.255 - }
70.256 - }
70.257 - if (list.size() > 1) {
70.258 - ambiguous = true;
70.259 - }
70.260 -
70.261 - // TODO - if it's a call, try to match functions instead of imported symbols
70.262 - } else {
70.263 - ambiguous = true;
70.264 - }
70.265 - }
70.266 -
70.267 - // TODO - look up -functions- and -data- defined across all modules
70.268 - // that might define these guys
70.269 -
70.270 - }
70.271 -
70.272 - List<String> unambiguousNames = new ArrayList<>();
70.273 - for (Map.Entry<String, List<String>> entry : alternatives.entrySet()) {
70.274 - List<String> list = entry.getValue();
70.275 - if (list == null || list.size() == 0) {
70.276 - ambiguous = true;
70.277 - } else if (list.size() == 1) {
70.278 - String key = entry.getKey();
70.279 - unambiguousNames.add(key);
70.280 - }
70.281 - }
70.282 -
70.283 - // If we've had to choose certain libraries (e.g. because they're the
70.284 - // only choice available in some cases) then make those libraries default
70.285 - // for all the ambiguous cases as well
70.286 - if (!unambiguousNames.isEmpty()) {
70.287 - for (String name : alternatives.keySet()) {
70.288 - List<String> list = alternatives.get(name);
70.289 - for (String choice : list) {
70.290 - if (unambiguousNames.contains(choice)) {
70.291 - defaults.put(name, choice);
70.292 - }
70.293 - }
70.294 - }
70.295 - }
70.296 -
70.297 - unused.addAll(symbolTable.getUnusedImports());
70.298 -
70.299 -// During development
70.300 -//ambiguous = true;
70.301 -
70.302 - return ambiguous;
70.303 - }
70.304 -
70.305 - public void apply(EditList edits, String[] selections, Set<ImportEntry> removeEntries, Set<ImportEntry> duplicates) {
70.306 - // Update the imports
70.307 - // Sort the imports
70.308 - // Delete the unused imports
70.309 - boolean apply = false;
70.310 - if (edits == null) {
70.311 - edits = new EditList(doc);
70.312 - apply = true;
70.313 - }
70.314 -
70.315 - Set<PythonTree> removedAlready = new HashSet<>();
70.316 -
70.317 - Set<PythonTree> mainImport;
70.318 - //if (sortImports) {
70.319 - mainImport = new HashSet<>(mainImports);
70.320 - //} else {
70.321 - // mainImport = Collections.<PythonTree>emptySet();
70.322 - //}
70.323 - Set<PythonTree> topLevel = topLevelImports;
70.324 -
70.325 -//
70.326 -// // Remove duplicates. Note - these are always removed, not just commented out.
70.327 -// if (duplicates.size() > 0 && cleanup != ImportCleanupStyle.LEAVE_ALONE) {
70.328 -// Set<PythonTree> candidates = new HashSet<PythonTree>();
70.329 -// // Map from import node to list of names that should be removed, if only some are duplicates
70.330 -// Map<PythonTree,List<String>> names = new HashMap<PythonTree,List<String>>();
70.331 -// // Find the corresponding import
70.332 -// //List<PythonTree> candidates = new ArrayList<PythonTree>();
70.333 -// boolean foundFirst = false;
70.334 -// for (Import imp : imports) {
70.335 -// if (imp.names != null) {
70.336 -// boolean all = true;
70.337 -// boolean some = false;
70.338 -// for (alias at : imp.getInternalNames()) {
70.339 -// if (duplicates.contains(at.getInternalName())) {
70.340 -// if (!foundFirst) {
70.341 -// foundFirst = true;
70.342 -// } else {
70.343 -// some = true;
70.344 -// List<String> nameList = names.get(imp);
70.345 -// if (nameList == null) {
70.346 -// nameList = new ArrayList<String>();
70.347 -// names.put(imp, nameList);
70.348 -// }
70.349 -// nameList.add(at.getInternalName());
70.350 -// }
70.351 -// break;
70.352 -// } else {
70.353 -// all = false;
70.354 -// }
70.355 -// }
70.356 -// if (some) {
70.357 -// candidates.add(imp);
70.358 -// if (all) {
70.359 -// // No need to limit deletion to just one
70.360 -// names.put(imp, null);
70.361 -// }
70.362 -// }
70.363 -// }
70.364 -// }
70.365 -//
70.366 -// for (ImportFrom from : importsFrom) {
70.367 -// if (from.names != null) {
70.368 -// boolean all = true;
70.369 -// boolean some = false;
70.370 -// for (alias at : from.names) {
70.371 -// assert at.getInternalName() != null;
70.372 -// String value;
70.373 -// if (at.getInternalAsname() != null) {
70.374 -// value = from.module + ":" + at.getInternalName() + ":" + at.getInternalAsname();
70.375 -// } else {
70.376 -// value = from.module + ":" + at.getInternalName();
70.377 -// }
70.378 -// if (duplicates.contains(value)) {
70.379 -// if (!foundFirst) {
70.380 -// foundFirst = true;
70.381 -// } else {
70.382 -// some = true;
70.383 -// List<String> nameList = names.get(from);
70.384 -// if (nameList == null) {
70.385 -// nameList = new ArrayList<String>();
70.386 -// names.put(from, nameList);
70.387 -// }
70.388 -// nameList.add(at.getInternalName());
70.389 -// }
70.390 -// } else {
70.391 -// all = false;
70.392 -// }
70.393 -// }
70.394 -// if (some) {
70.395 -// candidates.add(from);
70.396 -// if (all) {
70.397 -// // No need to limit deletion to just one
70.398 -// names.put(from, null);
70.399 -// }
70.400 -// }
70.401 -// }
70.402 -// }
70.403 -//
70.404 -// Set<PythonTree> filtered = new HashSet<PythonTree>();
70.405 -// for (PythonTree node : candidates) {
70.406 -// if (!mainImport.contains(node) && topLevel.contains(node)) {
70.407 -// filtered.add(node);
70.408 -// }
70.409 -// }
70.410 -//
70.411 -// removedAlready.addAll(filtered);
70.412 -//
70.413 -// // Note - we always REMOVE duplicate imports rather than just commenting
70.414 -// // them out. We may sometimes be wrong about unused imports, so we let
70.415 -// // users leave them commented out when we clean up to make it easier
70.416 -// // to backtrack if we were wrong. However, duplicate imports is something
70.417 -// // we can accurately detect and leaving them commented out isn't something
70.418 -// // users will probably want.
70.419 -// removeImports(edits, filtered, /*commentOut*/false, names);
70.420 -// }
70.421 -
70.422 - if (cleanup == ImportCleanupStyle.LEAVE_ALONE) {
70.423 - removeEntries.clear();
70.424 - } else {
70.425 - Set<ImportEntry> newSet = new HashSet<>();
70.426 - Set<PythonTree> filtered = new HashSet<>();
70.427 - for (ImportEntry entry : removeEntries) {
70.428 - PythonTree node = entry.node;
70.429 - if (!mainImport.contains(node) && topLevel.contains(node)) {
70.430 - filtered.add(node);
70.431 - } else {
70.432 - if (removeDuplicates) {
70.433 - entry.node = null;
70.434 - }
70.435 - if (sortImports) {
70.436 - entry.ordinal = 0;
70.437 - }
70.438 - if (!separateFromImps) {
70.439 - entry.sortedFrom = false;
70.440 - }
70.441 - }
70.442 -
70.443 - newSet.add(entry);
70.444 - }
70.445 - removeEntries = newSet;
70.446 -// int ordinal = 0;
70.447 -// if (unused.size() > 0 && cleanup != ImportCleanupStyle.LEAVE_ALONE) {
70.448 -// Set<PythonTree> candidates = new HashSet<PythonTree>();
70.449 -// Map<PythonTree,List<String>> names = new HashMap<PythonTree,List<String>>();
70.450 -// // Find the corresponding import
70.451 -// //List<PythonTree> candidates = new ArrayList<PythonTree>();
70.452 -// for (Import imp : imports) {
70.453 -// if (imp.names != null) {
70.454 -// boolean all = true;
70.455 -// boolean some = false;
70.456 -// for (alias at : imp.getInternalNames()) {
70.457 -// if (unused.contains(at.getInternalName())) {
70.458 -// some = true;
70.459 -// List<String> nameList = names.get(imp);
70.460 -// if (nameList == null) {
70.461 -// nameList = new ArrayList<String>();
70.462 -// names.put(imp, nameList);
70.463 -// }
70.464 -// nameList.add(at.getInternalName());
70.465 -//
70.466 -// boolean isSystem = false; // Don't care what it is for deletion
70.467 -// removeEntries.add(new ImportEntry(at.getInternalName(), at.getInternalAsname(), isSystem,
70.468 -// removeDuplicates ? null : imp,
70.469 -// sortImports ? 0 : ordinal++));
70.470 -// break;
70.471 -// } else {
70.472 -// all = false;
70.473 -// }
70.474 -// }
70.475 -//
70.476 -// if (some) {
70.477 -// candidates.add(imp);
70.478 -// if (all) {
70.479 -// // No need to limit deletion to just one
70.480 -// names.put(imp, null);
70.481 -// }
70.482 -// }
70.483 -// }
70.484 -// }
70.485 -//
70.486 -// for (ImportFrom from : importsFrom) {
70.487 -// if (from.names != null) {
70.488 -// boolean all = true;
70.489 -// boolean some = false;
70.490 -// for (alias at : from.names) {
70.491 -// boolean isSystem = false; // Don't care what it is for deletion
70.492 -//
70.493 -// assert at.getInternalName() != null;
70.494 -// String value;
70.495 -// if (at.getInternalAsname() != null) {
70.496 -// value = from.module + ":" + at.getInternalName() + ":" + at.getInternalAsname();
70.497 -// } else {
70.498 -// value = from.module + ":" + at.getInternalName();
70.499 -// }
70.500 -// if (unused.contains(value)) {
70.501 -// removeEntries.add(new ImportEntry(from.module, at.getInternalName(), at.getInternalAsname(), isSystem,
70.502 -// removeDuplicates ? null : from,
70.503 -// sortImports ? 0 : ordinal++));
70.504 -// some = true;
70.505 -// List<String> nameList = names.get(from);
70.506 -// if (nameList == null) {
70.507 -// nameList = new ArrayList<String>();
70.508 -// names.put(from, nameList);
70.509 -// }
70.510 -// nameList.add(at.getInternalName());
70.511 -// } else {
70.512 -// all = false;
70.513 -// }
70.514 -// }
70.515 -// if (some) {
70.516 -// candidates.add(from);
70.517 -// if (all) {
70.518 -// // No need to limit deletion to just one
70.519 -// names.put(from, null);
70.520 -// }
70.521 -// }
70.522 -// }
70.523 -// }
70.524 -//
70.525 -// // Don't try to delete nodes we've already deleted or commented out
70.526 -// // because they are unused
70.527 -//
70.528 -// candidates.removeAll(removedAlready);
70.529 -//
70.530 -// Set<PythonTree> filtered = new HashSet<PythonTree>();
70.531 -// for (PythonTree node : candidates) {
70.532 -// if (!mainImport.contains(node) && topLevel.contains(node)) {
70.533 -// filtered.add(node);
70.534 -// }
70.535 -// }
70.536 -
70.537 - removeImports(edits, filtered, cleanup == ImportCleanupStyle.COMMENT_OUT, null);
70.538 - }
70.539 -
70.540 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
70.541 -
70.542 - Collection<ImportEntry> newEntries = new ArrayList<>();
70.543 - if (selections != null) {
70.544 - for (String module : selections) {
70.545 - if (module.startsWith("<html>")) { // NOI18N
70.546 - // Skip cannot resolve stuff
70.547 - continue;
70.548 - }
70.549 - int colon = module.indexOf(':');
70.550 - if (colon != -1) {
70.551 - int end = module.indexOf('(', colon + 1);
70.552 - if (end == -1) {
70.553 - end = module.indexOf(';', colon + 1);
70.554 - if (end == -1) {
70.555 - end = module.length();
70.556 - }
70.557 - }
70.558 - String symbol = module.substring(colon + 1, end).trim();
70.559 - module = module.substring(0, colon).trim();
70.560 - boolean isSystem = systemLibsFirst && index.isSystemModule(module);
70.561 - ImportEntry importEntry = new ImportEntry(module, symbol, null, isSystem, null, 0);
70.562 - if (!separateFromImps) {
70.563 - importEntry.sortedFrom = false;
70.564 - }
70.565 - newEntries.add(importEntry);
70.566 - } else {
70.567 - boolean isSystem = systemLibsFirst && index.isSystemModule(module);
70.568 - ImportEntry importEntry = new ImportEntry(module, null, null, isSystem, null, 0);
70.569 - if (!separateFromImps) {
70.570 - importEntry.sortedFrom = false;
70.571 - }
70.572 - newEntries.add(importEntry);
70.573 - }
70.574 - }
70.575 - }
70.576 -
70.577 - rewriteMainImports(edits, newEntries, removeEntries);
70.578 -
70.579 - if (apply) {
70.580 - edits.apply();
70.581 - }
70.582 - }
70.583 -
70.584 - public boolean isTopLevel(PythonTree node) {
70.585 - return topLevelImports.contains(node);
70.586 - }
70.587 -
70.588 - /**
70.589 - * Remove or comment out the given import statements (Import or ImportFrom).
70.590 - * @param edits The edit list to add edits for comment or removal
70.591 - * @param candidates The set of Import or ImportFrom nodes
70.592 - * @param commentOut If true, comment out the import, or else, delete it
70.593 - * @param onlyNames A map from nodes to lists where if the list is null,
70.594 - * remove or comment out the entire import, otherwise comment
70.595 - * or delete only the specified name portions.
70.596 - */
70.597 - public void removeImports(EditList edits, Set<PythonTree> candidates, boolean commentOut, Map<PythonTree, List<String>> onlyNames) {
70.598 - for (PythonTree node : candidates) {
70.599 - // Don't touch imports that aren't top level!!!
70.600 - // These can be inside If blocks and such so we don't
70.601 - // have enough knowledge to mess with them
70.602 - if (!isTopLevel(node)) {
70.603 - continue;
70.604 - }
70.605 -
70.606 - OffsetRange astRange = PythonAstUtils.getRange(node);
70.607 - OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
70.608 - if (lexRange == OffsetRange.NONE) {
70.609 - continue;
70.610 - }
70.611 -
70.612 - List<String> names = onlyNames.get(node);
70.613 - if (names != null) {
70.614 -
70.615 - // TODO Handle commenting out portions of a line! An idea which
70.616 - // might work is to replace the whole import with a new import
70.617 - // that moves the commented out portions to the end!!
70.618 -
70.619 - // Only delete/comment out a portion of the line
70.620 -// if (commentOut) {
70.621 -// TODO
70.622 -// } else {
70.623 - // Determine offsets within the line
70.624 - List<OffsetRange> ranges = new ArrayList<>();
70.625 - try {
70.626 - int start = lexRange.getStart();
70.627 - int end = lexRange.getEnd();
70.628 - if (end > doc.getLength()) {
70.629 - end = doc.getLength();
70.630 - if (start > doc.getLength()) {
70.631 - start = doc.getLength();
70.632 - }
70.633 - }
70.634 - String line = doc.getText(start, end - start);
70.635 - for (String name : names) {
70.636 - int index = line.indexOf(name);
70.637 - if (index != -1) {
70.638 - int nameEnd = index + name.length();
70.639 - boolean removedComma = false;
70.640 - for (int i = nameEnd; i < line.length(); i++) {
70.641 - char c = line.charAt(i);
70.642 - if (c == ',') {
70.643 - removedComma = true;
70.644 - nameEnd = i + 1;
70.645 - if (nameEnd < line.length() && line.charAt(nameEnd) == ' ') {
70.646 - // Include space after comma in deletion
70.647 - nameEnd++;
70.648 - }
70.649 - break;
70.650 - } else if (c == ' ' || c == '\t') {
70.651 - continue;
70.652 - } else {
70.653 - break;
70.654 - }
70.655 - }
70.656 - if (!removedComma) {
70.657 - // If I removed the last name on the line there is no
70.658 - // comma at the end, so I should try removing one -before-
70.659 - // the name instead
70.660 - for (int i = index - 1; i >= 0; i--) {
70.661 - char c = line.charAt(i);
70.662 - if (c == ',') {
70.663 - index = i;
70.664 - break;
70.665 - } else if (c == ' ' || c == '\t') {
70.666 - continue;
70.667 - } else {
70.668 - break;
70.669 - }
70.670 - }
70.671 - }
70.672 - OffsetRange remove = new OffsetRange(start + index, start + nameEnd);
70.673 -
70.674 - // Prevent overlaps
70.675 - for (OffsetRange range : ranges) {
70.676 - if (range.overlaps(remove)) {
70.677 - if (range.getStart() < remove.getStart()) {
70.678 - remove = new OffsetRange(range.getEnd(), Math.max(remove.getEnd(), range.getEnd()));
70.679 - } else {
70.680 - remove = new OffsetRange(Math.min(remove.getStart(), range.getStart()), range.getStart());
70.681 - }
70.682 - }
70.683 - }
70.684 -
70.685 - ranges.add(remove);
70.686 - }
70.687 - }
70.688 - int prio = 0;
70.689 - for (OffsetRange range : ranges) {
70.690 - edits.replace(range.getStart(), range.getLength(), null, false, prio++);
70.691 - }
70.692 - } catch (BadLocationException ex) {
70.693 - Exceptions.printStackTrace(ex);
70.694 - }
70.695 -// }
70.696 - } else {
70.697 - int start = lexRange.getStart();
70.698 - if (commentOut) {
70.699 - edits.replace(start, 0, "#", false, 0); // NOI18N
70.700 - } else {
70.701 - int length = lexRange.getLength();
70.702 - // See if this leaves an empty line and if so remove it
70.703 - int endPos = lexRange.getEnd();
70.704 - if (endPos < doc.getLength()) {
70.705 - try {
70.706 - char c = doc.getText(endPos, 1).charAt(0);
70.707 - if (c == '\n') {
70.708 - length++;
70.709 - }
70.710 - } catch (BadLocationException ex) {
70.711 - Exceptions.printStackTrace(ex);
70.712 - }
70.713 - }
70.714 - edits.replace(start, length, null, false, 0);
70.715 - }
70.716 - }
70.717 - }
70.718 - }
70.719 -
70.720 - private OffsetRange getMainImportsRange() {
70.721 - // Compute editor range required
70.722 - int begin = Integer.MAX_VALUE;
70.723 - int end = Integer.MIN_VALUE;
70.724 - OffsetRange lexRange;
70.725 - if (mainImports.size() == 0) {
70.726 - if (mainImports.size() == 1) {
70.727 - OffsetRange astRange = PythonAstUtils.getRange(mainImports.get(0));
70.728 - lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
70.729 - } else {
70.730 - assert mainImports.size() == 0;
70.731 - begin = getImportsLexOffset(null);
70.732 - end = begin;
70.733 - lexRange = new OffsetRange(begin, end);
70.734 - }
70.735 - } else {
70.736 - for (PythonTree node : mainImports) {
70.737 - OffsetRange range = PythonAstUtils.getRange(node);
70.738 - if (range.getStart() < begin) {
70.739 - begin = range.getStart();
70.740 - }
70.741 - if (range.getEnd() > end) {
70.742 - end = range.getEnd();
70.743 - }
70.744 - }
70.745 - OffsetRange astReplace = new OffsetRange(begin, end);
70.746 - lexRange = PythonLexerUtils.getLexerOffsets(info, astReplace);
70.747 - }
70.748 -
70.749 - return lexRange;
70.750 - }
70.751 -
70.752 - public void rewriteMainImports(EditList edits, Collection<ImportEntry> newEntries, Set<ImportEntry> remove) {
70.753 - // Items to be deleted should be deleted after this
70.754 -
70.755 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
70.756 -
70.757 - // TODO:
70.758 - // Look for comments to preserve
70.759 - // Replace the entire editor block
70.760 - Set<ImportEntry> entries = new HashSet<>();
70.761 - int ordinal = 0;
70.762 - for (PythonTree node : mainImports) {
70.763 - if (node instanceof Import) {
70.764 - Import imp = (Import)node;
70.765 - // TODO - look up for at.getInternalName()!
70.766 - List<alias> names = imp.getInternalNames();
70.767 - if (names != null) {
70.768 - for (alias at : names) {
70.769 - ImportEntry importEntry = new ImportEntry(at.getInternalName(), at.getInternalAsname(), systemLibsFirst && index.isSystemModule(at.getInternalName()),
70.770 - removeDuplicates ? null : imp, sortImports ? 0 : ordinal++);
70.771 - if (!separateFromImps) {
70.772 - importEntry.sortedFrom = false;
70.773 - }
70.774 - entries.add(importEntry);
70.775 - }
70.776 - }
70.777 - } else {
70.778 - assert node instanceof ImportFrom;
70.779 - ImportFrom imp = (ImportFrom)node;
70.780 - List<alias> names = imp.getInternalNames();
70.781 - if (names != null && names.size() > 0) {
70.782 - // TODO - look up for imp.getInternalModule()!
70.783 - boolean isSystemLibrary = systemLibsFirst && index.isSystemModule(imp.getInternalModule());
70.784 - for (alias at : names) {
70.785 - ImportEntry importEntry = new ImportEntry(imp.getInternalModule(), at.getInternalName(), at.getInternalAsname(), isSystemLibrary,
70.786 - removeDuplicates ? null : imp, sortImports ? 0 : ordinal++);
70.787 - if (!separateFromImps) {
70.788 - importEntry.sortedFrom = false;
70.789 - }
70.790 - entries.add(importEntry);
70.791 - }
70.792 - }
70.793 - }
70.794 - }
70.795 -
70.796 - // Add in entries discovered as needed by the import manager
70.797 - if (newEntries.size() > 0) {
70.798 - entries.addAll(newEntries);
70.799 - }
70.800 -
70.801 - // Remove any items that needs to be removed
70.802 - if (remove.size() > 0) {
70.803 - entries.removeAll(remove);
70.804 - }
70.805 -
70.806 - // Sort imports -- first by system/nonsystem, then alphabetically
70.807 - List<ImportEntry> sortedEntries = new ArrayList<>(entries);
70.808 - Collections.sort(sortedEntries);
70.809 -
70.810 - // Write out existing imports
70.811 - StringBuilder sb = new StringBuilder();
70.812 - int size = sortedEntries.size();
70.813 - if (size > 0) {
70.814 - boolean prevSystem = sortedEntries.get(0).isSystem;
70.815 -
70.816 - for (int i = 0; i < size; i++) {
70.817 - ImportEntry entry = sortedEntries.get(i);
70.818 - if (systemLibsFirst && entry.isSystem != prevSystem) {
70.819 - prevSystem = entry.isSystem;
70.820 - sb.append("\n"); // NOI18N Separate system and regular libs
70.821 - }
70.822 -
70.823 - if (entry.isFromImport) {
70.824 - int start = sb.length();
70.825 - sb.append("from "); // NOI18N
70.826 - sb.append(entry.module);
70.827 - sb.append(" import "); // NOI18N
70.828 - sb.append(entry.symbol);
70.829 - if (entry.asName != null) {
70.830 - sb.append(" as "); // NOI18N
70.831 - sb.append(entry.asName);
70.832 - }
70.833 -
70.834 - if (!splitImports) {
70.835 - // Look ahead and combine subsequent entries
70.836 - int lookahead = i + 1;
70.837 - for (; lookahead < size; lookahead++) {
70.838 - ImportEntry next = sortedEntries.get(lookahead);
70.839 - if (next.isFromImport != entry.isFromImport ||
70.840 - !next.module.equals(entry.module)) {
70.841 - break;
70.842 - }
70.843 - sb.append(", "); // NOI18N
70.844 -
70.845 - if (sb.length() - start > rightMargin && (rightMargin > 30)) {
70.846 - sb.append("\\\n");
70.847 - start = sb.length();
70.848 - sb.append(IndentUtils.createIndentString(doc, IndentUtils.indentLevelSize(doc)));
70.849 - }
70.850 -
70.851 - sb.append(next.symbol);
70.852 - if (next.asName != null) {
70.853 - sb.append(" as ");
70.854 - sb.append(next.asName);
70.855 - }
70.856 - }
70.857 - i = lookahead - 1;
70.858 - }
70.859 - sb.append("\n"); // NOI18N
70.860 - } else {
70.861 - // Plain import
70.862 - // We never combine imports
70.863 - sb.append("import "); // NOI18N
70.864 - sb.append(entry.module);
70.865 - if (entry.asName != null) {
70.866 - sb.append(" as "); // NOI18N
70.867 - sb.append(entry.asName);
70.868 - }
70.869 - sb.append("\n"); // NOI18N
70.870 - }
70.871 - }
70.872 - }
70.873 -
70.874 - // Write commented out deleted entries as well
70.875 - if (remove.size() > 0 && cleanup == ImportCleanupStyle.COMMENT_OUT) {
70.876 - size = remove.size();
70.877 - List<ImportEntry> sortedRemove = new ArrayList<>();
70.878 - sortedRemove.addAll(remove);
70.879 - Collections.sort(sortedRemove);
70.880 - for (ImportEntry entry : sortedRemove) {
70.881 - if (entry.isFromImport) {
70.882 - sb.append("#from "); // NOI18N
70.883 - sb.append(entry.module);
70.884 - sb.append(" import "); // NOI18N
70.885 - sb.append(entry.symbol);
70.886 - if (entry.asName != null) {
70.887 - sb.append(" as "); // NOI18N
70.888 - sb.append(entry.asName);
70.889 - }
70.890 - sb.append("\n"); // NOI18N
70.891 - } else {
70.892 - sb.append("#import "); // NOI18N
70.893 - sb.append(entry.module);
70.894 - if (entry.asName != null) {
70.895 - sb.append(" as "); // NOI18N
70.896 - sb.append(entry.asName);
70.897 - }
70.898 - sb.append("\n"); // NOI18N
70.899 - }
70.900 - }
70.901 - }
70.902 -
70.903 - // Compute editor range required
70.904 - OffsetRange lexRange = getMainImportsRange();
70.905 -
70.906 - // Replace final newline if it's there so we don't grow whitespace around the imports
70.907 - int lastNewlineDelta = 0;
70.908 - try {
70.909 - if (lexRange.getEnd() < doc.getLength() && doc.getText(lexRange.getEnd(), 1).charAt(0) == '\n') {
70.910 - lastNewlineDelta++;
70.911 - }
70.912 - } catch (BadLocationException ex) {
70.913 - Exceptions.printStackTrace(ex);
70.914 - }
70.915 -
70.916 - edits.replace(lexRange.getStart(), lexRange.getLength() + lastNewlineDelta, sb.toString(), false, 0);
70.917 - }
70.918 -
70.919 - /** Compute the location where the main import block should be located */
70.920 - public int getImportsLexOffset(String module) {
70.921 - int begin = 0;
70.922 -
70.923 - // First try computing a position in the standard imports
70.924 - if (module != null) {
70.925 - PythonTree last = null;
70.926 - for (PythonTree node : mainImports) {
70.927 - boolean stop = false;
70.928 - if (node instanceof Import) {
70.929 - Import imp = (Import)node;
70.930 - List<alias> names = imp.getInternalNames();
70.931 - if (names != null && names.size() > 0 &&
70.932 - names.get(0).getInternalName().compareTo(module) >= 0) {
70.933 - stop = true;
70.934 - }
70.935 - } else {
70.936 - assert node instanceof ImportFrom;
70.937 - ImportFrom imp = (ImportFrom)node;
70.938 - if (imp.getInternalModule().compareTo(module) >= 0) {
70.939 - stop = true;
70.940 - }
70.941 - }
70.942 -
70.943 - if (stop) {
70.944 - return PythonLexerUtils.getLexerOffsets(info,
70.945 - PythonAstUtils.getRange(node)).getStart();
70.946 - }
70.947 -
70.948 - last = node;
70.949 - }
70.950 -
70.951 - if (last != null) {
70.952 - return PythonLexerUtils.getLexerOffsets(info,
70.953 - PythonAstUtils.getRange(last)).getStart();
70.954 - }
70.955 - }
70.956 -
70.957 - Str documentationNode = PythonAstUtils.getDocumentationNode(root);
70.958 - if (documentationNode != null) {
70.959 - int astEnd = documentationNode.getCharStopIndex();
70.960 - begin = PythonLexerUtils.getLexerOffset(info, astEnd);
70.961 - if (begin == -1) {
70.962 - begin = 0;
70.963 - } else {
70.964 - begin = Math.min(doc.getLength(), begin);
70.965 - try {
70.966 - begin = Utilities.getRowEnd(doc, begin) + 1;
70.967 - begin = Math.min(begin, doc.getLength());
70.968 - } catch (BadLocationException ex) {
70.969 - Exceptions.printStackTrace(ex);
70.970 - begin = 0;
70.971 - }
70.972 - }
70.973 - }
70.974 -
70.975 - // TODO - I should even do a lexical lookup for this in case we're in an embedded scenario!
70.976 - return begin;
70.977 - }
70.978 -
70.979 - /** Determine if the given module is imported (for the given symbol) */
70.980 - public boolean isImported(String module, String ident) {
70.981 - for (Import imp : imports) {
70.982 - List<alias> names = imp.getInternalNames();
70.983 - if (names != null) {
70.984 - for (alias at : names) {
70.985 - if (module.equals(at.getInternalName()) && (ident == null || (ident.equals(module) || ident.equals(at.getInternalAsname())))) {
70.986 - return true;
70.987 - }
70.988 - }
70.989 - }
70.990 - }
70.991 -
70.992 - for (ImportFrom from : importsFrom) {
70.993 - if (module.equals(from.getInternalModule())) {
70.994 - // Make sure -this- symbol hasn't been imported!
70.995 - if (ident != null) {
70.996 - List<alias> names = from.getInternalNames();
70.997 - if (names != null) {
70.998 - for (alias at : names) {
70.999 - if (at.getInternalAsname() == null) {
70.1000 - // If you have "from module1 import Class1 as Class2", then
70.1001 - // "Class1" is not already imported, and "Class2" is.
70.1002 - if (ident.equals(at.getInternalName())) {
70.1003 - return true;
70.1004 - }
70.1005 - } else if (ident.equals(at.getInternalAsname())) {
70.1006 - return true;
70.1007 - }
70.1008 - }
70.1009 - }
70.1010 - }
70.1011 - }
70.1012 - }
70.1013 -
70.1014 - return false;
70.1015 - }
70.1016 -
70.1017 - public void ensureImported(String name, String ident, boolean packageImport, boolean useFqn, boolean warnIfExists) {
70.1018 - // TODO - look up the splitImports setting and add to existing import if possible...
70.1019 -
70.1020 - if (PythonIndex.isBuiltinModule(name)) {
70.1021 - return;
70.1022 - }
70.1023 -
70.1024 - // Test whether already imported
70.1025 - if (isImported(name, ident)) {
70.1026 - if (warnIfExists) {
70.1027 - Utilities.setStatusText(EditorRegistry.lastFocusedComponent(),
70.1028 - NbBundle.getMessage(
70.1029 - ImportManager.class,
70.1030 - packageImport ? "MSG_PackageAlreadyImported" : "MSG_ClassAlreadyImported",
70.1031 - name, ident));
70.1032 - Toolkit.getDefaultToolkit().beep();
70.1033 - }
70.1034 - return;
70.1035 - }
70.1036 -
70.1037 - int begin = getImportsLexOffset(ident);
70.1038 - try {
70.1039 - // TODO - warp to the new import and let you edit the "AS" part??
70.1040 -
70.1041 - if (useFqn || ident == null) {
70.1042 - doc.insertString(begin, "import " + name + "\n", null); // NOI18N
70.1043 - } else if (packageImport) {
70.1044 - //doc.insertString(begin, "import " + name + "\n", null); // NOI18N
70.1045 - doc.insertString(begin, "from " + name + " import *\n", null); // NOI18N
70.1046 - } else {
70.1047 - doc.insertString(begin, "from " + name + " import " + ident + "\n", null); // NOI18N
70.1048 - }
70.1049 - } catch (BadLocationException ble) {
70.1050 - Exceptions.printStackTrace(ble);
70.1051 - }
70.1052 - }
70.1053 -}
71.1 --- a/python.editor/src/org/netbeans/modules/python/editor/imports/ImportModulePanel.java Fri Sep 18 16:20:24 2015 -0500
71.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/imports/ImportModulePanel.java Mon Sep 21 13:01:16 2015 +0200
71.3 @@ -43,6 +43,7 @@
71.4 */
71.5 package org.netbeans.modules.python.editor.imports;
71.6
71.7 +import org.netbeans.modules.python.source.ImportManager;
71.8 import java.awt.Color;
71.9 import java.awt.Component;
71.10 import java.awt.Font;
71.11 @@ -64,9 +65,9 @@
71.12 import org.netbeans.editor.Utilities;
71.13 import org.netbeans.modules.csl.api.ElementKind;
71.14 import org.netbeans.modules.csl.spi.GsfUtilities;
71.15 -import org.netbeans.modules.python.editor.PythonIndex;
71.16 -import org.netbeans.modules.python.editor.PythonParserResult;
71.17 -import org.netbeans.modules.python.editor.lexer.Call;
71.18 +import org.netbeans.modules.python.source.PythonIndex;
71.19 +import org.netbeans.modules.python.source.PythonParserResult;
71.20 +import org.netbeans.modules.python.source.lexer.Call;
71.21 import org.openide.util.Exceptions;
71.22 import org.openide.util.ImageUtilities;
71.23 import org.openide.util.NbBundle;
72.1 --- a/python.editor/src/org/netbeans/modules/python/editor/layer.xml Fri Sep 18 16:20:24 2015 -0500
72.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/layer.xml Mon Sep 21 13:01:16 2015 +0200
72.3 @@ -7,11 +7,6 @@
72.4 <folder name="x-python">
72.5 <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.python.editor.Bundle"/>
72.6
72.7 - <file name="language.instance">
72.8 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.lexer.PythonTokenId.language"/>
72.9 - <attr name="instanceOf" stringvalue="org.netbeans.api.lexer.Language"/>
72.10 - </file>
72.11 -
72.12 <folder name="Actions">
72.13 <file name="org-netbeans-modules-python-editor-imports-FixImportsAction.instance"/>
72.14 <file name="org-netbeans-modules-python-editor-imports-FastImportAction.instance"/>
72.15 @@ -142,37 +137,6 @@
72.16 </folder>
72.17 </folder>
72.18
72.19 - <folder name="csl-hints">
72.20 - <folder name="text">
72.21 - <folder name="x-python">
72.22 - <folder name="hints">
72.23 - <folder name="general">
72.24 - <attr name="position" intvalue="100"/>
72.25 - <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.python.editor.hints.Bundle"/>
72.26 - <file name="org-netbeans-modules-python-editor-hints-NameRule.instance"/>
72.27 - <file name="org-netbeans-modules-python-editor-hints-CreateDocString.instance"/>
72.28 - <file name="org-netbeans-modules-python-editor-hints-AssignToVariable.instance"/>
72.29 - <file name="org-netbeans-modules-python-editor-hints-SplitImports.instance"/>
72.30 - <file name="org-netbeans-modules-python-editor-hints-RelativeImports.instance"/>
72.31 - <file name="org-netbeans-modules-python-editor-hints-Deprecations.instance"/>
72.32 - <file name="org-netbeans-modules-python-editor-hints-UnusedImports.instance"/>
72.33 - <file name="org-netbeans-modules-python-editor-hints-UnusedDetector.instance"/>
72.34 - <file name="org-netbeans-modules-python-editor-hints-UnresolvedDetector.instance"/>
72.35 - <file name="org-netbeans-modules-python-editor-hints-UnresolvedClassComponents.instance"/>
72.36 - <file name="org-netbeans-modules-python-editor-hints-AllAssignExists.instance"/>
72.37 - <file name="org-netbeans-modules-python-editor-hints-AccessToProtected.instance"/>
72.38 - <file name="org-netbeans-modules-python-editor-hints-AttributeDefinedOutsideInit.instance"/>
72.39 - <file name="org-netbeans-modules-python-editor-hints-ClassCircularRedundancy.instance"/>
72.40 - </folder>
72.41 - </folder>
72.42 - <folder name="selection">
72.43 - <file name="org-netbeans-modules-python-editor-hints-SurroundWith.instance"/>
72.44 - <file name="org-netbeans-modules-python-editor-hints-ExtractCode.instance"/>
72.45 - </folder>
72.46 - </folder>
72.47 - </folder>
72.48 - </folder>
72.49 -
72.50 <folder name="CslPlugins">
72.51 <folder name="text">
72.52 <folder name="x-python">
72.53 @@ -180,12 +144,6 @@
72.54 <!-- <attr name="instanceOf" stringvalue="org.netbeans.modules.gsf.api.GsfLanguage"/>-->
72.55 <attr name="instanceClass" stringvalue="org.netbeans.modules.python.editor.PythonLanguage"/>
72.56 </file>
72.57 - <file name="structure.instance">
72.58 - <attr name="instanceClass" stringvalue="org.netbeans.modules.python.editor.PythonStructureScanner"/>
72.59 - </file>
72.60 - <file name="hints.instance">
72.61 - <attr name="instanceClass" stringvalue="org.netbeans.modules.python.editor.hints.PythonHintsProvider"/>
72.62 - </file>
72.63 <file name="codecoverage"/>
72.64 </folder>
72.65 </folder>
72.66 @@ -272,66 +230,6 @@
72.67 </folder>
72.68 </folder>
72.69
72.70 - <folder name="OptionsDialog">
72.71 - <folder name="PreviewExamples">
72.72 - <folder name="text">
72.73 - <file name="x-python" url="PythonExample.py"/>
72.74 - </folder>
72.75 - </folder>
72.76 - <folder name="Editor">
72.77 - <folder name="Hints">
72.78 - <attr name="position" intvalue="0"/>
72.79 - <folder name="text">
72.80 - <folder name="x-python">
72.81 - <file name="PythonHints.instance">
72.82 - <attr name="instanceOf" stringvalue="org.netbeans.spi.options.OptionsPanelController"/>
72.83 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.PythonHintOptions.createStatic"/>
72.84 - </file>
72.85 - </folder>
72.86 - </folder>
72.87 - </folder>
72.88 - <folder name="Formatting">
72.89 - <attr name="position" intvalue="0"/>
72.90 - <folder name="text">
72.91 - <folder name="x-python">
72.92 - <file name="Imports.instance">
72.93 - <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
72.94 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.options.FmtImports.getController"/>
72.95 - <attr name="position" intvalue="150"/>
72.96 - </file>
72.97 - <!-- Not yet implemented
72.98 - <file name="TabsAndIndents.instance">
72.99 - <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
72.100 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.options.FmtTabsIndents.getController"/>
72.101 - <attr name="position" intvalue="100"/>
72.102 - </file>
72.103 - <file name="Alignment.instance">
72.104 - <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
72.105 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.options.FmtAlignment.getController"/>
72.106 - <attr name="position" intvalue="200"/>
72.107 - </file>
72.108 - <file name="Wrapping.instance">
72.109 - <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
72.110 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.options.FmtWrapping.getController"/>
72.111 - <attr name="position" intvalue="400"/>
72.112 - </file>
72.113 - <file name="BlankLines.instance">
72.114 - <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
72.115 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.options.FmtBlankLines.getController"/>
72.116 - <attr name="position" intvalue="500"/>
72.117 - </file>
72.118 - -->
72.119 - <file name="Spaces.instance">
72.120 - <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
72.121 - <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.editor.options.FmtSpaces.getController"/>
72.122 - <attr name="position" intvalue="600"/>
72.123 - </file>
72.124 - </folder>
72.125 - </folder>
72.126 - </folder>
72.127 - </folder>
72.128 - </folder>
72.129 -
72.130 <folder name="Templates">
72.131 <folder name="Python">
72.132 <attr name="position" intvalue="1403"/>
73.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/BuiltinException.java Fri Sep 18 16:20:24 2015 -0500
73.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
73.3 @@ -1,127 +0,0 @@
73.4 -/*
73.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
73.6 - *
73.7 - * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
73.8 - *
73.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
73.10 - * Other names may be trademarks of their respective owners.
73.11 - *
73.12 - * The contents of this file are subject to the terms of either the GNU
73.13 - * General Public License Version 2 only ("GPL") or the Common
73.14 - * Development and Distribution License("CDDL") (collectively, the
73.15 - * "License"). You may not use this file except in compliance with the
73.16 - * License. You can obtain a copy of the License at
73.17 - * http://www.netbeans.org/cddl-gplv2.html
73.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
73.19 - * specific language governing permissions and limitations under the
73.20 - * License. When distributing the software, include this License Header
73.21 - * Notice in each file and include the License file at
73.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
73.23 - * particular file as subject to the "Classpath" exception as provided
73.24 - * by Oracle in the GPL Version 2 section of the License file that
73.25 - * accompanied this code. If applicable, add the following below the
73.26 - * License Header, with the fields enclosed by brackets [] replaced by
73.27 - * your own identifying information:
73.28 - * "Portions Copyrighted [year] [name of copyright owner]"
73.29 - *
73.30 - * If you wish your version of this file to be governed by only the CDDL
73.31 - * or only the GPL Version 2, indicate your decision by adding
73.32 - * "[Contributor] elects to include this software in this distribution
73.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
73.34 - * single choice of license, a recipient has the option to distribute
73.35 - * your version of this file under either the CDDL, the GPL Version 2 or
73.36 - * to extend the choice of license to its licensees as provided above.
73.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
73.38 - * Version 2 license, then the option applies only if the new code is
73.39 - * made subject to such option by the copyright holder.
73.40 - *
73.41 - * Contributor(s):
73.42 - *
73.43 - * Portions Copyrighted 2015 Sun Microsystems, Inc.
73.44 - */
73.45 -package org.netbeans.modules.python.editor.lexer;
73.46 -
73.47 -import java.util.Arrays;
73.48 -import java.util.HashSet;
73.49 -import java.util.Set;
73.50 -
73.51 -/**
73.52 - *
73.53 - * @author jenselme
73.54 - */
73.55 -public class BuiltinException {
73.56 - private final static String[] BUILTIN_EXCEPTIONS_ARRAY = {
73.57 - "ArithmeticError",
73.58 - "AssertionError",
73.59 - "AttributeError",
73.60 - "BaseException",
73.61 - "BlockingIOError",
73.62 - "BrokenPipeError",
73.63 - "BufferError",
73.64 - "BytesWarning",
73.65 - "BytesWarningBaseException",
73.66 - "ChildProcessError",
73.67 - "ConnectionAbortedError",
73.68 - "ConnectionError",
73.69 - "ConnectionRefusedError",
73.70 - "ConnectionResetError",
73.71 - "DeprecationWarning",
73.72 - "EnvironmentError",
73.73 - "EOFError",
73.74 - "Exception",
73.75 - "FileExistsError",
73.76 - "FileNotFoundError",
73.77 - "FloatingPointError",
73.78 - "FutureWarning",
73.79 - "GeneratorExit",
73.80 - "ImportError",
73.81 - "ImportWarning",
73.82 - "IndentationError",
73.83 - "IndexError",
73.84 - "InterruptedError",
73.85 - "IOError",
73.86 - "IsADirectoryError",
73.87 - "KeyboardInterrupt",
73.88 - "KeyError",
73.89 - "LookupError",
73.90 - "MemoryError",
73.91 - "NameError",
73.92 - "NotADirectoryError",
73.93 - "NotImplementedError",
73.94 - "OSError",
73.95 - "OverflowError",
73.96 - "PendingDeprecationWarning",
73.97 - "PermissionError",
73.98 - "ProcessLookupError",
73.99 - "ReferenceError",
73.100 - "ResourceWarning",
73.101 - "RuntimeError",
73.102 - "RuntimeWarning",
73.103 - "StandardError",
73.104 - "StopIteration",
73.105 - "SyntaxError",
73.106 - "SyntaxWarning",
73.107 - "SystemError",
73.108 - "SystemExit",
73.109 - "TabError",
73.110 - "TimeoutError",
73.111 - "TypeError",
73.112 - "UnboundLocalError",
73.113 - "UnicodeDecodeError",
73.114 - "UnicodeEncodeError",
73.115 - "UnicodeError",
73.116 - "UnicodeTranslateError",
73.117 - "UnicodeWarning",
73.118 - "UserWarning",
73.119 - "ValueError",
73.120 - "VMSError",
73.121 - "Warning",
73.122 - "WindowsError",
73.123 - "ZeroDivisionError"
73.124 - };
73.125 - private final static Set<String> BUILTIN_EXCEPTIONS = new HashSet<String>(Arrays.asList(BUILTIN_EXCEPTIONS_ARRAY));
73.126 -
73.127 - public static boolean isBuiltInException(CharSequence name) {
73.128 - return BUILTIN_EXCEPTIONS.contains(name.toString());
73.129 - }
73.130 -}
74.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/Call.java Fri Sep 18 16:20:24 2015 -0500
74.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
74.3 @@ -1,322 +0,0 @@
74.4 -/*
74.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
74.6 - *
74.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
74.8 - *
74.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
74.10 - * Other names may be trademarks of their respective owners.
74.11 - *
74.12 - * The contents of this file are subject to the terms of either the GNU
74.13 - * General Public License Version 2 only ("GPL") or the Common
74.14 - * Development and Distribution License("CDDL") (collectively, the
74.15 - * "License"). You may not use this file except in compliance with the
74.16 - * License. You can obtain a copy of the License at
74.17 - * http://www.netbeans.org/cddl-gplv2.html
74.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
74.19 - * specific language governing permissions and limitations under the
74.20 - * License. When distributing the software, include this License Header
74.21 - * Notice in each file and include the License file at
74.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
74.23 - * particular file as subject to the "Classpath" exception as provided
74.24 - * by Oracle in the GPL Version 2 section of the License file that
74.25 - * accompanied this code. If applicable, add the following below the
74.26 - * License Header, with the fields enclosed by brackets [] replaced by
74.27 - * your own identifying information:
74.28 - * "Portions Copyrighted [year] [name of copyright owner]"
74.29 - *
74.30 - * Contributor(s):
74.31 - *
74.32 - * The Original Software is NetBeans. The Initial Developer of the Original
74.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
74.34 - * Microsystems, Inc. All Rights Reserved.
74.35 - *
74.36 - * If you wish your version of this file to be governed by only the CDDL
74.37 - * or only the GPL Version 2, indicate your decision by adding
74.38 - * "[Contributor] elects to include this software in this distribution
74.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
74.40 - * single choice of license, a recipient has the option to distribute
74.41 - * your version of this file under either the CDDL, the GPL Version 2 or
74.42 - * to extend the choice of license to its licensees as provided above.
74.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
74.44 - * Version 2 license, then the option applies only if the new code is
74.45 - * made subject to such option by the copyright holder.
74.46 - */
74.47 -package org.netbeans.modules.python.editor.lexer;
74.48 -
74.49 -import javax.swing.text.BadLocationException;
74.50 -import javax.swing.text.Document;
74.51 -import org.netbeans.api.annotations.common.NonNull;
74.52 -
74.53 -import org.netbeans.api.lexer.Token;
74.54 -import org.netbeans.api.lexer.TokenHierarchy;
74.55 -import org.netbeans.api.lexer.TokenId;
74.56 -import org.netbeans.api.lexer.TokenSequence;
74.57 -import org.netbeans.editor.BaseDocument;
74.58 -import org.netbeans.editor.Utilities;
74.59 -import org.openide.util.Exceptions;
74.60 -
74.61 -/**
74.62 - * Class which represents a Call in the source
74.63 - */
74.64 -public class Call {
74.65 - public static final Call LOCAL = new Call(null, null, false, false);
74.66 - public static final Call NONE = new Call(null, null, false, false);
74.67 - public static final Call UNKNOWN = new Call(null, null, false, false);
74.68 - private final String type;
74.69 - private final String lhs;
74.70 - private final boolean isStatic;
74.71 - private final boolean methodExpected;
74.72 -
74.73 - public Call(String type, String lhs, boolean isStatic, boolean methodExpected) {
74.74 - super();
74.75 - this.type = type;
74.76 - this.lhs = lhs;
74.77 - this.methodExpected = methodExpected;
74.78 - if (lhs == null) {
74.79 - lhs = type;
74.80 - }
74.81 - this.isStatic = isStatic;
74.82 - }
74.83 -
74.84 - public String getType() {
74.85 - return type;
74.86 - }
74.87 -
74.88 - public String getLhs() {
74.89 - return lhs;
74.90 - }
74.91 -
74.92 - public boolean isStatic() {
74.93 - return isStatic;
74.94 - }
74.95 -
74.96 - public boolean isSimpleIdentifier() {
74.97 - if (lhs == null) {
74.98 - return false;
74.99 - }
74.100 - // TODO - replace with the new PythonUtil validations
74.101 - for (int i = 0, n = lhs.length(); i < n; i++) {
74.102 - char c = lhs.charAt(i);
74.103 - if (Character.isJavaIdentifierPart(c)) {
74.104 - continue;
74.105 - }
74.106 - return false;
74.107 - }
74.108 - return true;
74.109 - }
74.110 -
74.111 - @Override
74.112 - public String toString() {
74.113 - if (this == LOCAL) {
74.114 - return "LOCAL";
74.115 - } else if (this == NONE) {
74.116 - return "NONE";
74.117 - } else if (this == UNKNOWN) {
74.118 - return "UNKNOWN";
74.119 - } else {
74.120 - return "Call(" + type + "," + lhs + "," + isStatic + ")";
74.121 - }
74.122 - }
74.123 -
74.124 - /** foo.| or foo.b| -> we're expecting a method call. For Foo:: we don't know. */
74.125 - public boolean isMethodExpected() {
74.126 - return this.methodExpected;
74.127 - }
74.128 -
74.129 - /**
74.130 - * Determine whether the given offset corresponds to a method call on another
74.131 - * object. This would happen in these cases:
74.132 - * Foo::|, Foo::Bar::|, Foo.|, Foo.x|, foo.|, foo.x|
74.133 - * and not here:
74.134 - * |, Foo|, foo|
74.135 - * The method returns the left hand side token, if any, such as "Foo", Foo::Bar",
74.136 - * and "foo". If not, it will return null.
74.137 - * Note that "self" and "super" are possible return values for the lhs, which mean
74.138 - * that you don't have a call on another object. Clients of this method should
74.139 - * handle that return value properly (I could return null here, but clients probably
74.140 - * want to distinguish self and super in this case so it's useful to return the info.)
74.141 - *
74.142 - * This method will also try to be smart such that if you have a block or array
74.143 - * call, it will return the relevant classnames (e.g. for [1,2].x| it returns "Array").
74.144 - */
74.145 - @SuppressWarnings("unchecked")
74.146 - @NonNull
74.147 - public static Call getCallType(BaseDocument doc, TokenHierarchy<Document> th, int offset) {
74.148 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(th, offset);
74.149 -
74.150 - if (ts == null) {
74.151 - return Call.NONE;
74.152 - }
74.153 -
74.154 - ts.move(offset);
74.155 -
74.156 - boolean methodExpected = false;
74.157 -
74.158 - if (!ts.moveNext() && !ts.movePrevious()) {
74.159 - return Call.NONE;
74.160 - }
74.161 -
74.162 - if (ts.offset() == offset) {
74.163 - // We're looking at the offset to the RIGHT of the caret
74.164 - // position, which could be whitespace, e.g.
74.165 - // "foo.x| " <-- looking at the whitespace
74.166 - ts.movePrevious();
74.167 - }
74.168 -
74.169 - Token<? extends PythonTokenId> token = ts.token();
74.170 -
74.171 - if (token != null) {
74.172 - TokenId id = token.id();
74.173 -
74.174 - if (id == PythonTokenId.WHITESPACE) {
74.175 - return Call.LOCAL;
74.176 - }
74.177 -
74.178 - // See if we're in the identifier - "x" in "foo.x"
74.179 - // I could also be a keyword in case the prefix happens to currently
74.180 - // match a keyword, such as "next"
74.181 - // However, if we're at the end of the document, x. will lex . as an
74.182 - // identifier of text ".", so handle this case specially
74.183 - if ((id == PythonTokenId.IDENTIFIER)/* || (id == PythonTokenId.CONSTANT)*/ ||
74.184 - id.primaryCategory().equals("keyword")) {
74.185 - String tokenText = token.text().toString();
74.186 -
74.187 - if (".".equals(tokenText)) {
74.188 - // Special case - continue - we'll handle this part next
74.189 - methodExpected = true;
74.190 - } else {
74.191 - methodExpected = true;
74.192 -
74.193 - if (Character.isUpperCase(tokenText.charAt(0))) {
74.194 - methodExpected = false;
74.195 - }
74.196 -
74.197 - if (!ts.movePrevious()) {
74.198 - return Call.LOCAL;
74.199 - }
74.200 - }
74.201 -
74.202 - token = ts.token();
74.203 - id = token.id();
74.204 - }
74.205 -
74.206 - // If we're not in the identifier we need to be in the dot (in "foo.x").
74.207 - // I can't just check for tokens DOT and COLON3 because for unparseable source
74.208 - // (like "File.|") the lexer will return the "." as an identifier.
74.209 - if (id == PythonTokenId.DOT) {
74.210 - methodExpected = true;
74.211 - } else if (id == PythonTokenId.IDENTIFIER) {
74.212 - String t = token.text().toString();
74.213 -
74.214 - if (t.equals(".")) {
74.215 - methodExpected = true;
74.216 - } else {
74.217 - return Call.LOCAL;
74.218 - }
74.219 - } else {
74.220 - return Call.LOCAL;
74.221 - }
74.222 -
74.223 - int lastSeparatorOffset = ts.offset();
74.224 - int beginOffset = lastSeparatorOffset;
74.225 - int lineStart = 0;
74.226 -
74.227 - try {
74.228 - if (offset > doc.getLength()) {
74.229 - offset = doc.getLength();
74.230 - }
74.231 -
74.232 - lineStart = Utilities.getRowStart(doc, offset);
74.233 - } catch (BadLocationException ble) {
74.234 - Exceptions.printStackTrace(ble);
74.235 - }
74.236 -
74.237 - // Find the beginning of the expression. We'll go past keywords, identifiers
74.238 - // and dots or double-colons
74.239 - while (ts.movePrevious()) {
74.240 - // If we get to the previous line we're done
74.241 - if (ts.offset() < lineStart) {
74.242 - break;
74.243 - }
74.244 -
74.245 - token = ts.token();
74.246 - id = token.id();
74.247 -
74.248 - String tokenText = null;
74.249 - if (id == PythonTokenId.ANY_KEYWORD || id == PythonTokenId.IDENTIFIER) {
74.250 - tokenText = token.text().toString();
74.251 - }
74.252 -
74.253 - if (id == PythonTokenId.WHITESPACE) {
74.254 - break;
74.255 - } else if (id == PythonTokenId.RBRACKET) {
74.256 - return new Call("ListType", null, false, methodExpected);
74.257 - } else if (id == PythonTokenId.RBRACE) {
74.258 - return new Call("DictType", null, false, methodExpected);
74.259 - } else if ((id == PythonTokenId.STRING_END)/* || (id == PythonTokenId.QUOTED_STRING_END)*/) {
74.260 - return new Call("StringType", null, false, methodExpected);
74.261 - } else if ((id == PythonTokenId.IDENTIFIER) && "True".equals(tokenText)) { // NOI18N
74.262 - return new Call("BooleanType", null, false, methodExpected);
74.263 - } else if ((id == PythonTokenId.IDENTIFIER) && "False".equals(tokenText)) { // NOI18N
74.264 - return new Call("BooleanType", null, false, methodExpected);
74.265 - } else if (((id == PythonTokenId.IDENTIFIER)) ||
74.266 - id.primaryCategory().equals("keyword") || (id == PythonTokenId.DOT)) {
74.267 -
74.268 - // We're building up a potential expression such as "Test::Unit" so continue looking
74.269 - beginOffset = ts.offset();
74.270 -
74.271 - continue;
74.272 - } else if ((id == PythonTokenId.LPAREN) || (id == PythonTokenId.LBRACE) ||
74.273 - (id == PythonTokenId.LBRACKET)) {
74.274 - // It's an expression for example within a parenthesis, e.g.
74.275 - // yield(^File.join())
74.276 - // in this case we can do top level completion
74.277 - // TODO: There are probably more valid contexts here
74.278 - break;
74.279 - } else if (id == PythonTokenId.ANY_OPERATOR) {
74.280 - break;
74.281 - } else {
74.282 - // Something else - such as "getFoo().x|" - at this point we don't know the type
74.283 - // so we'll just return unknown
74.284 - return Call.UNKNOWN;
74.285 - }
74.286 - }
74.287 -
74.288 - if (beginOffset < lastSeparatorOffset) {
74.289 - try {
74.290 - String lhs = doc.getText(beginOffset, lastSeparatorOffset - beginOffset);
74.291 -
74.292 - if (lhs.equals("super") || lhs.equals("self")) { // NOI18N
74.293 -
74.294 - return new Call(lhs, lhs, false, true);
74.295 - } else if (Character.isUpperCase(lhs.charAt(0))) {
74.296 -
74.297 -// // Detect constructor calls of the form String.new.^
74.298 -// if (lhs.endsWith(".new")) { // NOI18N
74.299 -// // See if it looks like a type prior to that
74.300 -// String type = lhs.substring(0, lhs.length()-4); // 4=".new".length()
74.301 -// if (PythonUtils.isValidPythonModuleName(type)) {
74.302 -// return new Call(type, lhs, false, methodExpected);
74.303 -// }
74.304 -// }
74.305 -
74.306 - String type = null;
74.307 -// if (PythonUtils.isValidPythonModuleName(lhs)) {
74.308 - type = lhs;
74.309 -// }
74.310 -
74.311 - return new Call(type, lhs, true, methodExpected);
74.312 - } else {
74.313 - return new Call(null, lhs, false, methodExpected);
74.314 - }
74.315 - } catch (BadLocationException ble) {
74.316 - Exceptions.printStackTrace(ble);
74.317 - }
74.318 - } else {
74.319 - return Call.UNKNOWN;
74.320 - }
74.321 - }
74.322 -
74.323 - return Call.LOCAL;
74.324 - }
74.325 -}
75.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonCommentLexer.java Fri Sep 18 16:20:24 2015 -0500
75.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
75.3 @@ -1,229 +0,0 @@
75.4 -/*
75.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
75.6 - *
75.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
75.8 - *
75.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
75.10 - * Other names may be trademarks of their respective owners.
75.11 - *
75.12 - * The contents of this file are subject to the terms of either the GNU
75.13 - * General Public License Version 2 only ("GPL") or the Common
75.14 - * Development and Distribution License("CDDL") (collectively, the
75.15 - * "License"). You may not use this file except in compliance with the
75.16 - * License. You can obtain a copy of the License at
75.17 - * http://www.netbeans.org/cddl-gplv2.html
75.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
75.19 - * specific language governing permissions and limitations under the
75.20 - * License. When distributing the software, include this License Header
75.21 - * Notice in each file and include the License file at
75.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
75.23 - * particular file as subject to the "Classpath" exception as provided
75.24 - * by Oracle in the GPL Version 2 section of the License file that
75.25 - * accompanied this code. If applicable, add the following below the
75.26 - * License Header, with the fields enclosed by brackets [] replaced by
75.27 - * your own identifying information:
75.28 - * "Portions Copyrighted [year] [name of copyright owner]"
75.29 - *
75.30 - * Contributor(s):
75.31 - *
75.32 - * The Original Software is NetBeans. The Initial Developer of the Original
75.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
75.34 - * Microsystems, Inc. All Rights Reserved.
75.35 - *
75.36 - * If you wish your version of this file to be governed by only the CDDL
75.37 - * or only the GPL Version 2, indicate your decision by adding
75.38 - * "[Contributor] elects to include this software in this distribution
75.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
75.40 - * single choice of license, a recipient has the option to distribute
75.41 - * your version of this file under either the CDDL, the GPL Version 2 or
75.42 - * to extend the choice of license to its licensees as provided above.
75.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
75.44 - * Version 2 license, then the option applies only if the new code is
75.45 - * made subject to such option by the copyright holder.
75.46 - */
75.47 -package org.netbeans.modules.python.editor.lexer;
75.48 -
75.49 -import org.netbeans.api.lexer.Token;
75.50 -import org.netbeans.spi.lexer.Lexer;
75.51 -import org.netbeans.spi.lexer.LexerInput;
75.52 -import org.netbeans.spi.lexer.LexerRestartInfo;
75.53 -import org.netbeans.spi.lexer.TokenFactory;
75.54 -
75.55 -/**
75.56 - * A lexer for python comments.
75.57 - *
75.58 - * Highlights TODO items and certain keywords (like @-param and @-type (without -)).
75.59 - *
75.60 - * @author Tor Norbye
75.61 - */
75.62 -public class PythonCommentLexer implements Lexer<PythonCommentTokenId> {
75.63 - private static final int EOF = LexerInput.EOF;
75.64 - private final LexerInput input;
75.65 - private final TokenFactory<PythonCommentTokenId> tokenFactory;
75.66 - private final boolean substituting;
75.67 -
75.68 - private static enum State {
75.69 - INIT,
75.70 - /** We've just seen @type */
75.71 - SEEN_TYPE_KEY,
75.72 - /** We've just seen @type< > */
75.73 - SEEN_TYPE_WS,
75.74 - /** We've just seen @type <varname> */
75.75 - SEEN_NAME,
75.76 - /** We've just seen @type varname< > */
75.77 - SEEN_NAME_WS
75.78 - };
75.79 - private State state;
75.80 -
75.81 - /**
75.82 - * A Lexer for Python strings
75.83 - * @param substituting If true, handle substitution rules for double quoted strings, otherwise
75.84 - * single quoted strings.
75.85 - */
75.86 - public PythonCommentLexer(LexerRestartInfo<PythonCommentTokenId> info, boolean substituting) {
75.87 - this.input = info.input();
75.88 - this.tokenFactory = info.tokenFactory();
75.89 - this.substituting = substituting;
75.90 - state = (State)info.state();
75.91 - if (state == null) {
75.92 - state = State.INIT;
75.93 - }
75.94 - }
75.95 -
75.96 - @Override
75.97 - public Object state() {
75.98 - return state;
75.99 - }
75.100 -
75.101 - @Override
75.102 - public Token<PythonCommentTokenId> nextToken() {
75.103 - switch (state) {
75.104 - case SEEN_NAME:
75.105 - case SEEN_TYPE_KEY:
75.106 - while (true) {
75.107 - int ch = input.read();
75.108 - if (ch == ':' && state == State.SEEN_NAME && input.readLength() == 1) {
75.109 - continue;
75.110 - }
75.111 - if (ch == EOF || !Character.isWhitespace(ch)) {
75.112 - if (ch != EOF) {
75.113 - input.backup(1);
75.114 - }
75.115 - if (input.readLength() > 0) {
75.116 - state = (state == State.SEEN_TYPE_KEY) ? State.SEEN_TYPE_WS : State.SEEN_NAME_WS;
75.117 - return tokenFactory.createToken(PythonCommentTokenId.SEPARATOR,
75.118 - input.readLength());
75.119 - } else {
75.120 - return null;
75.121 - }
75.122 - }
75.123 - }
75.124 -
75.125 - case SEEN_NAME_WS:
75.126 - case SEEN_TYPE_WS:
75.127 - while (true) {
75.128 - int ch = input.read();
75.129 - if (ch == EOF || Character.isWhitespace(ch) || ch == ':') {
75.130 - if (ch != EOF) {
75.131 - input.backup(1);
75.132 - }
75.133 - if (input.readLength() > 0) {
75.134 - State nextState;
75.135 - PythonCommentTokenId id;
75.136 - if (state == State.SEEN_TYPE_WS) {
75.137 - nextState = State.SEEN_NAME;
75.138 - id = PythonCommentTokenId.VARNAME;
75.139 - } else {
75.140 - nextState = State.INIT;
75.141 - id = PythonCommentTokenId.TYPE;
75.142 - }
75.143 - state = nextState;
75.144 - return tokenFactory.createToken(id, input.readLength());
75.145 - } else if (ch == EOF) {
75.146 - return null;
75.147 - } else {
75.148 - // Error - : without an actual var name
75.149 - state = State.INIT;
75.150 - return nextToken(); // recurse
75.151 - }
75.152 - }
75.153 - }
75.154 - default:
75.155 - case INIT: {
75.156 -
75.157 - int last = EOF;
75.158 - while (true) {
75.159 - int ch = input.read();
75.160 -
75.161 - switch (ch) {
75.162 - case EOF:
75.163 - if (input.readLength() > 0) {
75.164 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
75.165 - input.readLength());
75.166 - } else {
75.167 - return null;
75.168 - }
75.169 -
75.170 - case '@': {
75.171 - // Is it "@type"
75.172 - int initialReadLength = input.readLength();
75.173 - if (input.read() == 't' && input.read() == 'y' && input.read() == 'p' && input.read() == 'e') {
75.174 - if (input.readLength() > 5) {
75.175 - input.backup(5);
75.176 - // Finish this token such that we can do a dedicated token for the @type item.
75.177 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
75.178 - input.readLength());
75.179 - }
75.180 - state = State.SEEN_TYPE_KEY;
75.181 - return tokenFactory.createToken(PythonCommentTokenId.TYPEKEY,
75.182 - input.readLength());
75.183 - }
75.184 - if (input.readLength() > initialReadLength) {
75.185 - input.backup(input.readLength() - initialReadLength);
75.186 - } else {
75.187 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
75.188 - input.readLength());
75.189 - }
75.190 - }
75.191 - break;
75.192 -
75.193 - case 'T': {
75.194 - if (last == EOF || !Character.isLetter(last)) {
75.195 - // Is it "\wTODO\w" ?
75.196 - int initialReadLength = input.readLength();
75.197 - if (input.read() == 'O' && input.read() == 'D' && input.read() == 'O') {
75.198 - int peek = input.read();
75.199 - input.backup(1);
75.200 - if (peek == EOF || !Character.isLetter(peek)) {
75.201 - if (input.readLength() > 4) {
75.202 - input.backup(4);
75.203 - // Finish this token such that we can do a dedicated token for the @type item.
75.204 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
75.205 - input.readLength());
75.206 - }
75.207 - return tokenFactory.createToken(PythonCommentTokenId.TODO,
75.208 - input.readLength());
75.209 - }
75.210 - }
75.211 - if (input.readLength() > initialReadLength) {
75.212 - input.backup(input.readLength() - initialReadLength);
75.213 - } else {
75.214 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
75.215 - input.readLength());
75.216 - }
75.217 - }
75.218 - }
75.219 - break;
75.220 - }
75.221 -
75.222 - last = ch;
75.223 - }
75.224 -
75.225 - }
75.226 - }
75.227 - }
75.228 -
75.229 - @Override
75.230 - public void release() {
75.231 - }
75.232 -}
76.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonCommentTokenId.java Fri Sep 18 16:20:24 2015 -0500
76.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
76.3 @@ -1,120 +0,0 @@
76.4 -/*
76.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
76.6 - *
76.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
76.8 - *
76.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
76.10 - * Other names may be trademarks of their respective owners.
76.11 - *
76.12 - * The contents of this file are subject to the terms of either the GNU
76.13 - * General Public License Version 2 only ("GPL") or the Common
76.14 - * Development and Distribution License("CDDL") (collectively, the
76.15 - * "License"). You may not use this file except in compliance with the
76.16 - * License. You can obtain a copy of the License at
76.17 - * http://www.netbeans.org/cddl-gplv2.html
76.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
76.19 - * specific language governing permissions and limitations under the
76.20 - * License. When distributing the software, include this License Header
76.21 - * Notice in each file and include the License file at
76.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
76.23 - * particular file as subject to the "Classpath" exception as provided
76.24 - * by Oracle in the GPL Version 2 section of the License file that
76.25 - * accompanied this code. If applicable, add the following below the
76.26 - * License Header, with the fields enclosed by brackets [] replaced by
76.27 - * your own identifying information:
76.28 - * "Portions Copyrighted [year] [name of copyright owner]"
76.29 - *
76.30 - * Contributor(s):
76.31 - *
76.32 - * The Original Software is NetBeans. The Initial Developer of the Original
76.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
76.34 - * Microsystems, Inc. All Rights Reserved.
76.35 - *
76.36 - * If you wish your version of this file to be governed by only the CDDL
76.37 - * or only the GPL Version 2, indicate your decision by adding
76.38 - * "[Contributor] elects to include this software in this distribution
76.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
76.40 - * single choice of license, a recipient has the option to distribute
76.41 - * your version of this file under either the CDDL, the GPL Version 2 or
76.42 - * to extend the choice of license to its licensees as provided above.
76.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
76.44 - * Version 2 license, then the option applies only if the new code is
76.45 - * made subject to such option by the copyright holder.
76.46 - */
76.47 -package org.netbeans.modules.python.editor.lexer;
76.48 -
76.49 -import java.util.Collection;
76.50 -import java.util.EnumSet;
76.51 -import java.util.Map;
76.52 -
76.53 -import org.netbeans.api.lexer.InputAttributes;
76.54 -import org.netbeans.api.lexer.Language;
76.55 -import org.netbeans.api.lexer.LanguagePath;
76.56 -import org.netbeans.api.lexer.Token;
76.57 -import org.netbeans.api.lexer.TokenId;
76.58 -import org.netbeans.spi.lexer.LanguageEmbedding;
76.59 -import org.netbeans.spi.lexer.LanguageHierarchy;
76.60 -import org.netbeans.spi.lexer.Lexer;
76.61 -import org.netbeans.spi.lexer.LexerRestartInfo;
76.62 -
76.63 -/**
76.64 - *
76.65 - * @author Tor Norbye
76.66 - */
76.67 -public enum PythonCommentTokenId implements TokenId {
76.68 - TEXT("comment"),
76.69 - KEYWORD("comment"),
76.70 - SEPARATOR("comment"),
76.71 - TYPEKEY("comment"),
76.72 - VARNAME("comment"),
76.73 - TYPE("comment"),
76.74 - TODO("comment");
76.75 - private final String primaryCategory;
76.76 -
76.77 - PythonCommentTokenId() {
76.78 - this(null);
76.79 - }
76.80 -
76.81 - PythonCommentTokenId(String primaryCategory) {
76.82 - this.primaryCategory = primaryCategory;
76.83 - }
76.84 -
76.85 - @Override
76.86 - public String primaryCategory() {
76.87 - return primaryCategory;
76.88 - }
76.89 - public static final Language<PythonCommentTokenId> language =
76.90 - new LanguageHierarchy<PythonCommentTokenId>() {
76.91 - @Override
76.92 - protected Collection<PythonCommentTokenId> createTokenIds() {
76.93 - return EnumSet.allOf(PythonCommentTokenId.class);
76.94 - }
76.95 -
76.96 - @Override
76.97 - protected Map<String, Collection<PythonCommentTokenId>> createTokenCategories() {
76.98 - return null; // no extra categories
76.99 - }
76.100 -
76.101 - @Override
76.102 - protected Lexer<PythonCommentTokenId> createLexer(
76.103 - LexerRestartInfo<PythonCommentTokenId> info) {
76.104 - return new PythonCommentLexer(info, true);
76.105 - }
76.106 -
76.107 - @Override
76.108 - protected LanguageEmbedding<?> embedding(
76.109 - Token<PythonCommentTokenId> token, LanguagePath languagePath,
76.110 - InputAttributes inputAttributes) {
76.111 - return null; // No embedding
76.112 - }
76.113 -
76.114 - @Override
76.115 - public String mimeType() {
76.116 - return "text/x-python-comment"; // NOI18N
76.117 - }
76.118 - }.language();
76.119 -
76.120 - public static Language<PythonCommentTokenId> language() {
76.121 - return language;
76.122 - }
76.123 -}
77.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonLexer.java Fri Sep 18 16:20:24 2015 -0500
77.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
77.3 @@ -1,1158 +0,0 @@
77.4 -/*
77.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
77.6 - *
77.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
77.8 - *
77.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
77.10 - * Other names may be trademarks of their respective owners.
77.11 - *
77.12 - * The contents of this file are subject to the terms of either the GNU
77.13 - * General Public License Version 2 only ("GPL") or the Common
77.14 - * Development and Distribution License("CDDL") (collectively, the
77.15 - * "License"). You may not use this file except in compliance with the
77.16 - * License. You can obtain a copy of the License at
77.17 - * http://www.netbeans.org/cddl-gplv2.html
77.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
77.19 - * specific language governing permissions and limitations under the
77.20 - * License. When distributing the software, include this License Header
77.21 - * Notice in each file and include the License file at
77.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
77.23 - * particular file as subject to the "Classpath" exception as provided
77.24 - * by Oracle in the GPL Version 2 section of the License file that
77.25 - * accompanied this code. If applicable, add the following below the
77.26 - * License Header, with the fields enclosed by brackets [] replaced by
77.27 - * your own identifying information:
77.28 - * "Portions Copyrighted [year] [name of copyright owner]"
77.29 - *
77.30 - * Contributor(s):
77.31 - *
77.32 - * The Original Software is NetBeans. The Initial Developer of the Original
77.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
77.34 - * Microsystems, Inc. All Rights Reserved.
77.35 - *
77.36 - * If you wish your version of this file to be governed by only the CDDL
77.37 - * or only the GPL Version 2, indicate your decision by adding
77.38 - * "[Contributor] elects to include this software in this distribution
77.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
77.40 - * single choice of license, a recipient has the option to distribute
77.41 - * your version of this file under either the CDDL, the GPL Version 2 or
77.42 - * to extend the choice of license to its licensees as provided above.
77.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
77.44 - * Version 2 license, then the option applies only if the new code is
77.45 - * made subject to such option by the copyright holder.
77.46 - */
77.47 -package org.netbeans.modules.python.editor.lexer;
77.48 -
77.49 -import org.netbeans.api.lexer.Token;
77.50 -import org.netbeans.api.lexer.TokenUtilities;
77.51 -import org.netbeans.spi.lexer.Lexer;
77.52 -import org.netbeans.spi.lexer.LexerInput;
77.53 -import org.netbeans.spi.lexer.LexerRestartInfo;
77.54 -import org.netbeans.spi.lexer.TokenFactory;
77.55 -
77.56 -/**
77.57 - * Lexer for Python.
77.58 - *
77.59 - * This is a hand written lexer for Python which recognizes the logical token types
77.60 - * we care about within the IDE support.
77.61 - *
77.62 - * Initially, we were using Jython's lexer directly here. However, that had some
77.63 - * problems:
77.64 - *
77.65 - * <ul>
77.66 - * <li>
77.67 - * In the IDE, we have to support incremental parsing. Not only is this a must
77.68 - * from a user performance perspective (typing a keystroke near the bottom of a
77.69 - * 2,000 line file shouldn't cause complete re-lexing of the entire document), but
77.70 - * the NetBeans APIs require it; they restart the lexer on the nearest token
77.71 - * boundary.
77.72 - * ANTLR doesn't support incremental lexing. I looked into what it would take
77.73 - * to patch it to do so (as I have done for JRuby in the Ruby support), but
77.74 - * it (a) wasn't trivial, and (b) would require a LOT of data to be stored for
77.75 - * every token boundary.
77.76 - * </li>
77.77 - * <li>
77.78 - * Similarly, we need to put our lexer on top of a LexerInput, and it is not
77.79 - * particularly compatible with the way ANTLR handles input. We had an
77.80 - * adapter class for this which was jumping through various hoops to expose
77.81 - * the LexerInput as ANTLR input. However, it had some severe problems with
77.82 - * large inputs.
77.83 - * </li>
77.84 - * <li>
77.85 - * We need slightly different token divisions. For example, for matching bracket
77.86 - * purposes, we'd like to have strings split into string delimiters and the
77.87 - * string contents. Similarly, Jython did some things like coalesce all whitespace
77.88 - * around a newline into that newline token which causes some complications
77.89 - * for our token analysis.
77.90 - * </li>
77.91 - * <li>
77.92 - * For Ruby, I decided to use the JRuby lexer because JRuby lexing is very
77.93 - * difficult. They have a huge complicated class to do the lexing - and there's
77.94 - * no Ruby language spec. Python on the other hand seems to have a very simple
77.95 - * lexing model, and a clear spec and grammar, so I don't feel worried that
77.96 - * our custom Python lexer is going to have a lot of corner case bugs.
77.97 - * </li>
77.98 - * </ul>
77.99 - *
77.100 - * @author Tor Norbye
77.101 - */
77.102 -public final class PythonLexer implements Lexer<PythonTokenId> {
77.103 - public static final String COMMENT_CAT = "comment";
77.104 - public static final String KEYWORD_CAT = "keyword"; // NOI18N
77.105 - public static final String STRING_CAT = "string"; // NOI18N
77.106 - public static final String WHITESPACE_CAT = "whitespace"; // NOI18N
77.107 - public static final String OPERATOR_CAT = "operator"; // NOI18N
77.108 - public static final String SEPARATOR_CAT = "separator"; // NOI18N
77.109 - public static final String ERROR_CAT = "error"; // NOI18N
77.110 - public static final String NUMBER_CAT = "number"; // NOI18N
77.111 - public static final String IDENTIFIER_CAT = "identifier"; // NOI18N
77.112 - private static final int EOF = LexerInput.EOF;
77.113 - private final LexerInput input;
77.114 - private final TokenFactory<PythonTokenId> tokenFactory;
77.115 -
77.116 - // Lexer state - preserved per token boundary
77.117 - private enum State {
77.118 - /** Normal state, same state as on entry into a Python file */
77.119 - INIT,
77.120 - /** We've processed the beginning string delimiter of a double-quoted short string */
77.121 - BEGIN_SHORTSTRING_DOUBLE,
77.122 - /** We've processed the beginning string delimiter of a single-quoted short string */
77.123 - BEGIN_SHORTSTRING_SINGLE,
77.124 - /** We've processed the beginning string delimiter of a double-quoted long string */
77.125 - BEGIN_LONGSTRING_DOUBLE,
77.126 - /** We've processed the beginning string delimiter of a singl-quoted long string */
77.127 - BEGIN_LONGSTRING_SINGLE,
77.128 - /** We've processed the string content in a double-quoted short string */
77.129 - END_SHORTSTRING_DOUBLE,
77.130 - /** We've processed the string content in a single-quoted short string */
77.131 - END_SHORTSTRING_SINGLE,
77.132 - /** We've processed the string content in a double-quoted long string */
77.133 - END_LONGSTRING_DOUBLE,
77.134 - /** We've processed the string content in a single-quoted long string */
77.135 - END_LONGSTRING_SINGLE,
77.136 - };
77.137 - private State state;
77.138 -
77.139 - public PythonLexer(LexerRestartInfo<PythonTokenId> info) {
77.140 - this.input = info.input();
77.141 - this.tokenFactory = info.tokenFactory();
77.142 -
77.143 - state = (State)info.state();
77.144 - if (state == null) {
77.145 - state = State.INIT;
77.146 - }
77.147 - }
77.148 -
77.149 - @Override
77.150 - public Object state() {
77.151 - return state;
77.152 - }
77.153 -
77.154 - private Token<PythonTokenId> createToken(PythonTokenId id, int tokenLength) {
77.155 - String fixedText = id.fixedText();
77.156 - return (fixedText != null) ? tokenFactory.getFlyweightToken(id, fixedText)
77.157 - : tokenFactory.createToken(id, tokenLength);
77.158 - }
77.159 -
77.160 - @SuppressWarnings("fallthrough")
77.161 - @Override
77.162 - public Token<PythonTokenId> nextToken() {
77.163 - switch (state) {
77.164 - case INIT: {
77.165 - int ch = input.read();
77.166 - switch (ch) {
77.167 - case EOF:
77.168 - return null;
77.169 -
77.170 - // Newline
77.171 - case '\n':
77.172 - assert input.readLength() == 1;
77.173 - return createToken(PythonTokenId.NEWLINE, 1);
77.174 -
77.175 - // Whitespace
77.176 - case ' ':
77.177 - case '\t': {
77.178 - for (; ch != EOF; ch = input.read()) {
77.179 - if (ch != ' ' && ch != '\t') {
77.180 - break;
77.181 - }
77.182 - }
77.183 - input.backup(1);
77.184 - return createToken(PythonTokenId.WHITESPACE, input.readLength());
77.185 - }
77.186 -
77.187 - // Comment
77.188 - case '#': {
77.189 - ch = input.read();
77.190 - while (ch != EOF && ch != '\n') {
77.191 - ch = input.read();
77.192 - }
77.193 - input.backup(1);
77.194 - return createToken(PythonTokenId.COMMENT, input.readLength());
77.195 - }
77.196 -
77.197 - case '.': {
77.198 - assert input.readLength() == 1;
77.199 - int peek = input.read();
77.200 - input.backup(1);
77.201 - if (!Character.isDigit(peek)) {
77.202 - return createToken(PythonTokenId.DOT, 1);
77.203 - } // else: Fallthrough to process the number!!
77.204 - } // FALLTHROUGH
77.205 - // FALLTHROUGH!!!!
77.206 -
77.207 - // Number (integer, float, complex)
77.208 - case '0':
77.209 - case '1':
77.210 - case '2':
77.211 - case '3':
77.212 - case '4':
77.213 - case '5':
77.214 - case '6':
77.215 - case '7':
77.216 - case '8':
77.217 - case '9': {
77.218 - if (ch == '0') {
77.219 - int peek = input.read();
77.220 - if (peek == 'x' || peek == 'X') {
77.221 - // Hex
77.222 - ch = input.read();
77.223 - while (ch != EOF) {
77.224 - if (!(Character.isDigit(ch) ||
77.225 - (ch >= 'a' && ch <= 'f') ||
77.226 - (ch >= 'A' && ch <= 'F'))) {
77.227 - break;
77.228 - }
77.229 - ch = input.read();
77.230 - }
77.231 - if (ch != 'l' && (ch != 'L')) {
77.232 - input.backup(1);
77.233 - }
77.234 - return createToken(PythonTokenId.INT_LITERAL, input.readLength());
77.235 - }
77.236 - input.backup(1);
77.237 - }
77.238 - boolean isFloat = false;
77.239 - digitLoop:
77.240 - for (; ch != EOF; ch = input.read()) {
77.241 - switch (ch) {
77.242 - case '0':
77.243 - case '1':
77.244 - case '2':
77.245 - case '3':
77.246 - case '4':
77.247 - case '5':
77.248 - case '6':
77.249 - case '7':
77.250 - case '8':
77.251 - case '9':
77.252 - continue;
77.253 - case '.':
77.254 - isFloat = true;
77.255 - continue;
77.256 - case 'e': // Exponent
77.257 - case 'E': {
77.258 - int peek = input.read();
77.259 - if (peek != '+' && peek != '-') {
77.260 - input.backup(1);
77.261 - }
77.262 - ch = input.read();
77.263 - while (ch != EOF) {
77.264 - if (!Character.isDigit(ch)) {
77.265 - break;
77.266 - }
77.267 - ch = input.read();
77.268 - }
77.269 - if (ch != 'j' && ch != 'J') {
77.270 - input.backup(1);
77.271 - }
77.272 - return createToken(PythonTokenId.FLOAT_LITERAL, input.readLength());
77.273 - }
77.274 - case 'j': // Imaginary
77.275 - case 'J':
77.276 - isFloat = true;
77.277 - break digitLoop;
77.278 - case 'l': // Long
77.279 - case 'L':
77.280 - break digitLoop;
77.281 - case EOF:
77.282 - default:
77.283 - input.backup(1);
77.284 - break digitLoop;
77.285 -
77.286 - }
77.287 - }
77.288 -
77.289 - return createToken(isFloat ? PythonTokenId.FLOAT_LITERAL : PythonTokenId.INT_LITERAL, input.readLength());
77.290 - }
77.291 -
77.292 - // Operators and delimiters
77.293 - case '+': // +,+=
77.294 - if (input.read() != '=') {
77.295 - input.backup(1);
77.296 - }
77.297 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.298 - case '-': // -,-=
77.299 - if (input.read() != '=') {
77.300 - input.backup(1);
77.301 - }
77.302 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.303 - case '*': { // *,**,*=, **=
77.304 - int peek = input.read();
77.305 - if (peek == '=') {
77.306 - // No need to back up, include it
77.307 - } else if (peek == '*') {
77.308 - peek = input.read();
77.309 - if (peek != '=') {
77.310 - input.backup(1);
77.311 - }
77.312 - } else {
77.313 - input.backup(1);
77.314 - }
77.315 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.316 - }
77.317 - case '/': {
77.318 - // Look for /,//, /=, //=
77.319 - int peek = input.read();
77.320 - if (peek == '=') {
77.321 - // No need to back up, include it
77.322 - } else if (peek == '/') {
77.323 - peek = input.read();
77.324 - if (peek != '=') {
77.325 - input.backup(1);
77.326 - }
77.327 - } else {
77.328 - input.backup(1);
77.329 - }
77.330 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.331 - }
77.332 - case '%': { // Look for %, %=
77.333 - if (input.read() != '=') {
77.334 - input.backup(1);
77.335 - }
77.336 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.337 - }
77.338 - case '<': {
77.339 - // Look for <, <<, <=, <>, <<=
77.340 - int peek = input.read();
77.341 - if (peek == '=') {
77.342 - // No need to back up, include it
77.343 - } else if (peek == '<') {
77.344 - peek = input.read();
77.345 - if (peek != '=') {
77.346 - input.backup(1);
77.347 - }
77.348 - } else if (peek != '>') {
77.349 - input.backup(1);
77.350 - }
77.351 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.352 - }
77.353 - case '>': {
77.354 - // Look for >, >>, >=, >>=
77.355 - int peek = input.read();
77.356 - if (peek == '=') {
77.357 - // No need to back up, include it
77.358 - } else if (peek == '>') {
77.359 - peek = input.read();
77.360 - if (peek != '=') {
77.361 - input.backup(1);
77.362 - }
77.363 - } else {
77.364 - input.backup(1);
77.365 - }
77.366 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.367 - }
77.368 - case '&': { // Look for &,&=
77.369 - if (input.read() != '=') {
77.370 - input.backup(1);
77.371 - }
77.372 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.373 - }
77.374 - case '|': { // Look for |, |=
77.375 - if (input.read() != '=') {
77.376 - input.backup(1);
77.377 - }
77.378 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.379 - }
77.380 - case '^': { // ^,^=
77.381 - if (input.read() != '=') {
77.382 - input.backup(1);
77.383 - }
77.384 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.385 - }
77.386 - case '=': {
77.387 - // Look for =,==
77.388 - if (input.read() != '=') {
77.389 - input.backup(1);
77.390 - }
77.391 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.392 - }
77.393 - case '!': {
77.394 - // Look for !=
77.395 - if (input.read() != '=') {
77.396 - input.backup(1);
77.397 - }
77.398 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.399 - }
77.400 - case '~':
77.401 - case '`':
77.402 - case ';':
77.403 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
77.404 -
77.405 - case ':':
77.406 - assert input.readLength() == 1;
77.407 - return createToken(PythonTokenId.COLON, 1);
77.408 - case '(':
77.409 - assert input.readLength() == 1;
77.410 - return createToken(PythonTokenId.LPAREN, 1);
77.411 - case ')':
77.412 - assert input.readLength() == 1;
77.413 - return createToken(PythonTokenId.RPAREN, 1);
77.414 - case '[':
77.415 - assert input.readLength() == 1;
77.416 - return createToken(PythonTokenId.LBRACKET, 1);
77.417 - case ']':
77.418 - assert input.readLength() == 1;
77.419 - return createToken(PythonTokenId.RBRACKET, 1);
77.420 - case '{':
77.421 - assert input.readLength() == 1;
77.422 - return createToken(PythonTokenId.LBRACE, 1);
77.423 - case '}':
77.424 - assert input.readLength() == 1;
77.425 - return createToken(PythonTokenId.RBRACE, 1);
77.426 - case ',':
77.427 - assert input.readLength() == 1;
77.428 - return createToken(PythonTokenId.COMMA, 1);
77.429 - case '\\':
77.430 - assert input.readLength() == 1;
77.431 - return createToken(PythonTokenId.ESC, 1);
77.432 -
77.433 - case '$':
77.434 - case '?':
77.435 - assert input.readLength() == 1;
77.436 - return createToken(PythonTokenId.ERROR, 1);
77.437 -
77.438 - // String?
77.439 - case '\'':
77.440 - case '"': {
77.441 - int peek = input.read();
77.442 - if (peek != ch) {
77.443 - input.backup(1);
77.444 - assert input.readLength() == 1;
77.445 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
77.446 - return createToken(PythonTokenId.STRING_BEGIN, 1);
77.447 - }
77.448 - // We've seen two quotes... it's either an empty string,
77.449 - // or the beginning of a longstring
77.450 - int peek2 = input.read();
77.451 - if (peek2 == peek) {
77.452 - // It's a longstring!
77.453 - assert input.readLength() == 3;
77.454 - state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
77.455 - return createToken(PythonTokenId.STRING_BEGIN, 3);
77.456 - } else {
77.457 - input.backup(2);
77.458 - assert input.readLength() == 1;
77.459 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
77.460 - return createToken(PythonTokenId.STRING_BEGIN, 1);
77.461 - }
77.462 - }
77.463 - case '@': { // Decorator
77.464 - // Identifier or keyword?
77.465 - ch = input.read();
77.466 - if (Character.isJavaIdentifierStart(ch)) {
77.467 - while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
77.468 - ch = input.read();
77.469 - }
77.470 - input.backup(1);
77.471 -
77.472 - return createToken(PythonTokenId.DECORATOR, input.readLength());
77.473 - }
77.474 - input.backup(1); // Remove the peeked char
77.475 -
77.476 - assert input.readLength() == 1;
77.477 - return createToken(PythonTokenId.DECORATOR, 1);
77.478 - }
77.479 -
77.480 - case 'r':
77.481 - case 'R':
77.482 - case 'u':
77.483 - case 'U': {
77.484 - // Digest the "u" and the "r" and position the input
77.485 - // before the following ' or "
77.486 - boolean isStringPrefix = false;
77.487 - int peek = input.read();
77.488 - if (ch == 'r' || ch == 'R') {
77.489 - if (peek == '\'' || peek == '"') {
77.490 - isStringPrefix = true;
77.491 - }
77.492 - input.backup(1);
77.493 - } else {
77.494 - assert ch == 'u' || ch == 'U';
77.495 - if (peek == 'r' || peek == 'R') {
77.496 - int peek2 = input.read();
77.497 - if (peek2 == '\'' || peek2 == '"') {
77.498 - isStringPrefix = true;
77.499 - }
77.500 - input.backup(1);
77.501 - } else if (peek == '\'' || peek == '"') {
77.502 - isStringPrefix = true;
77.503 - input.backup(1);
77.504 - }
77.505 - if (!isStringPrefix) {
77.506 - input.backup(1);
77.507 - }
77.508 - }
77.509 - if (isStringPrefix) {
77.510 - ch = input.read();
77.511 - assert ch == '\'' || ch == '"';
77.512 -
77.513 - peek = input.read();
77.514 - if (peek != ch) {
77.515 - input.backup(1);
77.516 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
77.517 - return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
77.518 - }
77.519 - // We've seen two quotes... it's either an empty string,
77.520 - // or the beginning of a longstring
77.521 - int peek2 = input.read();
77.522 - if (peek2 == peek) {
77.523 - // It's a longstring!
77.524 - state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
77.525 - return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
77.526 - } else {
77.527 - input.backup(2);
77.528 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
77.529 - return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
77.530 - }
77.531 - }// else: FALLTHROUGH!!! The "u" or "r" is probably an identifier prefix!!
77.532 - }
77.533 - // Fallthrough...
77.534 -
77.535 - default: {
77.536 - // Identifier or keyword?
77.537 - if (Character.isJavaIdentifierStart(ch)) {
77.538 - while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
77.539 - ch = input.read();
77.540 - }
77.541 - input.backup(1);
77.542 -
77.543 - // See if it's a keyword
77.544 - PythonTokenId pid = getKeywordToken(input.readText());
77.545 - if (pid != null) {
77.546 - return createToken(pid, input.readLength());
77.547 - } else {
77.548 - return createToken(PythonTokenId.IDENTIFIER, input.readLength());
77.549 - }
77.550 - }
77.551 -
77.552 - assert input.readLength() == 1;
77.553 - return createToken(PythonTokenId.ANY_OPERATOR, 1);
77.554 - }
77.555 - }
77.556 - }
77.557 -
77.558 - case BEGIN_LONGSTRING_SINGLE:
77.559 - case BEGIN_LONGSTRING_DOUBLE: {
77.560 - // In a long string. Look for the end.
77.561 - int ch = input.read();
77.562 - if (ch == EOF) {
77.563 - return null;
77.564 - }
77.565 - int term = (state == State.BEGIN_LONGSTRING_DOUBLE) ? '"' : '\'';
77.566 - while (ch != EOF) {
77.567 - if (ch == '\\') {
77.568 - // It's an escape - read escaped char
77.569 - input.read();
77.570 - } else if (ch == term) {
77.571 - int peek = input.read();
77.572 - if (peek == term) {
77.573 - int peek2 = input.read();
77.574 - if (peek2 == term) {
77.575 - // Found the end
77.576 - if (input.readLength() == 3) {
77.577 - // Empty string - go straight to closed state
77.578 - state = State.INIT;
77.579 - return createToken(PythonTokenId.STRING_END, input.readLength());
77.580 - }
77.581 - input.backup(3);
77.582 - if (state == State.BEGIN_LONGSTRING_DOUBLE) {
77.583 - state = State.END_LONGSTRING_DOUBLE;
77.584 - } else {
77.585 - assert state == State.BEGIN_LONGSTRING_SINGLE;
77.586 - state = State.END_LONGSTRING_SINGLE;
77.587 - }
77.588 - return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
77.589 - }
77.590 - input.backup(1);
77.591 - }
77.592 - input.backup(1);
77.593 - }
77.594 - ch = input.read();
77.595 - }
77.596 - // Literal not terminated
77.597 - state = State.INIT;
77.598 - return createToken(PythonTokenId.ERROR, input.readLength());
77.599 - }
77.600 - case BEGIN_SHORTSTRING_SINGLE:
77.601 - case BEGIN_SHORTSTRING_DOUBLE: {
77.602 - // In a short string. Look for the end.
77.603 - int ch = input.read();
77.604 - if (ch == EOF) {
77.605 - return null;
77.606 - }
77.607 - int term = (state == State.BEGIN_SHORTSTRING_DOUBLE) ? '"' : '\'';
77.608 - while (ch != EOF) {
77.609 - if (ch == '\\') {
77.610 - // It's an escape - read escaped char
77.611 - input.read();
77.612 - } else if (ch == '\n') {
77.613 - // Literal not terminated
77.614 - state = State.INIT;
77.615 - return createToken(PythonTokenId.ERROR, input.readLength());
77.616 - } else if (ch == term) {
77.617 - if (input.readLength() == 1) {
77.618 - // It's an empty string! Skip straight to the end state
77.619 - state = State.INIT;
77.620 - return createToken(PythonTokenId.STRING_END, input.readLength());
77.621 - }
77.622 - input.backup(1);
77.623 - if (state == State.BEGIN_SHORTSTRING_DOUBLE) {
77.624 - state = State.END_SHORTSTRING_DOUBLE;
77.625 - } else {
77.626 - assert state == State.BEGIN_SHORTSTRING_SINGLE;
77.627 - state = State.END_SHORTSTRING_SINGLE;
77.628 - }
77.629 - return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
77.630 - }
77.631 - ch = input.read();
77.632 - }
77.633 - // Literal not terminated
77.634 - state = State.INIT;
77.635 - return createToken(PythonTokenId.ERROR, input.readLength());
77.636 - }
77.637 -
77.638 - case END_LONGSTRING_SINGLE:
77.639 - case END_LONGSTRING_DOUBLE: {
77.640 - // In a long string. Look for the end.
77.641 - int ch = input.read();
77.642 - if (ch == EOF) {
77.643 - return null;
77.644 - }
77.645 - int term = (state == State.END_LONGSTRING_DOUBLE) ? '"' : '\'';
77.646 - while (ch != EOF) {
77.647 - if (ch == term) {
77.648 - int peek = input.read();
77.649 - if (peek == term) {
77.650 - int peek2 = input.read();
77.651 - if (peek2 == term) {
77.652 - // Found the end
77.653 - state = State.INIT;
77.654 - return createToken(PythonTokenId.STRING_END, input.readLength());
77.655 - }
77.656 - input.backup(1);
77.657 - }
77.658 - input.backup(1);
77.659 - }
77.660 - ch = input.read();
77.661 - }
77.662 - // Literal not terminated
77.663 - state = State.INIT;
77.664 - return createToken(PythonTokenId.ERROR, input.readLength());
77.665 - }
77.666 - case END_SHORTSTRING_SINGLE:
77.667 - case END_SHORTSTRING_DOUBLE: {
77.668 - // In a short string. Look for the end.
77.669 - int ch = input.read();
77.670 - if (ch == EOF) {
77.671 - return null;
77.672 - }
77.673 - int term = (state == State.END_SHORTSTRING_DOUBLE) ? '"' : '\'';
77.674 - if (ch == term) {
77.675 - state = State.INIT;
77.676 - return createToken(PythonTokenId.STRING_END, input.readLength());
77.677 - }
77.678 - state = State.INIT;
77.679 - return createToken(PythonTokenId.ERROR, input.readLength());
77.680 - }
77.681 -
77.682 - default:
77.683 - assert false : state;
77.684 - }
77.685 -
77.686 - return null;
77.687 - }
77.688 -
77.689 - @Override
77.690 - public void release() {
77.691 - }
77.692 -
77.693 - private static PythonTokenId getKeywordToken(CharSequence s) {
77.694 - int length = s.length();
77.695 - if (length < 2) {
77.696 - return null;
77.697 - }
77.698 -
77.699 - if (BuiltinException.isBuiltInException(s)) {
77.700 - return PythonTokenId.ERROR;
77.701 - }
77.702 -
77.703 - char c1 = s.charAt(0);
77.704 - char c2 = s.charAt(1);
77.705 -
77.706 - switch (c1) {
77.707 - case 'a': // and, as, assert, async, await
77.708 - switch (c2) {
77.709 - case 'b': // abs
77.710 - if (length == 3 && TokenUtilities.textEquals(s, "abs")) { // NOI18N
77.711 - return PythonTokenId.BUILTIN_FUNCTION;
77.712 - }
77.713 - case 'l': // all
77.714 - if (length == 3 && TokenUtilities.textEquals(s, "all")) { // NOI18N
77.715 - return PythonTokenId.BUILTIN_FUNCTION;
77.716 - }
77.717 - case 'n': // and, any
77.718 - if (length == 3 && TokenUtilities.textEquals(s, "and")) { // NOI18N
77.719 - return PythonTokenId.ANY_KEYWORD;
77.720 - } else if (TokenUtilities.textEquals(s, "any")) { // NOI18N
77.721 - return PythonTokenId.BUILTIN_FUNCTION;
77.722 - }
77.723 - break;
77.724 - case 's': // as, ascii, assert, async
77.725 - if (length == 2) { // as
77.726 - return PythonTokenId.ANY_KEYWORD;
77.727 - }
77.728 - if (length == 5 && TokenUtilities.textEquals(s, "ascii")) { // NOI18N
77.729 - return PythonTokenId.BUILTIN_FUNCTION;
77.730 - }
77.731 - if (length == 6 && TokenUtilities.textEquals(s, "assert")) { // NOI18N
77.732 - return PythonTokenId.ANY_KEYWORD;
77.733 - }
77.734 - if (length == 5 && TokenUtilities.textEquals(s, "async")) { // NOI18N
77.735 - return PythonTokenId.ANY_KEYWORD;
77.736 - }
77.737 - break;
77.738 - case 'w': // await
77.739 - if (length == 5 && TokenUtilities.textEquals(s, "await")) { // NOI18N
77.740 - return PythonTokenId.ANY_KEYWORD;
77.741 - }
77.742 - }
77.743 - break;
77.744 - case 'b': // basestring, bin, bool, break, bytearray, bytes
77.745 - if (length == 10 && TokenUtilities.textEquals(s, "basestring")) { // NOI18N
77.746 - return PythonTokenId.BUILTIN_FUNCTION;
77.747 - }
77.748 - if (length == 3 && TokenUtilities.textEquals(s, "bin")) { // NOI18N
77.749 - return PythonTokenId.BUILTIN_FUNCTION;
77.750 - }
77.751 - if (length == 4 && TokenUtilities.textEquals(s, "bool")) { // NOI18N
77.752 - return PythonTokenId.BUILTIN_FUNCTION;
77.753 - }
77.754 - if (length == 5 && TokenUtilities.textEquals(s, "break")) { // NOI18N
77.755 - return PythonTokenId.ANY_KEYWORD;
77.756 - }
77.757 - if (length == 9 && TokenUtilities.textEquals(s, "bytearray")) { // NOI18N
77.758 - return PythonTokenId.BUILTIN_FUNCTION;
77.759 - }
77.760 - if (length == 5 && TokenUtilities.textEquals(s, "bytes")) { // NOI18N
77.761 - return PythonTokenId.BUILTIN_FUNCTION;
77.762 - }
77.763 - break;
77.764 - case 'c': // callable, chr, class, classmethod, continue
77.765 - switch (c2) {
77.766 - case 'a': // callable
77.767 - if (length == 8 && TokenUtilities.textEquals(s, "callable")) { // NOI18N
77.768 - return PythonTokenId.BUILTIN_FUNCTION;
77.769 - }
77.770 - break;
77.771 - case 'h': // chr
77.772 - if (length == 3 && TokenUtilities.textEquals(s, "chr")) { // NOI18N
77.773 - return PythonTokenId.BUILTIN_FUNCTION;
77.774 - }
77.775 - break;
77.776 - case 'l': // class, classmethod
77.777 - if (length == 5 && TokenUtilities.textEquals(s, "class")) { // NOI18N
77.778 - return PythonTokenId.CLASS;
77.779 - }
77.780 - if (length == 11 && TokenUtilities.textEquals(s, "classmethod")) { // NOI18N
77.781 - return PythonTokenId.BUILTIN_FUNCTION;
77.782 - }
77.783 - break;
77.784 - case 'm': // cmp
77.785 - if (length == 3 && TokenUtilities.textEquals(s, "cmp")) { // NOI18N
77.786 - return PythonTokenId.BUILTIN_FUNCTION;
77.787 - }
77.788 - break;
77.789 - case 'o': // compile, complex, continue
77.790 - if (length == 7 && TokenUtilities.textEquals(s, "compile")) { // NOI18N
77.791 - return PythonTokenId.BUILTIN_FUNCTION;
77.792 - }
77.793 - if (length == 7 && TokenUtilities.textEquals(s, "complex")) { // NOI18N
77.794 - return PythonTokenId.BUILTIN_FUNCTION;
77.795 - }
77.796 - if (length == 8 && TokenUtilities.textEquals(s, "continue")) { // NOI18N
77.797 - return PythonTokenId.ANY_KEYWORD;
77.798 - }
77.799 - break;
77.800 - }
77.801 - break;
77.802 - case 'd': // def, del
77.803 - switch (c2) {
77.804 - case 'e': // def, del, delattr
77.805 - if (length == 3 && TokenUtilities.textEquals(s, "def")) { // NOI18N
77.806 - return PythonTokenId.DEF;
77.807 - }
77.808 - if (length == 3 && TokenUtilities.textEquals(s, "del")) { // NOI18N
77.809 - return PythonTokenId.ANY_KEYWORD;
77.810 - }
77.811 - if (length == 7 && TokenUtilities.textEquals(s, "delattr")) { // NOI18N
77.812 - return PythonTokenId.BUILTIN_FUNCTION;
77.813 - }
77.814 - break;
77.815 - case 'i': // dict, dir, divmod
77.816 - if (length == 4 && TokenUtilities.textEquals(s, "dict")) { // NOI18N
77.817 - return PythonTokenId.BUILTIN_FUNCTION;
77.818 - }
77.819 - if (length == 3 && TokenUtilities.textEquals(s, "dir")) { // NOI18N
77.820 - return PythonTokenId.BUILTIN_FUNCTION;
77.821 - }
77.822 - if (length == 6 && TokenUtilities.textEquals(s, "divmod")) { // NOI18N
77.823 - return PythonTokenId.BUILTIN_FUNCTION;
77.824 - }
77.825 - break;
77.826 - }
77.827 - break;
77.828 - case 'e': // elif, else, enumerate, eval, except, exec, execfile
77.829 - switch (c2) {
77.830 - case 'l': // elif, else
77.831 - if (length == 4) {
77.832 - if (TokenUtilities.textEquals(s, "elif")) { // NOI18N
77.833 - return PythonTokenId.ELIF;
77.834 - }
77.835 - if (TokenUtilities.textEquals(s, "else")) { // NOI18N
77.836 - return PythonTokenId.ELSE;
77.837 - }
77.838 - }
77.839 - break;
77.840 - case 'n': // enumerate
77.841 - if (length == 9 && TokenUtilities.textEquals(s, "enumerate")) { // NOI18N
77.842 - return PythonTokenId.BUILTIN_FUNCTION;
77.843 - }
77.844 - break;
77.845 - case 'v': // eval
77.846 - if (length == 4 && TokenUtilities.textEquals(s, "eval")) { // NOI18N
77.847 - return PythonTokenId.BUILTIN_FUNCTION;
77.848 - }
77.849 - break;
77.850 - case 'x': // except, exec, execfile
77.851 - if (length == 4 && TokenUtilities.textEquals(s, "exec")) { // NOI18N
77.852 - return PythonTokenId.ANY_KEYWORD;
77.853 - }
77.854 - if (length == 8 && TokenUtilities.textEquals(s, "execfile")) { // NOI18N
77.855 - return PythonTokenId.BUILTIN_FUNCTION;
77.856 - }
77.857 - if (length == 6 && TokenUtilities.textEquals(s, "except")) { // NOI18N
77.858 - return PythonTokenId.EXCEPT;
77.859 - }
77.860 - break;
77.861 - }
77.862 - break;
77.863 - case 'f': // file, filter, finally, for, from
77.864 - switch (c2) {
77.865 - case 'i': // file, filter, finally
77.866 - if (length == 4 && TokenUtilities.textEquals(s, "file")) { // NOI18N
77.867 - return PythonTokenId.BUILTIN_FUNCTION;
77.868 - }
77.869 - if (length == 6 && TokenUtilities.textEquals(s, "filter")) { // NOI18N
77.870 - return PythonTokenId.BUILTIN_FUNCTION;
77.871 - }
77.872 - if (length == 7 && TokenUtilities.textEquals(s, "finally")) { // NOI18N
77.873 - return PythonTokenId.FINALLY;
77.874 - }
77.875 - break;
77.876 - case 'o': // for, format
77.877 - if (length == 3 && TokenUtilities.textEquals(s, "for")) { // NOI18N
77.878 - return PythonTokenId.ANY_KEYWORD;
77.879 - }
77.880 - if (length == 6 && TokenUtilities.textEquals(s, "format")) { // NOI18N
77.881 - return PythonTokenId.BUILTIN_FUNCTION;
77.882 - }
77.883 - break;
77.884 - case 'r': // from, frozenset
77.885 - if (length == 4 && TokenUtilities.textEquals(s, "from")) { // NOI18N
77.886 - return PythonTokenId.FROM;
77.887 - }
77.888 - if (length == 9 && TokenUtilities.textEquals(s, "frozenset")) { // NOI18N
77.889 - return PythonTokenId.BUILTIN_FUNCTION;
77.890 - }
77.891 - break;
77.892 - case 'l':
77.893 - if (length == 5 && TokenUtilities.textEquals(s, "float")) {
77.894 - return PythonTokenId.BUILTIN_FUNCTION;
77.895 - }
77.896 - break;
77.897 - }
77.898 - break;
77.899 - case 'g': // getattr, global, globals
77.900 - if (length == 7 && TokenUtilities.textEquals(s, "getattr")) { // NOI18N
77.901 - return PythonTokenId.BUILTIN_FUNCTION;
77.902 - }
77.903 - if (length == 6 && TokenUtilities.textEquals(s, "global")) { // NOI18N
77.904 - return PythonTokenId.ANY_KEYWORD;
77.905 - }
77.906 - if (length == 7 && TokenUtilities.textEquals(s, "globals")) { // NOI18N
77.907 - return PythonTokenId.BUILTIN_FUNCTION;
77.908 - }
77.909 - break;
77.910 - case 'h': // hasattr, hash, help, hex
77.911 - if (length == 7 && TokenUtilities.textEquals(s, "hasattr")) { // NOI18N
77.912 - return PythonTokenId.BUILTIN_FUNCTION;
77.913 - }
77.914 - if (length == 4 && TokenUtilities.textEquals(s, "hash")) { // NOI18N
77.915 - return PythonTokenId.BUILTIN_FUNCTION;
77.916 - }
77.917 - if (length == 4 && TokenUtilities.textEquals(s, "help")) { // NOI18N
77.918 - return PythonTokenId.BUILTIN_FUNCTION;
77.919 - }
77.920 - if (length == 3 && TokenUtilities.textEquals(s, "hex")) { // NOI18N
77.921 - return PythonTokenId.BUILTIN_FUNCTION;
77.922 - }
77.923 - break;
77.924 - case 'i': // id, if, import, in, input, int, is, issubclass, iter
77.925 - if (length == 2) {
77.926 - switch (c2) {
77.927 - case 'd': // id
77.928 - return PythonTokenId.BUILTIN_FUNCTION;
77.929 - case 'f': // if
77.930 - return PythonTokenId.IF;
77.931 - case 'n': // in
77.932 - if (length == 2 && TokenUtilities.textEquals(s, "in")) { //NOI18N
77.933 - return PythonTokenId.ANY_KEYWORD;
77.934 - }
77.935 - case 's': // is
77.936 - return PythonTokenId.ANY_KEYWORD;
77.937 - }
77.938 - } else if (c2 == 'm' && length == 6 && TokenUtilities.textEquals(s, "import")) { // NOI18N
77.939 - return PythonTokenId.IMPORT;
77.940 - } else if (length == 5 && TokenUtilities.textEquals(s, "input")) { // NOI18N
77.941 - return PythonTokenId.BUILTIN_FUNCTION;
77.942 - } else if (length == 3 && TokenUtilities.textEquals(s, "int")) { // NOI18N
77.943 - return PythonTokenId.BUILTIN_FUNCTION;
77.944 - } else if (length == 10 && TokenUtilities.textEquals(s, "isinstance")) { // NOI18N
77.945 - return PythonTokenId.BUILTIN_FUNCTION;
77.946 - } else if (length == 10 && TokenUtilities.textEquals(s, "issubclass")) { // NOI18N
77.947 - return PythonTokenId.BUILTIN_FUNCTION;
77.948 - } else if (length == 4 && TokenUtilities.textEquals(s, "iter")) { // NOI18N
77.949 - return PythonTokenId.BUILTIN_FUNCTION;
77.950 - }
77.951 - break;
77.952 - case 'l': // lambda, len, list, locals, long
77.953 - if (length == 6 && TokenUtilities.textEquals(s, "lambda")) { // NOI18N
77.954 - return PythonTokenId.ANY_KEYWORD;
77.955 - } else if (length == 3 && TokenUtilities.textEquals(s, "len")) { // NOI18N
77.956 - return PythonTokenId.BUILTIN_FUNCTION;
77.957 - } else if (length == 4 && TokenUtilities.textEquals(s, "list")) { // NOI18N
77.958 - return PythonTokenId.BUILTIN_FUNCTION;
77.959 - } else if (length == 6 && TokenUtilities.textEquals(s, "locals")) { // NOI18N
77.960 - return PythonTokenId.BUILTIN_FUNCTION;
77.961 - } else if (length == 4 && TokenUtilities.textEquals(s, "long")) { // NOI18N
77.962 - return PythonTokenId.BUILTIN_FUNCTION;
77.963 - }
77.964 - break;
77.965 - case 'm': // map, max, memoryview, min
77.966 - if (length == 3 && TokenUtilities.textEquals(s, "map")) { // NOI18N
77.967 - return PythonTokenId.BUILTIN_FUNCTION;
77.968 - }
77.969 - if (length == 3 && TokenUtilities.textEquals(s, "max")) { // NOI18N
77.970 - return PythonTokenId.BUILTIN_FUNCTION;
77.971 - }
77.972 - if (length == 10 && TokenUtilities.textEquals(s, "memoryview")) { // NOI18N
77.973 - return PythonTokenId.BUILTIN_FUNCTION;
77.974 - }
77.975 - if (length == 3 && TokenUtilities.textEquals(s, "min")) { // NOI18N
77.976 - return PythonTokenId.BUILTIN_FUNCTION;
77.977 - }
77.978 - break;
77.979 - case 'n': // next, nonlocal, not
77.980 - if (length == 4 && TokenUtilities.textEquals(s, "next")) { // NOI18N
77.981 - return PythonTokenId.BUILTIN_FUNCTION;
77.982 - }
77.983 - if (length == 8 && TokenUtilities.textEquals(s, "nonlocal")) { // NOI18N
77.984 - return PythonTokenId.ANY_KEYWORD;
77.985 - }
77.986 - if (length == 3 && TokenUtilities.textEquals(s, "not")) { // NOI18N
77.987 - return PythonTokenId.ANY_KEYWORD;
77.988 - }
77.989 - break;
77.990 - case 'o': // or, object, oct, open, ord
77.991 - if (length == 2 && TokenUtilities.textEquals(s, "or")) { // NOI18N
77.992 - return PythonTokenId.ANY_KEYWORD;
77.993 - }
77.994 - if (length == 6 && TokenUtilities.textEquals(s, "object")) { // NOI18N
77.995 - return PythonTokenId.BUILTIN_FUNCTION;
77.996 - }
77.997 - if (length == 3 && TokenUtilities.textEquals(s, "oct")) { // NOI18N
77.998 - return PythonTokenId.BUILTIN_FUNCTION;
77.999 - }
77.1000 - if (length == 4 && TokenUtilities.textEquals(s, "open")) { // NOI18N
77.1001 - return PythonTokenId.BUILTIN_FUNCTION;
77.1002 - }
77.1003 - if (length == 3 && TokenUtilities.textEquals(s, "ord")) { // NOI18N
77.1004 - return PythonTokenId.BUILTIN_FUNCTION;
77.1005 - }
77.1006 - break;
77.1007 - case 'p': // pass, pow, print, property
77.1008 - if (c2 == 'a') { // pass
77.1009 - if (length == 4 && TokenUtilities.textEquals(s, "pass")) { // NOI18N
77.1010 - return PythonTokenId.PASS;
77.1011 - }
77.1012 - }
77.1013 - if (length == 3 && TokenUtilities.textEquals(s, "pow")) { // NOI18N
77.1014 - return PythonTokenId.BUILTIN_FUNCTION;
77.1015 - }
77.1016 - if (c2 == 'r') { // print, property
77.1017 - if (length == 5 && TokenUtilities.textEquals(s, "print")) { // NOI18N
77.1018 - return PythonTokenId.ANY_KEYWORD;
77.1019 - }
77.1020 - if (length == 8 && TokenUtilities.textEquals(s, "property")) { // NOI18N
77.1021 - return PythonTokenId.BUILTIN_FUNCTION;
77.1022 - }
77.1023 - }
77.1024 - break;
77.1025 - case 'r': // raise, range, raise, raw_input, reduce, reload, repr, return, reversed, round
77.1026 - if (c2 == 'a') { // raise, range
77.1027 - if (length == 5 && TokenUtilities.textEquals(s, "range")) { // NOI18N
77.1028 - return PythonTokenId.BUILTIN_FUNCTION;
77.1029 - }
77.1030 - if (length == 5 && TokenUtilities.textEquals(s, "raise")) { // NOI18N
77.1031 - return PythonTokenId.RAISE;
77.1032 - }
77.1033 - if (length == 9 && TokenUtilities.textEquals(s, "raw_input")) { // NOI18N
77.1034 - return PythonTokenId.BUILTIN_FUNCTION;
77.1035 - }
77.1036 - } else if (c2 == 'e') { // reduce, reload, repr, return, reversed
77.1037 - if (length == 6 && TokenUtilities.textEquals(s, "reduce")) { // NOI18N
77.1038 - return PythonTokenId.BUILTIN_FUNCTION;
77.1039 - }
77.1040 - if (length == 6 && TokenUtilities.textEquals(s, "reload")) { // NOI18N
77.1041 - return PythonTokenId.BUILTIN_FUNCTION;
77.1042 - }
77.1043 - if (length == 4 && TokenUtilities.textEquals(s, "repr")) { // NOI18N
77.1044 - return PythonTokenId.BUILTIN_FUNCTION;
77.1045 - }
77.1046 - if (length == 6 && TokenUtilities.textEquals(s, "return")) { // NOI18N
77.1047 - return PythonTokenId.RETURN;
77.1048 - }
77.1049 - if (length == 8 && TokenUtilities.textEquals(s, "reversed")) { // NOI18N
77.1050 - return PythonTokenId.BUILTIN_FUNCTION;
77.1051 - }
77.1052 - } else if (length == 5 && TokenUtilities.textEquals(s, "round")) { // NOI18N
77.1053 - return PythonTokenId.BUILTIN_FUNCTION;
77.1054 - }
77.1055 - break;
77.1056 - case 's': // self, set, setattr, slice, sorted, staticmethod, str, sum, super
77.1057 - if (length == 4 && TokenUtilities.textEquals(s, "self")) { // NOI18N
77.1058 - return PythonTokenId.ANY_KEYWORD;
77.1059 - }
77.1060 - if (length == 3 && TokenUtilities.textEquals(s, "set")) { // NOI18N
77.1061 - return PythonTokenId.BUILTIN_FUNCTION;
77.1062 - }
77.1063 - if (length == 7 && TokenUtilities.textEquals(s, "setattr")) { // NOI18N
77.1064 - return PythonTokenId.BUILTIN_FUNCTION;
77.1065 - }
77.1066 - if (length == 5 && TokenUtilities.textEquals(s, "slice")) { // NOI18N
77.1067 - return PythonTokenId.BUILTIN_FUNCTION;
77.1068 - }
77.1069 - if (length == 6 && TokenUtilities.textEquals(s, "sorted")) { // NOI18N
77.1070 - return PythonTokenId.BUILTIN_FUNCTION;
77.1071 - }
77.1072 - if (length == 12 && TokenUtilities.textEquals(s, "staticmethod")) { // NOI18N
77.1073 - return PythonTokenId.BUILTIN_FUNCTION;
77.1074 - }
77.1075 - if (length == 3 && TokenUtilities.textEquals(s, "str")) { // NOI18N
77.1076 - return PythonTokenId.BUILTIN_FUNCTION;
77.1077 - }
77.1078 - if (length == 3 && TokenUtilities.textEquals(s, "sum")) { // NOI18N
77.1079 - return PythonTokenId.BUILTIN_FUNCTION;
77.1080 - }
77.1081 - if (length == 5 && TokenUtilities.textEquals(s, "super")) { // NOI18N
77.1082 - return PythonTokenId.BUILTIN_FUNCTION;
77.1083 - }
77.1084 - break;
77.1085 - case 't': // try, tuple, type
77.1086 - if (length == 3 && TokenUtilities.textEquals(s, "try")) { // NOI18N
77.1087 - return PythonTokenId.TRY;
77.1088 - } else if (length == 5 && TokenUtilities.textEquals(s, "tuple")) { // NOI18N
77.1089 - return PythonTokenId.BUILTIN_FUNCTION;
77.1090 - } else if (length == 4 && TokenUtilities.textEquals(s, "type")) { // NOI18N
77.1091 - return PythonTokenId.BUILTIN_FUNCTION;
77.1092 - }
77.1093 - break;
77.1094 - case 'u': // unichr, unicode
77.1095 - if (length == 6 && TokenUtilities.textEquals(s, "unichr")) { // NOI18N
77.1096 - return PythonTokenId.BUILTIN_FUNCTION;
77.1097 - }
77.1098 - if (length == 7 && TokenUtilities.textEquals(s, "unicode")) { // NOI18N
77.1099 - return PythonTokenId.BUILTIN_FUNCTION;
77.1100 - }
77.1101 - break;
77.1102 - case 'v': // vars
77.1103 - if (length == 4 && TokenUtilities.textEquals(s, "vars")) { // NOI18N
77.1104 - return PythonTokenId.BUILTIN_FUNCTION;
77.1105 - }
77.1106 - break;
77.1107 - case 'w': // while,with
77.1108 - if (c2 == 'h') { // while
77.1109 - if (length == 5 && TokenUtilities.textEquals(s, "while")) { // NOI18N
77.1110 - return PythonTokenId.ANY_KEYWORD;
77.1111 - }
77.1112 - } else if (c2 == 'i') { // with
77.1113 - if (length == 4 && TokenUtilities.textEquals(s, "with")) { // NOI18N
77.1114 - return PythonTokenId.ANY_KEYWORD;
77.1115 - }
77.1116 - }
77.1117 - break;
77.1118 - case 'x': // xrange
77.1119 - if (length == 6 && TokenUtilities.textEquals(s, "xrange")) { // NOI18N
77.1120 - return PythonTokenId.BUILTIN_FUNCTION;
77.1121 - }
77.1122 - break;
77.1123 - case 'y': // yield
77.1124 - if (length == 5 && TokenUtilities.textEquals(s, "yield")) { // NOI18N
77.1125 - return PythonTokenId.ANY_KEYWORD;
77.1126 - }
77.1127 - break;
77.1128 - case 'z': // zip
77.1129 - if (length == 3 && TokenUtilities.textEquals(s, "zip")) { // NOI18N
77.1130 - return PythonTokenId.BUILTIN_FUNCTION;
77.1131 - }
77.1132 - break;
77.1133 - case 'F': // False
77.1134 - if (length == 5 && TokenUtilities.textEquals(s, "False")) { // NOI18N
77.1135 - return PythonTokenId.FALSE;
77.1136 - }
77.1137 - break;
77.1138 - case 'N': // None
77.1139 - if (length == 4 && TokenUtilities.textEquals(s, "None")) { // NOI18N
77.1140 - return PythonTokenId.NONE;
77.1141 - }
77.1142 - break;
77.1143 - case 'T': // True
77.1144 - if (length == 4 && TokenUtilities.textEquals(s, "True")) { // NOI18N
77.1145 - return PythonTokenId.TRUE;
77.1146 - }
77.1147 - break;
77.1148 - case '_': // Special symbols of python
77.1149 - if (length > 4 && TokenUtilities.startsWith(s, "__") && TokenUtilities.endsWith(s, "__")) { // NOI18N
77.1150 - return PythonTokenId.BUILTIN_FUNCTION;
77.1151 - }
77.1152 - break;
77.1153 - }
77.1154 -
77.1155 - return null;
77.1156 - }
77.1157 -
77.1158 - public static boolean isKeywordOrBuiltin(CharSequence name) {
77.1159 - return getKeywordToken(name) != null;
77.1160 - }
77.1161 -}
78.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonLexerUtils.java Fri Sep 18 16:20:24 2015 -0500
78.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
78.3 @@ -1,562 +0,0 @@
78.4 -/*
78.5 - * To change this template, choose Tools | Templates
78.6 - * and open the template in the editor.
78.7 - */
78.8 -package org.netbeans.modules.python.editor.lexer;
78.9 -
78.10 -import java.util.Arrays;
78.11 -import java.util.List;
78.12 -import java.util.regex.Matcher;
78.13 -import java.util.regex.Pattern;
78.14 -import javax.swing.text.BadLocationException;
78.15 -import javax.swing.text.Document;
78.16 -import org.netbeans.api.lexer.Token;
78.17 -import org.netbeans.api.lexer.TokenHierarchy;
78.18 -import org.netbeans.api.lexer.TokenId;
78.19 -import org.netbeans.api.lexer.TokenSequence;
78.20 -import org.netbeans.editor.BaseDocument;
78.21 -import org.netbeans.editor.Utilities;
78.22 -import org.netbeans.modules.csl.api.OffsetRange;
78.23 -import org.netbeans.modules.python.editor.PythonParserResult;
78.24 -import org.openide.filesystems.FileUtil;
78.25 -import org.openide.loaders.DataObject;
78.26 -import org.openide.util.Exceptions;
78.27 -import org.python.antlr.PythonTree;
78.28 -
78.29 -/**
78.30 - * Utility functions around the Python lexer
78.31 - *
78.32 - * @author Tor Norbye
78.33 - */
78.34 -public class PythonLexerUtils {
78.35 - /**
78.36 - * Try to produce a more accurate location for the given name in the given import statement, located
78.37 - * at the lexRange provided
78.38 - */
78.39 - public static OffsetRange getImportNameOffset(BaseDocument doc, OffsetRange lexRange, PythonTree node, String name) {
78.40 - int docLength = doc.getLength();
78.41 - int start = Math.min(docLength, lexRange.getStart());
78.42 - int end = Math.min(docLength, lexRange.getEnd());
78.43 - try {
78.44 - String s = doc.getText(start, end - start);
78.45 -
78.46 - Pattern p = Pattern.compile(".*import\\s+\\b(" + name + ")\\b.*");
78.47 - Matcher m = p.matcher(s);
78.48 - if (m.matches()) {
78.49 - int offset = start + m.start(1);
78.50 - return new OffsetRange(offset, offset + name.length());
78.51 - }
78.52 -
78.53 - // Lame
78.54 - int searchIndex = s.indexOf("import ");
78.55 - if (searchIndex == -1) {
78.56 - searchIndex = 0;
78.57 - } else {
78.58 - searchIndex += 7;
78.59 - }
78.60 - int match = s.indexOf(name, searchIndex + 7);
78.61 - if (match != -1) {
78.62 - int offset = start + match;
78.63 - return new OffsetRange(offset, offset + name.length());
78.64 - }
78.65 -
78.66 - // Give up - use the whole range
78.67 - } catch (BadLocationException ex) {
78.68 - Exceptions.printStackTrace(ex);
78.69 - }
78.70 -
78.71 - return lexRange;
78.72 - }
78.73 -
78.74 - /** For a possibly generated offset in an AST, return the corresponding lexing/true document offset */
78.75 - public static int getLexerOffset(PythonParserResult result, int astOffset) {
78.76 - return result.getSnapshot().getOriginalOffset(astOffset);
78.77 - }
78.78 -
78.79 - public static OffsetRange getLexerOffsets(PythonParserResult result, OffsetRange astRange) {
78.80 - if (result != null) {
78.81 - int rangeStart = astRange.getStart();
78.82 - int start = result.getSnapshot().getOriginalOffset(rangeStart);
78.83 - if (start == rangeStart) {
78.84 - return astRange;
78.85 - } else if (start == -1) {
78.86 - return OffsetRange.NONE;
78.87 - } else {
78.88 - // Assumes the translated range maintains size
78.89 - return new OffsetRange(start, start + astRange.getLength());
78.90 - }
78.91 - }
78.92 -
78.93 - return astRange;
78.94 - }
78.95 -
78.96 - /**
78.97 - * Narrow a given lexical offset range to the closest AST-relevant offsets.
78.98 - * This means it will pass over things like comments and whitespace.
78.99 - * @param doc The document containing the range
78.100 - * @param range The start/end lexical range we want to narrow
78.101 - * @return An OffsetRange where the offsets begin and end at AST-relevant tokens
78.102 - */
78.103 - public static OffsetRange narrow(BaseDocument doc, OffsetRange range, boolean skipComments) {
78.104 - try {
78.105 - doc.readLock(); // For token hiearchy use
78.106 - // For token hiearchy use
78.107 - int start = range.getStart();
78.108 - TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, start);
78.109 - if (ts != null) {
78.110 - int delta = ts.move(start);
78.111 - while (ts.moveNext()) {
78.112 - Token<? extends PythonTokenId> token = ts.token();
78.113 - PythonTokenId id = token.id();
78.114 - if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
78.115 - if (delta != 0) {
78.116 - return OffsetRange.NONE;
78.117 - }
78.118 - start = ts.offset();
78.119 - break;
78.120 - } else {
78.121 - delta = 0;
78.122 - }
78.123 - }
78.124 - }
78.125 - int end = range.getEnd();
78.126 - ts = getPositionedSequence(doc, end);
78.127 - if (ts != null) {
78.128 - int delta = ts.move(end);
78.129 - while (delta > 0 ? ts.moveNext() : ts.movePrevious()) {
78.130 - Token<? extends PythonTokenId> token = ts.token();
78.131 - PythonTokenId id = token.id();
78.132 - if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
78.133 - if (delta != 0) {
78.134 - return OffsetRange.NONE;
78.135 - }
78.136 - end = ts.offset() + token.length();
78.137 - break;
78.138 - } else {
78.139 - delta = 0;
78.140 - }
78.141 - }
78.142 - }
78.143 -
78.144 - if (end < start) {
78.145 - return OffsetRange.NONE;
78.146 - }
78.147 -
78.148 - return new OffsetRange(start, end);
78.149 - } finally {
78.150 - doc.readUnlock();
78.151 - }
78.152 - }
78.153 -
78.154 - /** Find the ruby token sequence (in case it's embedded in something else at the top level */
78.155 - @SuppressWarnings("unchecked")
78.156 - public static TokenSequence<? extends PythonTokenId> getPythonSequence(BaseDocument doc, int offset) {
78.157 - TokenHierarchy<Document> th = TokenHierarchy.get((Document)doc);
78.158 - return getPythonSequence(th, offset);
78.159 - }
78.160 -
78.161 - @SuppressWarnings("unchecked")
78.162 - public static TokenSequence<? extends PythonTokenId> getPythonSequence(TokenHierarchy<Document> th, int offset) {
78.163 - TokenSequence<? extends PythonTokenId> ts = th.tokenSequence(PythonTokenId.language());
78.164 -
78.165 - if (ts == null) {
78.166 - // Possibly an embedding scenario such as an RHTML file
78.167 - // First try with backward bias true
78.168 - List<TokenSequence<?>> list = th.embeddedTokenSequences(offset, true);
78.169 -
78.170 - for (TokenSequence t : list) {
78.171 - if (t.language() == PythonTokenId.language()) {
78.172 - ts = t;
78.173 -
78.174 - break;
78.175 - }
78.176 - }
78.177 -
78.178 - if (ts == null) {
78.179 - list = th.embeddedTokenSequences(offset, false);
78.180 -
78.181 - for (TokenSequence t : list) {
78.182 - if (t.language() == PythonTokenId.language()) {
78.183 - ts = t;
78.184 -
78.185 - break;
78.186 - }
78.187 - }
78.188 - }
78.189 - }
78.190 -
78.191 - return ts;
78.192 - }
78.193 -
78.194 - public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset) {
78.195 - return getPositionedSequence(doc, offset, true);
78.196 - }
78.197 -
78.198 - public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset, boolean lookBack) {
78.199 - TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, offset);
78.200 -
78.201 - if (ts != null) {
78.202 - try {
78.203 - ts.move(offset);
78.204 - } catch (AssertionError e) {
78.205 - DataObject dobj = (DataObject)doc.getProperty(Document.StreamDescriptionProperty);
78.206 -
78.207 - if (dobj != null) {
78.208 - Exceptions.attachMessage(e, FileUtil.getFileDisplayName(dobj.getPrimaryFile()));
78.209 - }
78.210 -
78.211 - throw e;
78.212 - }
78.213 -
78.214 - if (!lookBack && !ts.moveNext()) {
78.215 - return null;
78.216 - } else if (lookBack && !ts.moveNext() && !ts.movePrevious()) {
78.217 - return null;
78.218 - }
78.219 -
78.220 - /* TODO - allow Python inside strings
78.221 - if (ts.token().id() == PythonTokenId.STRING_LITERAL) {
78.222 - TokenSequence<? extends PythonStringTokenId> ets = ts.embedded(PythonStringTokenId.language());
78.223 - if (ets != null) {
78.224 - ets.move(offset);
78.225 - if ((!lookBack && ets.moveNext()) || (lookBack && ets.movePrevious())) {
78.226 - TokenSequence<?extends PythonTokenId> epts = ets.embedded(PythonTokenId.language());
78.227 - if (epts != null) {
78.228 - epts.move(offset);
78.229 - if (!lookBack && !epts.moveNext()) {
78.230 - return null;
78.231 - } else if (lookBack && !epts.moveNext() && !epts.movePrevious()) {
78.232 - return null;
78.233 - }
78.234 - return epts;
78.235 - }
78.236 - }
78.237 - }
78.238 - }
78.239 - */
78.240 -
78.241 - return ts;
78.242 - }
78.243 -
78.244 - return null;
78.245 - }
78.246 -
78.247 - public static Token<? extends PythonTokenId> getToken(BaseDocument doc, int offset) {
78.248 - TokenSequence<? extends PythonTokenId> ts = getPositionedSequence(doc, offset);
78.249 -
78.250 - if (ts != null) {
78.251 - return ts.token();
78.252 - }
78.253 -
78.254 - return null;
78.255 - }
78.256 -
78.257 - public static char getTokenChar(BaseDocument doc, int offset) {
78.258 - Token<? extends PythonTokenId> token = getToken(doc, offset);
78.259 -
78.260 - if (token != null) {
78.261 - String text = token.text().toString();
78.262 -
78.263 - if (text.length() > 0) { // Usually true, but I could have gotten EOF right?
78.264 -
78.265 - return text.charAt(0);
78.266 - }
78.267 - }
78.268 -
78.269 - return 0;
78.270 - }
78.271 -
78.272 - public static Token<? extends PythonTokenId> findNextNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
78.273 - return findNext(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
78.274 - }
78.275 -
78.276 - public static Token<? extends PythonTokenId> findPreviousNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
78.277 - return findPrevious(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
78.278 - }
78.279 -
78.280 - public static Token<? extends PythonTokenId> findNext(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
78.281 - if (ignores.contains(ts.token().id())) {
78.282 - while (ts.moveNext() && ignores.contains(ts.token().id())) {
78.283 - }
78.284 - }
78.285 - return ts.token();
78.286 - }
78.287 -
78.288 - public static Token<? extends PythonTokenId> findNextIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
78.289 - while (ts.moveNext() && !includes.contains(ts.token().id())) {
78.290 - }
78.291 - return ts.token();
78.292 - }
78.293 -
78.294 - public static Token<? extends PythonTokenId> findPreviousIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
78.295 - while (ts.movePrevious() && !includes.contains(ts.token().id())) {
78.296 - }
78.297 - return ts.token();
78.298 - }
78.299 -
78.300 - public static Token<? extends PythonTokenId> findPrevious(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
78.301 - if (ignores.contains(ts.token().id())) {
78.302 - while (ts.movePrevious() && ignores.contains(ts.token().id())) {
78.303 - }
78.304 - }
78.305 - return ts.token();
78.306 - }
78.307 -
78.308 - static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts) {
78.309 - return skipParenthesis(ts, false);
78.310 - }
78.311 -
78.312 - /**
78.313 - * Tries to skip parenthesis
78.314 - */
78.315 - public static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts, boolean back) {
78.316 - int balance = 0;
78.317 -
78.318 - Token<? extends PythonTokenId> token = ts.token();
78.319 - if (token == null) {
78.320 - return false;
78.321 - }
78.322 -
78.323 - TokenId id = token.id();
78.324 -
78.325 - if (id == PythonTokenId.WHITESPACE || id == PythonTokenId.NEWLINE) {
78.326 - while ((back ? ts.movePrevious() : ts.moveNext()) && (ts.token().id() == PythonTokenId.WHITESPACE || ts.token().id() == PythonTokenId.NEWLINE)) {
78.327 - }
78.328 - }
78.329 -
78.330 - // if current token is not left parenthesis
78.331 - if (ts.token().id() != (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
78.332 - return false;
78.333 - }
78.334 -
78.335 - do {
78.336 - token = ts.token();
78.337 - id = token.id();
78.338 -
78.339 - if (id == (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
78.340 - balance++;
78.341 - } else if (id == (back ? PythonTokenId.LPAREN : PythonTokenId.RPAREN)) {
78.342 - if (balance == 0) {
78.343 - return false;
78.344 - } else if (balance == 1) {
78.345 - //int length = ts.offset() + token.length();
78.346 - if (back) {
78.347 - ts.movePrevious();
78.348 - } else {
78.349 - ts.moveNext();
78.350 - }
78.351 - return true;
78.352 - }
78.353 -
78.354 - balance--;
78.355 - }
78.356 - } while (back ? ts.movePrevious() : ts.moveNext());
78.357 -
78.358 - return false;
78.359 - }
78.360 -
78.361 - /** Search forwards in the token sequence until a token of type <code>down</code> is found */
78.362 - public static OffsetRange findFwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
78.363 - TokenId down) {
78.364 - int balance = 0;
78.365 -
78.366 - while (ts.moveNext()) {
78.367 - Token<? extends PythonTokenId> token = ts.token();
78.368 - TokenId id = token.id();
78.369 -
78.370 - if (id == up) {
78.371 - balance++;
78.372 - } else if (id == down) {
78.373 - if (balance == 0) {
78.374 - return new OffsetRange(ts.offset(), ts.offset() + token.length());
78.375 - }
78.376 -
78.377 - balance--;
78.378 - }
78.379 - }
78.380 -
78.381 - return OffsetRange.NONE;
78.382 - }
78.383 -
78.384 - /** Search backwards in the token sequence until a token of type <code>up</code> is found */
78.385 - public static OffsetRange findBwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
78.386 - TokenId down) {
78.387 - int balance = 0;
78.388 -
78.389 - while (ts.movePrevious()) {
78.390 - Token<? extends PythonTokenId> token = ts.token();
78.391 - TokenId id = token.id();
78.392 -
78.393 - if (id == up) {
78.394 - if (balance == 0) {
78.395 - return new OffsetRange(ts.offset(), ts.offset() + token.length());
78.396 - }
78.397 -
78.398 - balance++;
78.399 - } else if (id == down) {
78.400 - balance--;
78.401 - }
78.402 - }
78.403 -
78.404 - return OffsetRange.NONE;
78.405 - }
78.406 -
78.407 - /** Compute the balance of begin/end tokens on the line */
78.408 - public static int getLineBalance(BaseDocument doc, int offset, TokenId up, TokenId down) {
78.409 - try {
78.410 - int begin = Utilities.getRowStart(doc, offset);
78.411 - int end = Utilities.getRowEnd(doc, offset);
78.412 -
78.413 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, begin);
78.414 - if (ts == null) {
78.415 - return 0;
78.416 - }
78.417 -
78.418 - ts.move(begin);
78.419 -
78.420 - if (!ts.moveNext()) {
78.421 - return 0;
78.422 - }
78.423 -
78.424 - int balance = 0;
78.425 -
78.426 - do {
78.427 - Token<? extends PythonTokenId> token = ts.token();
78.428 - TokenId id = token.id();
78.429 -
78.430 - if (id == up) {
78.431 - balance++;
78.432 - } else if (id == down) {
78.433 - balance--;
78.434 - }
78.435 - } while (ts.moveNext() && (ts.offset() <= end));
78.436 -
78.437 - return balance;
78.438 - } catch (BadLocationException ble) {
78.439 - Exceptions.printStackTrace(ble);
78.440 -
78.441 - return 0;
78.442 - }
78.443 - }
78.444 -
78.445 - /**
78.446 - * The same as braceBalance but generalized to any pair of matching
78.447 - * tokens.
78.448 - * @param open the token that increses the count
78.449 - * @param close the token that decreses the count
78.450 - */
78.451 - public static int getTokenBalance(BaseDocument doc, TokenId open, TokenId close, int offset)
78.452 - throws BadLocationException {
78.453 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, 0);
78.454 - if (ts == null) {
78.455 - return 0;
78.456 - }
78.457 -
78.458 - // XXX Why 0? Why not offset?
78.459 - ts.moveIndex(0);
78.460 -
78.461 - if (!ts.moveNext()) {
78.462 - return 0;
78.463 - }
78.464 -
78.465 - int balance = 0;
78.466 -
78.467 - do {
78.468 - Token t = ts.token();
78.469 -
78.470 - if (t.id() == open) {
78.471 - balance++;
78.472 - } else if (t.id() == close) {
78.473 - balance--;
78.474 - }
78.475 - } while (ts.moveNext());
78.476 -
78.477 - return balance;
78.478 - }
78.479 -
78.480 - /**
78.481 - * Return true iff the line for the given offset is a JavaScript comment line.
78.482 - * This will return false for lines that contain comments (even when the
78.483 - * offset is within the comment portion) but also contain code.
78.484 - */
78.485 - public static boolean isCommentOnlyLine(BaseDocument doc, int offset)
78.486 - throws BadLocationException {
78.487 - int begin = Utilities.getRowFirstNonWhite(doc, offset);
78.488 -
78.489 - if (begin == -1) {
78.490 - return false; // whitespace only
78.491 - }
78.492 -
78.493 - Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, begin);
78.494 - if (token != null) {
78.495 - return token.id() == PythonTokenId.COMMENT;
78.496 - }
78.497 -
78.498 - return false;
78.499 - }
78.500 -
78.501 - /**
78.502 - * Back up to the first space character prior to the given offset - as long as
78.503 - * it's on the same line! If there's only leading whitespace on the line up
78.504 - * to the lex offset, return the offset itself
78.505 - * @todo Rewrite this now that I have a separate newline token, EOL, that I can
78.506 - * break on - no need to call Utilities.getRowStart.
78.507 - */
78.508 - public static int findSpaceBegin(BaseDocument doc, int lexOffset) {
78.509 - TokenSequence ts = getPythonSequence(doc, lexOffset);
78.510 - if (ts == null) {
78.511 - return lexOffset;
78.512 - }
78.513 - boolean allowPrevLine = false;
78.514 - int lineStart;
78.515 - try {
78.516 - lineStart = Utilities.getRowStart(doc, Math.min(lexOffset, doc.getLength()));
78.517 - int prevLast = lineStart - 1;
78.518 - if (lineStart > 0) {
78.519 - prevLast = Utilities.getRowLastNonWhite(doc, lineStart - 1);
78.520 - if (prevLast != -1) {
78.521 - char c = doc.getText(prevLast, 1).charAt(0);
78.522 - if (c == ',') {
78.523 - // Arglist continuation? // TODO : check lexing
78.524 - allowPrevLine = true;
78.525 - }
78.526 - }
78.527 - }
78.528 - if (!allowPrevLine) {
78.529 - int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
78.530 - if (lexOffset <= firstNonWhite || firstNonWhite == -1) {
78.531 - return lexOffset;
78.532 - }
78.533 - } else {
78.534 - // Make lineStart so small that Math.max won't cause any problems
78.535 - int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
78.536 - if (prevLast >= 0 && (lexOffset <= firstNonWhite || firstNonWhite == -1)) {
78.537 - return prevLast + 1;
78.538 - }
78.539 - lineStart = 0;
78.540 - }
78.541 - } catch (BadLocationException ble) {
78.542 - Exceptions.printStackTrace(ble);
78.543 - return lexOffset;
78.544 - }
78.545 - ts.move(lexOffset);
78.546 - if (ts.moveNext()) {
78.547 - if (lexOffset > ts.offset()) {
78.548 - // We're in the middle of a token
78.549 - return Math.max((ts.token().id() == PythonTokenId.WHITESPACE) ? ts.offset() : lexOffset, lineStart);
78.550 - }
78.551 - while (ts.movePrevious()) {
78.552 - Token token = ts.token();
78.553 - if (token.id() != PythonTokenId.WHITESPACE) {
78.554 - return Math.max(ts.offset() + token.length(), lineStart);
78.555 - }
78.556 - }
78.557 - }
78.558 -
78.559 - return lexOffset;
78.560 - }
78.561 -
78.562 - public static boolean isKeywordOrBuiltin(CharSequence name) {
78.563 - return PythonLexer.isKeywordOrBuiltin(name);
78.564 - }
78.565 -}
79.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonStringLexer.java Fri Sep 18 16:20:24 2015 -0500
79.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
79.3 @@ -1,292 +0,0 @@
79.4 -/*
79.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
79.6 - *
79.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
79.8 - *
79.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
79.10 - * Other names may be trademarks of their respective owners.
79.11 - *
79.12 - * The contents of this file are subject to the terms of either the GNU
79.13 - * General Public License Version 2 only ("GPL") or the Common
79.14 - * Development and Distribution License("CDDL") (collectively, the
79.15 - * "License"). You may not use this file except in compliance with the
79.16 - * License. You can obtain a copy of the License at
79.17 - * http://www.netbeans.org/cddl-gplv2.html
79.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
79.19 - * specific language governing permissions and limitations under the
79.20 - * License. When distributing the software, include this License Header
79.21 - * Notice in each file and include the License file at
79.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
79.23 - * particular file as subject to the "Classpath" exception as provided
79.24 - * by Oracle in the GPL Version 2 section of the License file that
79.25 - * accompanied this code. If applicable, add the following below the
79.26 - * License Header, with the fields enclosed by brackets [] replaced by
79.27 - * your own identifying information:
79.28 - * "Portions Copyrighted [year] [name of copyright owner]"
79.29 - *
79.30 - * Contributor(s):
79.31 - *
79.32 - * The Original Software is NetBeans. The Initial Developer of the Original
79.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
79.34 - * Microsystems, Inc. All Rights Reserved.
79.35 - *
79.36 - * If you wish your version of this file to be governed by only the CDDL
79.37 - * or only the GPL Version 2, indicate your decision by adding
79.38 - * "[Contributor] elects to include this software in this distribution
79.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
79.40 - * single choice of license, a recipient has the option to distribute
79.41 - * your version of this file under either the CDDL, the GPL Version 2 or
79.42 - * to extend the choice of license to its licensees as provided above.
79.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
79.44 - * Version 2 license, then the option applies only if the new code is
79.45 - * made subject to such option by the copyright holder.
79.46 - */
79.47 -package org.netbeans.modules.python.editor.lexer;
79.48 -
79.49 -import org.netbeans.api.lexer.Token;
79.50 -import org.netbeans.spi.lexer.Lexer;
79.51 -import org.netbeans.spi.lexer.LexerInput;
79.52 -import org.netbeans.spi.lexer.LexerRestartInfo;
79.53 -import org.netbeans.spi.lexer.TokenFactory;
79.54 -
79.55 -/**
79.56 - * A lexer for python strings. Highlights escape sequences, and recognizes
79.57 - * doctest sections and highlights these as well.
79.58 - * http://docs.python.org/lib/module-doctest.html
79.59 - *
79.60 - * @todo Track whether strings are raw or not, and don't do escape sequence
79.61 - * highlighting in raw strings
79.62 - *
79.63 - * @author Tor Norbye
79.64 - */
79.65 -public class PythonStringLexer implements Lexer<PythonStringTokenId> {
79.66 - private static final int EOF = LexerInput.EOF;
79.67 - private final LexerInput input;
79.68 - private final TokenFactory<PythonStringTokenId> tokenFactory;
79.69 - private final boolean substituting;
79.70 -
79.71 - /**
79.72 - * A Lexer for Python strings
79.73 - * @param substituting If true, handle substitution rules for double quoted strings, otherwise
79.74 - * single quoted strings.
79.75 - */
79.76 - public PythonStringLexer(LexerRestartInfo<PythonStringTokenId> info, boolean substituting) {
79.77 - this.input = info.input();
79.78 - this.tokenFactory = info.tokenFactory();
79.79 - this.substituting = substituting;
79.80 - assert (info.state() == null); // passed argument always null
79.81 - }
79.82 -
79.83 - @Override
79.84 - public Object state() {
79.85 - return null;
79.86 - }
79.87 -
79.88 - @Override
79.89 - public Token<PythonStringTokenId> nextToken() {
79.90 - boolean inWord = false;
79.91 - while (true) {
79.92 - int ch = input.read();
79.93 -
79.94 - switch (ch) {
79.95 - case EOF:
79.96 -
79.97 - if (input.readLength() > 0) {
79.98 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
79.99 - input.readLength());
79.100 - } else {
79.101 - return null;
79.102 - }
79.103 -
79.104 - case '>':
79.105 - // Look for doctest: \n, whitespace, >>>{embedded python}\n
79.106 - int initialReadLength = input.readLength();
79.107 - input.read();
79.108 - if (ch == '>') {
79.109 - ch = input.read();
79.110 - if (ch == '>') {
79.111 - if (input.readLength() > 3) {
79.112 - input.backup(3);
79.113 - // Finish this token such that we can do a dedicated token for the ">>>" line.
79.114 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
79.115 - input.readLength());
79.116 - }
79.117 - // Find end...
79.118 - boolean nonempty = false;
79.119 - while (true) {
79.120 - ch = input.read();
79.121 - if (ch == EOF) {
79.122 - break;
79.123 - } else if (ch == '\n') {
79.124 - if (nonempty) {
79.125 - input.backup(1); // Don't include the \n
79.126 - return tokenFactory.createToken(PythonStringTokenId.EMBEDDED_PYTHON,
79.127 - input.readLength());
79.128 -
79.129 - }
79.130 - break;
79.131 - } else if (!Character.isWhitespace(ch)) {
79.132 - nonempty = true;
79.133 - }
79.134 - }
79.135 - }
79.136 - }
79.137 - if (input.readLength() > initialReadLength) {
79.138 - input.backup(input.readLength() - initialReadLength);
79.139 - } else {
79.140 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
79.141 - input.readLength());
79.142 - }
79.143 - break;
79.144 -
79.145 - case '\\':
79.146 -
79.147 - if (input.readLength() > 1) { // already read some text
79.148 - input.backup(1);
79.149 -
79.150 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
79.151 - input.readLength());
79.152 - }
79.153 -
79.154 - ch = input.read();
79.155 - if (ch == EOF) {
79.156 - return tokenFactory.createToken(PythonStringTokenId.STRING_INVALID,
79.157 - input.readLength());
79.158 - } else {
79.159 - return tokenFactory.createToken(PythonStringTokenId.STRING_ESCAPE,
79.160 - input.readLength());
79.161 - }
79.162 -
79.163 - case 'f': // ftp:
79.164 - case 'm': // mailto:
79.165 - case 'w': // www.
79.166 - case 'h': { // http links. TODO: link:, ftp:, mailto:, and www.
79.167 -
79.168 - if (inWord) {
79.169 - break;
79.170 - }
79.171 -
79.172 - int originalLength = input.readLength();
79.173 - boolean foundLinkBegin = false;
79.174 -
79.175 - if (ch == 'h') { // http:
79.176 -
79.177 - if (input.read() == 't') {
79.178 - if (input.read() == 't') {
79.179 - if (input.read() == 'p') {
79.180 - int r = input.read();
79.181 - if (r == ':') {
79.182 - foundLinkBegin = true;
79.183 - } else if (r == 's') {
79.184 - if (input.read() == ':') {
79.185 - foundLinkBegin = true;
79.186 - } else {
79.187 - input.backup(5);
79.188 - }
79.189 - } else {
79.190 - input.backup(4);
79.191 - }
79.192 - } else {
79.193 - input.backup(3);
79.194 - }
79.195 - } else {
79.196 - input.backup(2);
79.197 - }
79.198 - } else {
79.199 - input.backup(1);
79.200 - }
79.201 - } else if (ch == 'f') { // ftp:
79.202 -
79.203 - if (input.read() == 't') {
79.204 - if (input.read() == 'p') {
79.205 - if (input.read() == ':') {
79.206 - foundLinkBegin = true;
79.207 - } else {
79.208 - input.backup(3);
79.209 - }
79.210 - } else {
79.211 - input.backup(2);
79.212 - }
79.213 - } else {
79.214 - input.backup(1);
79.215 - }
79.216 - } else if (ch == 'm') { // mailto:
79.217 -
79.218 - if (input.read() == 'a') {
79.219 - if (input.read() == 'i') {
79.220 - if (input.read() == 'l') {
79.221 - if (input.read() == 't') {
79.222 - if (input.read() == 'o') {
79.223 - if (input.read() == ':') {
79.224 - foundLinkBegin = true;
79.225 - } else {
79.226 - input.backup(6);
79.227 - }
79.228 - } else {
79.229 - input.backup(5);
79.230 - }
79.231 - } else {
79.232 - input.backup(4);
79.233 - }
79.234 - } else {
79.235 - input.backup(3);
79.236 - }
79.237 - } else {
79.238 - input.backup(2);
79.239 - }
79.240 - } else {
79.241 - input.backup(1);
79.242 - }
79.243 - } else if (ch == 'w') { // www.
79.244 -
79.245 - if (input.read() == 'w') {
79.246 - if (input.read() == 'w') {
79.247 - if (input.read() == '.') {
79.248 - foundLinkBegin = true;
79.249 - } else {
79.250 - input.backup(3);
79.251 - }
79.252 - } else {
79.253 - input.backup(2);
79.254 - }
79.255 - } else {
79.256 - input.backup(1);
79.257 - }
79.258 - }
79.259 -
79.260 - if (foundLinkBegin) {
79.261 - while (ch != EOF) {
79.262 - ch = input.read();
79.263 -
79.264 - if ((ch == ']') || (ch == ')') || Character.isWhitespace(ch) ||
79.265 - (ch == '\'') || (ch == '"')) {
79.266 - input.backup(1);
79.267 -
79.268 - break;
79.269 - }
79.270 - }
79.271 -
79.272 - if (originalLength > 1) {
79.273 - input.backup(input.readLengthEOF() - originalLength + 1);
79.274 -
79.275 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
79.276 - input.readLength());
79.277 - }
79.278 -
79.279 - if (input.readLength() > 2) {
79.280 - return tokenFactory.createToken(PythonStringTokenId.URL,
79.281 - input.readLength());
79.282 - }
79.283 - }
79.284 - break;
79.285 - }
79.286 - }
79.287 -
79.288 - inWord = Character.isJavaIdentifierPart(ch);
79.289 - }
79.290 - }
79.291 -
79.292 - @Override
79.293 - public void release() {
79.294 - }
79.295 -}
80.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonStringTokenId.java Fri Sep 18 16:20:24 2015 -0500
80.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
80.3 @@ -1,125 +0,0 @@
80.4 -/*
80.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
80.6 - *
80.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
80.8 - *
80.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
80.10 - * Other names may be trademarks of their respective owners.
80.11 - *
80.12 - * The contents of this file are subject to the terms of either the GNU
80.13 - * General Public License Version 2 only ("GPL") or the Common
80.14 - * Development and Distribution License("CDDL") (collectively, the
80.15 - * "License"). You may not use this file except in compliance with the
80.16 - * License. You can obtain a copy of the License at
80.17 - * http://www.netbeans.org/cddl-gplv2.html
80.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
80.19 - * specific language governing permissions and limitations under the
80.20 - * License. When distributing the software, include this License Header
80.21 - * Notice in each file and include the License file at
80.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
80.23 - * particular file as subject to the "Classpath" exception as provided
80.24 - * by Oracle in the GPL Version 2 section of the License file that
80.25 - * accompanied this code. If applicable, add the following below the
80.26 - * License Header, with the fields enclosed by brackets [] replaced by
80.27 - * your own identifying information:
80.28 - * "Portions Copyrighted [year] [name of copyright owner]"
80.29 - *
80.30 - * Contributor(s):
80.31 - *
80.32 - * The Original Software is NetBeans. The Initial Developer of the Original
80.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
80.34 - * Microsystems, Inc. All Rights Reserved.
80.35 - *
80.36 - * If you wish your version of this file to be governed by only the CDDL
80.37 - * or only the GPL Version 2, indicate your decision by adding
80.38 - * "[Contributor] elects to include this software in this distribution
80.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
80.40 - * single choice of license, a recipient has the option to distribute
80.41 - * your version of this file under either the CDDL, the GPL Version 2 or
80.42 - * to extend the choice of license to its licensees as provided above.
80.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
80.44 - * Version 2 license, then the option applies only if the new code is
80.45 - * made subject to such option by the copyright holder.
80.46 - */
80.47 -package org.netbeans.modules.python.editor.lexer;
80.48 -
80.49 -import java.util.Collection;
80.50 -import java.util.EnumSet;
80.51 -import java.util.Map;
80.52 -
80.53 -import org.netbeans.api.lexer.InputAttributes;
80.54 -import org.netbeans.api.lexer.Language;
80.55 -import org.netbeans.api.lexer.LanguagePath;
80.56 -import org.netbeans.api.lexer.Token;
80.57 -import org.netbeans.api.lexer.TokenId;
80.58 -import org.netbeans.api.lexer.TokenUtilities;
80.59 -import org.netbeans.spi.lexer.LanguageEmbedding;
80.60 -import org.netbeans.spi.lexer.LanguageHierarchy;
80.61 -import org.netbeans.spi.lexer.Lexer;
80.62 -import org.netbeans.spi.lexer.LexerRestartInfo;
80.63 -
80.64 -/**
80.65 - *
80.66 - * @author Tor Norbye
80.67 - */
80.68 -public enum PythonStringTokenId implements TokenId {
80.69 - STRING_TEXT("string"),
80.70 - STRING_ESCAPE("string-escape"),
80.71 - STRING_INVALID("string-escape-invalid"),
80.72 - URL("url"),
80.73 - EMBEDDED_PYTHON("string");
80.74 - private final String primaryCategory;
80.75 -
80.76 - PythonStringTokenId() {
80.77 - this(null);
80.78 - }
80.79 -
80.80 - PythonStringTokenId(String primaryCategory) {
80.81 - this.primaryCategory = primaryCategory;
80.82 - }
80.83 -
80.84 - @Override
80.85 - public String primaryCategory() {
80.86 - return primaryCategory;
80.87 - }
80.88 - public static final Language<PythonStringTokenId> language =
80.89 - new LanguageHierarchy<PythonStringTokenId>() {
80.90 - @Override
80.91 - protected Collection<PythonStringTokenId> createTokenIds() {
80.92 - return EnumSet.allOf(PythonStringTokenId.class);
80.93 - }
80.94 -
80.95 - @Override
80.96 - protected Map<String, Collection<PythonStringTokenId>> createTokenCategories() {
80.97 - return null; // no extra categories
80.98 - }
80.99 -
80.100 - @Override
80.101 - protected Lexer<PythonStringTokenId> createLexer(
80.102 - LexerRestartInfo<PythonStringTokenId> info) {
80.103 - return new PythonStringLexer(info, true);
80.104 - }
80.105 -
80.106 - @Override
80.107 - protected LanguageEmbedding<?> embedding(
80.108 - Token<PythonStringTokenId> token, LanguagePath languagePath,
80.109 - InputAttributes inputAttributes) {
80.110 - PythonStringTokenId id = token.id();
80.111 -
80.112 - if (id == EMBEDDED_PYTHON && token.text() != null) {
80.113 - return LanguageEmbedding.create(PythonTokenId.language(), 3, 0); // 3: Exlude ">>>" prefix
80.114 - }
80.115 -
80.116 - return null; // No embedding
80.117 - }
80.118 -
80.119 - @Override
80.120 - public String mimeType() {
80.121 - return "text/x-python-string"; // NOI18N
80.122 - }
80.123 - }.language();
80.124 -
80.125 - public static Language<PythonStringTokenId> language() {
80.126 - return language;
80.127 - }
80.128 -}
81.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonTokenId.java Fri Sep 18 16:20:24 2015 -0500
81.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
81.3 @@ -1,206 +0,0 @@
81.4 -/*
81.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
81.6 - *
81.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
81.8 - *
81.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
81.10 - * Other names may be trademarks of their respective owners.
81.11 - *
81.12 - * The contents of this file are subject to the terms of either the GNU
81.13 - * General Public License Version 2 only ("GPL") or the Common
81.14 - * Development and Distribution License("CDDL") (collectively, the
81.15 - * "License"). You may not use this file except in compliance with the
81.16 - * License. You can obtain a copy of the License at
81.17 - * http://www.netbeans.org/cddl-gplv2.html
81.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
81.19 - * specific language governing permissions and limitations under the
81.20 - * License. When distributing the software, include this License Header
81.21 - * Notice in each file and include the License file at
81.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
81.23 - * particular file as subject to the "Classpath" exception as provided
81.24 - * by Oracle in the GPL Version 2 section of the License file that
81.25 - * accompanied this code. If applicable, add the following below the
81.26 - * License Header, with the fields enclosed by brackets [] replaced by
81.27 - * your own identifying information:
81.28 - * "Portions Copyrighted [year] [name of copyright owner]"
81.29 - *
81.30 - * Contributor(s):
81.31 - *
81.32 - * The Original Software is NetBeans. The Initial Developer of the Original
81.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
81.34 - * Microsystems, Inc. All Rights Reserved.
81.35 - *
81.36 - * If you wish your version of this file to be governed by only the CDDL
81.37 - * or only the GPL Version 2, indicate your decision by adding
81.38 - * "[Contributor] elects to include this software in this distribution
81.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
81.40 - * single choice of license, a recipient has the option to distribute
81.41 - * your version of this file under either the CDDL, the GPL Version 2 or
81.42 - * to extend the choice of license to its licensees as provided above.
81.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
81.44 - * Version 2 license, then the option applies only if the new code is
81.45 - * made subject to such option by the copyright holder.
81.46 - */
81.47 -package org.netbeans.modules.python.editor.lexer;
81.48 -
81.49 -import java.util.Collection;
81.50 -import java.util.EnumSet;
81.51 -import java.util.HashMap;
81.52 -import java.util.Map;
81.53 -import org.netbeans.api.lexer.InputAttributes;
81.54 -import org.netbeans.api.lexer.Language;
81.55 -import org.netbeans.api.lexer.LanguagePath;
81.56 -import org.netbeans.api.lexer.Token;
81.57 -import org.netbeans.api.lexer.TokenId;
81.58 -import org.netbeans.modules.python.api.PythonMIMEResolver;
81.59 -import org.netbeans.modules.python.editor.PythonUtils;
81.60 -import org.netbeans.spi.lexer.LanguageEmbedding;
81.61 -import org.netbeans.spi.lexer.LanguageHierarchy;
81.62 -import org.netbeans.spi.lexer.Lexer;
81.63 -import org.netbeans.spi.lexer.LexerInput;
81.64 -import org.netbeans.spi.lexer.LexerRestartInfo;
81.65 -
81.66 -import org.netbeans.spi.lexer.TokenFactory;
81.67 -import org.openide.filesystems.FileObject;
81.68 -import static org.netbeans.modules.python.editor.lexer.PythonLexer.*;
81.69 -
81.70 -/**
81.71 - * @todo add the rest of the tokens
81.72 - *
81.73 - * @author Martin Adamek
81.74 - * @author alley
81.75 - */
81.76 -public enum PythonTokenId implements TokenId {
81.77 - ERROR(null, ERROR_CAT),
81.78 - IDENTIFIER(null, IDENTIFIER_CAT),
81.79 - INT_LITERAL(null, NUMBER_CAT),
81.80 - FLOAT_LITERAL(null, NUMBER_CAT),
81.81 - STRING_LITERAL(null, STRING_CAT),
81.82 - WHITESPACE(null, WHITESPACE_CAT),
81.83 - NEWLINE(null, WHITESPACE_CAT),
81.84 - DECORATOR(null, OPERATOR_CAT), // NOI18N
81.85 - // CONTINUED_LINE(null, WHITESPACE_CAT), // NOI18N
81.86 - COMMENT(null, COMMENT_CAT),
81.87 - BUILTIN_FUNCTION(null, KEYWORD_CAT), // NOI18N
81.88 - LPAREN("(", SEPARATOR_CAT), // NOI18N
81.89 - RPAREN(")", SEPARATOR_CAT), // NOI18N
81.90 - LBRACE("{", SEPARATOR_CAT), // NOI18N
81.91 - RBRACE("}", SEPARATOR_CAT), // NOI18N
81.92 - LBRACKET("[", SEPARATOR_CAT), // NOI18N
81.93 - RBRACKET("]", SEPARATOR_CAT), // NOI18N
81.94 - STRING_BEGIN(null, STRING_CAT),
81.95 - STRING_END(null, STRING_CAT),
81.96 - // Cheating: out of laziness just map all keywords returning from Jython
81.97 - // into a single KEYWORD token; eventually we will have separate tokens
81.98 - // for each here such that the various helper methods for formatting,
81.99 - // smart indent, brace matching etc. can refer to specific keywords
81.100 - ANY_KEYWORD(null, KEYWORD_CAT),
81.101 - ANY_OPERATOR(null, OPERATOR_CAT),
81.102 - DEF("def", KEYWORD_CAT), // NOI18N
81.103 - CLASS("class", KEYWORD_CAT), // NOI18N
81.104 - IF("if", KEYWORD_CAT), // NOI18N
81.105 - ELSE("else", KEYWORD_CAT), // NOI18N
81.106 - ELIF("elif", KEYWORD_CAT), // NOI18N
81.107 - RAISE("raise", KEYWORD_CAT), // NOI18N
81.108 - PASS("pass", KEYWORD_CAT), // NOI18N
81.109 - RETURN("return", KEYWORD_CAT), // NOI18N
81.110 - EXCEPT("except", KEYWORD_CAT), // NOI18N
81.111 - FINALLY("finally", KEYWORD_CAT), // NOI18N
81.112 - IMPORT("import", KEYWORD_CAT), // NOI18N
81.113 - FROM("from", KEYWORD_CAT), // NOI18N
81.114 - TRUE("True", KEYWORD_CAT), // NOI18N
81.115 - FALSE("False", KEYWORD_CAT), // NOI18N
81.116 - NONE("None", KEYWORD_CAT), // NOI18N
81.117 - TRY("try", KEYWORD_CAT), // NOI18N
81.118 - DOT(".", OPERATOR_CAT), // NOI18N
81.119 - COMMA(",", OPERATOR_CAT), // NOI18N
81.120 - COLON(":", OPERATOR_CAT), // NOI18N
81.121 - ESC("\\", OPERATOR_CAT), // NOI18N
81.122 -
81.123 - // Non-unary operators which indicate a line continuation if used at the end of a line
81.124 - NONUNARY_OP(null, OPERATOR_CAT);
81.125 - private final String fixedText;
81.126 - private final String primaryCategory;
81.127 -
81.128 - PythonTokenId(String fixedText, String primaryCategory) {
81.129 - this.fixedText = fixedText;
81.130 - this.primaryCategory = primaryCategory;
81.131 - }
81.132 -
81.133 - @Override
81.134 - public String primaryCategory() {
81.135 - return primaryCategory;
81.136 - }
81.137 -
81.138 - public String fixedText() {
81.139 - return fixedText;
81.140 - }
81.141 - private static final Language<PythonTokenId> language =
81.142 - new LanguageHierarchy<PythonTokenId>() {
81.143 - @Override
81.144 - protected String mimeType() {
81.145 - return PythonMIMEResolver.PYTHON_MIME_TYPE;
81.146 - }
81.147 -
81.148 - @Override
81.149 - protected Collection<PythonTokenId> createTokenIds() {
81.150 - return EnumSet.allOf(PythonTokenId.class);
81.151 - }
81.152 -
81.153 - @Override
81.154 - protected Map<String, Collection<PythonTokenId>> createTokenCategories() {
81.155 - Map<String, Collection<PythonTokenId>> cats =
81.156 - new HashMap<>();
81.157 - return cats;
81.158 - }
81.159 -
81.160 - @Override
81.161 - protected Lexer<PythonTokenId> createLexer(LexerRestartInfo<PythonTokenId> info) {
81.162 - FileObject fileObject = (FileObject)info.getAttributeValue(FileObject.class);
81.163 - final TokenFactory<PythonTokenId> tokenFactory = info.tokenFactory();
81.164 - final LexerInput input = info.input();
81.165 - // Lex .rst files just as literal strings
81.166 - if (fileObject != null && PythonUtils.isRstFile(fileObject)) {
81.167 - return new Lexer<PythonTokenId>() {
81.168 - @Override
81.169 - public Token<PythonTokenId> nextToken() {
81.170 - if (input.read() == LexerInput.EOF) {
81.171 - return null;
81.172 - }
81.173 - while (input.read() != LexerInput.EOF) {
81.174 - ;
81.175 - }
81.176 - return tokenFactory.createToken(PythonTokenId.STRING_LITERAL, input.readLength());
81.177 - }
81.178 -
81.179 - @Override
81.180 - public Object state() {
81.181 - return null;
81.182 - }
81.183 -
81.184 - @Override
81.185 - public void release() {
81.186 - }
81.187 - };
81.188 - }
81.189 - return new PythonLexer(info);
81.190 - }
81.191 -
81.192 - @Override
81.193 - protected LanguageEmbedding<?> embedding(Token<PythonTokenId> token,
81.194 - LanguagePath languagePath, InputAttributes inputAttributes) {
81.195 - PythonTokenId id = token.id();
81.196 - if (id == STRING_LITERAL) {
81.197 - return LanguageEmbedding.create(PythonStringTokenId.language, 0, 0);
81.198 - } else if (id == COMMENT) {
81.199 - return LanguageEmbedding.create(PythonCommentTokenId.language(), 1, 0);
81.200 - }
81.201 -
81.202 - return null; // No embedding
81.203 - }
81.204 - }.language();
81.205 -
81.206 - public static Language<PythonTokenId> language() {
81.207 - return language;
81.208 - }
81.209 -}
82.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/Bundle.properties Fri Sep 18 16:20:24 2015 -0500
82.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
82.3 @@ -1,284 +0,0 @@
82.4 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
82.5 -#
82.6 -# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
82.7 -#
82.8 -# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
82.9 -# Other names may be trademarks of their respective owners.
82.10 -#
82.11 -# The contents of this file are subject to the terms of either the GNU
82.12 -# General Public License Version 2 only ("GPL") or the Common
82.13 -# Development and Distribution License("CDDL") (collectively, the
82.14 -# "License"). You may not use this file except in compliance with the
82.15 -# License. You can obtain a copy of the License at
82.16 -# http://www.netbeans.org/cddl-gplv2.html
82.17 -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
82.18 -# specific language governing permissions and limitations under the
82.19 -# License. When distributing the software, include this License Header
82.20 -# Notice in each file and include the License file at
82.21 -# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
82.22 -# particular file as subject to the "Classpath" exception as provided
82.23 -# by Oracle in the GPL Version 2 section of the License file that
82.24 -# accompanied this code. If applicable, add the following below the
82.25 -# License Header, with the fields enclosed by brackets [] replaced by
82.26 -# your own identifying information:
82.27 -# "Portions Copyrighted [year] [name of copyright owner]"
82.28 -#
82.29 -# Contributor(s):
82.30 -#
82.31 -# The Original Software is NetBeans. The Initial Developer of the Original
82.32 -# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
82.33 -# Microsystems, Inc. All Rights Reserved.
82.34 -#
82.35 -# If you wish your version of this file to be governed by only the CDDL
82.36 -# or only the GPL Version 2, indicate your decision by adding
82.37 -# "[Contributor] elects to include this software in this distribution
82.38 -# under the [CDDL or GPL Version 2] license." If you do not indicate a
82.39 -# single choice of license, a recipient has the option to distribute
82.40 -# your version of this file under either the CDDL, the GPL Version 2 or
82.41 -# to extend the choice of license to its licensees as provided above.
82.42 -# However, if you add GPL Version 2 code and therefore, elected the GPL
82.43 -# Version 2 license, then the option applies only if the new code is
82.44 -# made subject to such option by the copyright holder.
82.45 -
82.46 -# Formating options
82.47 -
82.48 -LBL_TabsAndIndents=Tabs and Indents
82.49 -LBL_CodeGeneration=Code Generation
82.50 -LBL_Alignment=Alignment
82.51 -LBL_Wrapping=Wrapping
82.52 -LBL_BlankLines=Blank Lines
82.53 -LBL_Spaces=Spaces
82.54 -LBL_Imports=Imports
82.55 -
82.56 -LBL_bp_SAME_LINE=Same Line
82.57 -LBL_bp_NEW_LINE=New Line
82.58 -LBL_bp_NEW_LINE_HALF_INDENTED=New Line Half Indented
82.59 -LBL_bp_NEW_LINE_INDENTED= New Line Indented
82.60 -
82.61 -LBL_bg_GENERATE=Generate
82.62 -LBL_bg_LEAVE_ALONE=Leave Alone
82.63 -LBL_bg_ELIMINATE=Eliminate
82.64 -
82.65 -LBL_wrp_WRAP_ALWAYS=Always
82.66 -LBL_wrp_WRAP_IF_LONG=If Long
82.67 -LBL_wrp_WRAP_NEVER=Never
82.68 -
82.69 -LBL_imp_COMMENT_OUT=Comment Out
82.70 -LBL_imp_LEAVE_ALONE=Leave Alone
82.71 -LBL_imp_DELETE=Delete
82.72 -
82.73 -LBL_ExpandTabToSpaces=&Expand Tab to Spaces
82.74 -LBL_TabSize=&Tab Size:
82.75 -LBL_IndentSize=&Indentation Size:
82.76 -LBL_ContinuationIndentSize=&Continuation Indentation Size:
82.77 -LBL_LabelIndent=&Label Indentation\:
82.78 -LBL_AbsoluteLabelIndent=&Absolute Label Indentation
82.79 -LBL_IndentTopLevelClassMemberts=Indent Top Level Class &Members
82.80 -LBL_AddLeadingStarInComment=Add Leading Star In Comment
82.81 -LBL_RightMargin=&Right Margin:
82.82 -
82.83 -LBL_Naming=Naming\:
82.84 -LBL_PreferLongerNames=Prefer Longer Names
82.85 -LBL_Prefix=Prefix
82.86 -LBL_Suffix=Suffix
82.87 -LBL_Field=Field\:
82.88 -LBL_StaticField=Static Field\:
82.89 -LBL_Parameter=Parameter\:
82.90 -LBL_LocalVariable=Local Variable\:
82.91 -LBL_Misc=Misc\:
82.92 -LBL_QualifyFieldAccess=Qualify Field Access
82.93 -LBL_UseIsForBooleanGetters=Use Is For Boolean Getters
82.94 -LBL_AddOverrideAnnotation=Add Override Annotation
82.95 -LBL_FinalMofier=Final Modifier\:
82.96 -LBL_ParametersFinal=Make Generated Parameters Final
82.97 -LBL_LocalVariablesFinal=Make Generated Local variables Final
82.98 -LBL_ImportOredering=Import Ordering\:
82.99 -LBL_ImportUp=Move Up
82.100 -LBL_ImportDown=Move Down
82.101 -LBL_blBeforePackage=Before &Package\:
82.102 -LBL_blAfterPackage=After P&ackage\:
82.103 -LBL_blBeforeImports=Before &Imports\:
82.104 -LBL_blAfterImports=After I&mports\:
82.105 -LBL_blBeforeClass=Before &Class\:
82.106 -LBL_blAfterClass=After C&lass\:
82.107 -LBL_blAfterClassHeader=After Class &Header\:
82.108 -LBL_blBeforeFields=Before &Field\:
82.109 -LBL_blAfterFields=After Fi&eld\:
82.110 -LBL_blBeforeMethods=Before &Method\:
82.111 -LBL_blAfterMethods=After Me&thod\:
82.112 -
82.113 -LBL_BeforeKeywords=Before Keywords
82.114 -LBL_spaceBeforeWhile="while"
82.115 -LBL_spaceBeforeElse="else"
82.116 -LBL_spaceBeforeCatch="catch"
82.117 -LBL_spaceBeforeFinally="finally"
82.118 -
82.119 -LBL_BeforeParentheses=Before Parentheses
82.120 -LBL_spaceBeforeMethodDeclParen=Method Declaration
82.121 -LBL_spaceBeforeMethodCallParen=Method Call
82.122 -LBL_spaceBeforeIfParen="if"
82.123 -LBL_spaceBeforeForParen="for"
82.124 -LBL_spaceBeforeWhileParen="while"
82.125 -LBL_spaceBeforeCatchParen="catch"
82.126 -LBL_spaceBeforeSwitchParen="switch"
82.127 -LBL_spaceBeforeSynchronizedParen="synchronized"
82.128 -LBL_spaceBeforeAnnotationParen=Annotation Parameters
82.129 -
82.130 -LBL_AroundOperators=Around Operators
82.131 -LBL_spaceAroundUnaryOps=Unary Operators
82.132 -LBL_spaceAroundBinaryOps=Binary Operators
82.133 -LBL_spaceAroundTernaryOps=Ternary Operators
82.134 -LBL_spaceAroundAssignOps=Assignment Operators
82.135 -
82.136 -LBL_BeforeLeftBraces=Before Left Braces
82.137 -LBL_spaceBeforeClassDeclLeftBrace=Class Declaration
82.138 -LBL_spaceBeforeMethodDeclLeftBrace=Method Declaration
82.139 -LBL_spaceBeforeIfLeftBrace="if"
82.140 -LBL_spaceBeforeElseLeftBrace="else"
82.141 -LBL_spaceBeforeWhileLeftBrace="while"
82.142 -LBL_spaceBeforeForLeftBrace="for"
82.143 -LBL_spaceBeforeDoLeftBrace="do"
82.144 -LBL_spaceBeforeSwitchLeftBrace="switch"
82.145 -LBL_spaceBeforeTryLeftBrace="try"
82.146 -LBL_spaceBeforeCatchLeftBrace="catch"
82.147 -LBL_spaceBeforeFinallyLeftBrace="finally"
82.148 -LBL_spaceBeforeSynchronizedLeftBrace="synchronized"
82.149 -LBL_spaceBeforeStaticInitLeftBrace=Static Initializer
82.150 -LBL_spaceBeforeArrayInitLeftBrace=Array Initializer
82.151 -
82.152 -LBL_WithinParentheses=Within Parentheses
82.153 -LBL_spaceWithinParens=Parentheses
82.154 -LBL_spaceWithinMethodDeclParens=Method Declaration
82.155 -LBL_spaceWithinMethodCallParens=Method Call
82.156 -LBL_spaceWithinIfParens="if"
82.157 -LBL_spaceWithinForParens="for"
82.158 -LBL_spaceWithinWhileParens="while"
82.159 -LBL_spaceWithinSwitchParens="switch"
82.160 -LBL_spaceWithinCatchParens="catch"
82.161 -LBL_spaceWithinSynchronizedParens="synchronized"
82.162 -LBL_spaceWithinTypeCastParens=Type Cast
82.163 -LBL_spaceWithinAnnotationParens=Annotation
82.164 -LBL_spaceWithinBraces=Braces
82.165 -LBL_spaceWithinArrayInitBrackets=Array Initializer Brackets
82.166 -
82.167 -LBL_Other=Other
82.168 -LBL_spaceBeforeComma=Before Comma
82.169 -LBL_spaceAfterComma=After Comma
82.170 -LBL_spaceBeforeSemi=Before Semicolon
82.171 -LBL_spaceAfterSemi=After Semicolon
82.172 -LBL_spaceBeforeColon=Before Colon
82.173 -LBL_spaceAfterColon=After Colon
82.174 -LBL_spaceAfterTypeCast=After Type Cast
82.175 -LBL_wrp_extendsImplementsKeyword=&Extends/Implements Keyword\:
82.176 -LBL_wrp_extendsImplementsList=E&xtends/Implements List\:
82.177 -LBL_wrp_methodParameters=Method &Parameters\:
82.178 -LBL_wrp_throwsKeyword=&Throws Keyword\:
82.179 -LBL_wrp_throwsList=Th&rows List\:
82.180 -LBL_wrp_methodCallArgs=Method Call &Arguments\:
82.181 -LBL_wrp_annotationArgs=Annotation Arg&uments\:
82.182 -LBL_wrp_chainedMethodCalls=C&hained Method Calls\:
82.183 -LBL_wrp_arrayInit=Array Initiali&zer\:
82.184 -LBL_wrp_for=&For\:
82.185 -LBL_wrp_forStatement=F&or Statement\:
82.186 -LBL_wrp_ifStatement=&If Statement\:
82.187 -LBL_wrp_whileStatement=&While Statement\:
82.188 -LBL_wrp_doWhileStatement=&Do ... While Statement
82.189 -LBL_wrp_assert=&Assert\:
82.190 -LBL_wrp_enumConstants=Enum &Constants\:
82.191 -LBL_wrp_annotations=A&nnotations\:
82.192 -LBL_wrp_binaryOps=&Binary Operators\:
82.193 -LBL_wrp_ternaryOps=Ternar&y Operators\:
82.194 -LBL_wrp_assignOps=Assi&gnment Operators\:
82.195 -
82.196 -LBL_br_bracesPlacement=Braces Placement
82.197 -LBL_br_bracesGeneration=Braces Generation
82.198 -LBL_al_newLines=New Lines
82.199 -LBL_al_multilineAlignment=Multiline Alignment
82.200 -LBL_nl_Else="&else"
82.201 -LBL_nl_While="w&hile"
82.202 -LBL_nl_Catch="c&atch"
82.203 -LBL_nl_Finally="finall&y"
82.204 -LBL_nl_Modifiers=after modifie&rs
82.205 -LBL_am_MethodParams=Method &Parameters
82.206 -LBL_am_CallArgs=Method Call Arg&uments
82.207 -LBL_am_AnnotationArgs=&Annotation Arguments
82.208 -LBL_an_Implements=I&mplements List
82.209 -LBL_am_Throws=&Throws List
82.210 -LBL_am_Paren=Parenthesize&d
82.211 -LBL_am_BinaryOp=&Binary Operators
82.212 -LBL_am_TernaryOp=Ter&nary Operators
82.213 -LBL_am_Assign=Assi&gnment
82.214 -LBL_am_For=&For
82.215 -LBL_am_ArrayInit=Array Initiali&zer
82.216 -
82.217 -LBL_IndentCasesFromSwitch=Indent Case Statements In &Switch
82.218 -
82.219 -# Following entries (marked) as samples are used as examples in the formating
82.220 -# options. It is highly discourage to localize them unless absolutely necessary.
82.221 -
82.222 -SAMPLE_Default=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC
82.223 -SAMPLE_TabsIndents=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC {
82.224 -SAMPLE_AlignBraces=@Anno(paramA="a Value", paramB="bValue")\n
82.225 -SAMPLE_Wrapping=@Anno(paramA="a Value", paramB="bValue")
82.226 -SAMPLE_BlankLines=package org.netbeans.samples;
82.227 -
82.228 -SAMPLE_Imports=\
82.229 -# Copyright 2008\n\
82.230 -"""My Module"""\n\
82.231 -\n\
82.232 -import sys\n\
82.233 -import wsgiref.handlers\n\
82.234 -from google.appengine.ext.webapp.util import run_wsgi_app\n\
82.235 -from google.appengine.ext import webapp\n\
82.236 -from google.appengine.ext import db\n\
82.237 -import os\n\
82.238 -\n\
82.239 -\n\
82.240 -from google.appengine.api import users\n\
82.241 -import google.appengine.api.test\n\
82.242 -from google.appengine.api import users\n\
82.243 -\n\
82.244 -from google.appengine.api import users\n\
82.245 -from google.appengine.api import users\n\
82.246 -import string\n\
82.247 -from google.appengine.ext.webapp import template as FooBar\n\
82.248 -from google.appengine.ext.webapp.util import login_required\n\
82.249 -import random\n\
82.250 -import datetime\n
82.251 -
82.252 -#\n\
82.253 -#new_str = swapcase("foo")
82.254 -
82.255 -
82.256 -# Newlines on the following line since space prefixes are ignored by the .properties loader
82.257 -SAMPLE_Spaces=\
82.258 -def func( arg1 ,arg2 ,\
82.259 -\n arg3 = 3, arg = 4):\
82.260 -\n\
82.261 -\n if pos!=-1 and optval[ pos-1 ].isspace():\
82.262 -\n x=5+2\
82.263 -\n\
82.264 -\nmodeDict = { 'r':'rb','w':'wb', \\\
82.265 -\n 'a' : 'r+b' }\
82.266 -\nx = 2; y=3 ; z = 5\n
82.267 -
82.268 -
82.269 -nlFinallyCheckBox1.text="finall&y"
82.270 -
82.271 -
82.272 -AN_Preview=Preview
82.273 -AD_Preview=Preview
82.274 -FmtImports.formatImportsCb.text=Organize Imports during formatting
82.275 -FmtImports.removeDuplicateCb.text=Remove Duplicate Imports
82.276 -FmtImports.systemLibsCb.text=Separate out system libraries
82.277 -FmtImports.onePerLineCb.text=Prefer one import per line
82.278 -FmtImports.cleanupLabel.text=Unused imports:
82.279 -FmtImports.preferSymbols.text=Prefer symbol imports
82.280 -FmtImports.sortImportsCb.text=Sort Alphabetically
82.281 -FmtSpaces.addAroundOp.text=Add spaces around operators
82.282 -FmtSpaces.removeInParam.text=But remove in parameter assignments
82.283 -FmtSpaces.removeInParen.text=Remove spaces inside ( ), { }, and [ ]
82.284 -FmtSpaces.addAfterComma.text=Add spaces after commas
82.285 -FmtSpaces.removeBeforeSep.text=Remove spaces before separators ( : , ; )
82.286 -FmtSpaces.collapseSpacesCb.text=Collapse multiple spaces
82.287 -FmtImports.sepFromImpCb.text=Separate "from" and "import" statements
83.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/CodeStyle.java Fri Sep 18 16:20:24 2015 -0500
83.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
83.3 @@ -1,737 +0,0 @@
83.4 -/*
83.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
83.6 - *
83.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
83.8 - *
83.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
83.10 - * Other names may be trademarks of their respective owners.
83.11 - *
83.12 - * The contents of this file are subject to the terms of either the GNU
83.13 - * General Public License Version 2 only ("GPL") or the Common
83.14 - * Development and Distribution License("CDDL") (collectively, the
83.15 - * "License"). You may not use this file except in compliance with the
83.16 - * License. You can obtain a copy of the License at
83.17 - * http://www.netbeans.org/cddl-gplv2.html
83.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
83.19 - * specific language governing permissions and limitations under the
83.20 - * License. When distributing the software, include this License Header
83.21 - * Notice in each file and include the License file at
83.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
83.23 - * particular file as subject to the "Classpath" exception as provided
83.24 - * by Oracle in the GPL Version 2 section of the License file that
83.25 - * accompanied this code. If applicable, add the following below the
83.26 - * License Header, with the fields enclosed by brackets [] replaced by
83.27 - * your own identifying information:
83.28 - * "Portions Copyrighted [year] [name of copyright owner]"
83.29 - *
83.30 - * Contributor(s):
83.31 - *
83.32 - * The Original Software is NetBeans. The Initial Developer of the Original
83.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
83.34 - * Microsystems, Inc. All Rights Reserved.
83.35 - *
83.36 - * If you wish your version of this file to be governed by only the CDDL
83.37 - * or only the GPL Version 2, indicate your decision by adding
83.38 - * "[Contributor] elects to include this software in this distribution
83.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
83.40 - * single choice of license, a recipient has the option to distribute
83.41 - * your version of this file under either the CDDL, the GPL Version 2 or
83.42 - * to extend the choice of license to its licensees as provided above.
83.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
83.44 - * Version 2 license, then the option applies only if the new code is
83.45 - * made subject to such option by the copyright holder.
83.46 - */
83.47 -package org.netbeans.modules.python.editor.options;
83.48 -
83.49 -import java.util.prefs.Preferences;
83.50 -import javax.swing.text.Document;
83.51 -import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
83.52 -
83.53 -import org.openide.filesystems.FileObject;
83.54 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
83.55 -
83.56 -/**
83.57 - * XXX make sure the getters get the defaults from somewhere
83.58 - * XXX add support for profiles
83.59 - * XXX get the preferences node from somewhere else in odrer to be able not to
83.60 - * use the getters and to be able to write to it.
83.61 - *
83.62 - * @author Dusan Balek
83.63 - */
83.64 -public final class CodeStyle {
83.65 - static {
83.66 - FmtOptions.codeStyleProducer = new Producer();
83.67 - }
83.68 - private Preferences preferences;
83.69 -
83.70 - private CodeStyle(Preferences preferences) {
83.71 - this.preferences = preferences;
83.72 - }
83.73 -
83.74 -// /**
83.75 -// * Gets <code>CodeStyle</code> for files in the given project.
83.76 -// *
83.77 -// * <p>Please see the other two <code>getDefault</code> methods as they are
83.78 -// * the preferred way of getting <code>CodeStyle</code>.
83.79 -// *
83.80 -// * @param project The project to get the <code>CodeStyle</code> for.
83.81 -// * @return The current code style that would be used by documents opened
83.82 -// * from files belonging to the <code>project</code>.
83.83 -// *
83.84 -// * @deprecated Please use {@link #getDefault(javax.swing.text.Document)}
83.85 -// * or {@link #getDefault(org.openide.filesystems.FileObject)} respectively.
83.86 -// */
83.87 -// @Deprecated
83.88 -// public static CodeStyle getDefault(Project project) {
83.89 -// return getDefault(project.getProjectDirectory());
83.90 -// }
83.91 - /**
83.92 - * Gets <code>CodeStyle</code> for the given file. If you have a document
83.93 - * instance you should use the {@link #getDefault(javax.swing.text.Document)}
83.94 - * method.
83.95 - *
83.96 - * @param file The file to get the <code>CodeStyle</code> for.
83.97 - * @return The current code style that would be used by a document if the
83.98 - * <code>file</code> were opened in the editor.
83.99 - *
83.100 - * @since 0.39
83.101 - */
83.102 - public synchronized static CodeStyle getDefault(FileObject file) {
83.103 - Preferences prefs = CodeStylePreferences.get(file).getPreferences();
83.104 - return FmtOptions.codeStyleProducer.create(prefs);
83.105 - }
83.106 -
83.107 - /**
83.108 - * Gets <code>CodeStyle</code> for the given document. This is the preferred
83.109 - * method of getting <code>CodeStyle</code>. If you don't have a document
83.110 - * you can use {@link #getDefault(org.openide.filesystems.FileObject)} method instead.
83.111 - *
83.112 - * @param doc The document to get the <code>CodeStyle</code> for.
83.113 - * @return The current code style used by a document. This is the code style that
83.114 - * will be used when formatting the document or generating new code.
83.115 - *
83.116 - * @since 0.39
83.117 - */
83.118 - public synchronized static CodeStyle getDefault(Document doc) {
83.119 - Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
83.120 - return FmtOptions.codeStyleProducer.create(prefs);
83.121 - }
83.122 -
83.123 - // General tabs and indents ------------------------------------------------
83.124 - public boolean expandTabToSpaces() {
83.125 -// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
83.126 - return preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
83.127 - }
83.128 -
83.129 - public int getTabSize() {
83.130 -// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
83.131 - return preferences.getInt(tabSize, getDefaultAsInt(tabSize));
83.132 - }
83.133 -
83.134 - public int getIndentSize() {
83.135 -// System.out.println("~~~ indent-shift-width=" + preferences.get(SimpleValueNames.INDENT_SHIFT_WIDTH, null));
83.136 - int indentLevel = preferences.getInt(indentSize, getDefaultAsInt(indentSize));
83.137 -
83.138 - if (indentLevel <= 0) {
83.139 -// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
83.140 - boolean expandTabs = preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
83.141 - if (expandTabs) {
83.142 -// System.out.println("~~~ spaces-per-tab=" + preferences.get(SimpleValueNames.SPACES_PER_TAB, null));
83.143 - indentLevel = preferences.getInt(spacesPerTab, getDefaultAsInt(spacesPerTab));
83.144 - } else {
83.145 -// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
83.146 - indentLevel = preferences.getInt(tabSize, getDefaultAsInt(tabSize));
83.147 - }
83.148 - }
83.149 -
83.150 - return indentLevel;
83.151 - }
83.152 -
83.153 - public int getContinuationIndentSize() {
83.154 - return preferences.getInt(continuationIndentSize, getDefaultAsInt(continuationIndentSize));
83.155 - }
83.156 -
83.157 - public int getLabelIndent() {
83.158 - return preferences.getInt(labelIndent, getDefaultAsInt(labelIndent));
83.159 - }
83.160 -
83.161 - public boolean absoluteLabelIndent() {
83.162 - return preferences.getBoolean(absoluteLabelIndent, getDefaultAsBoolean(absoluteLabelIndent));
83.163 - }
83.164 -
83.165 - public boolean indentTopLevelClassMembers() {
83.166 - return preferences.getBoolean(indentTopLevelClassMembers, getDefaultAsBoolean(indentTopLevelClassMembers));
83.167 - }
83.168 -
83.169 - public boolean indentCasesFromSwitch() {
83.170 - return preferences.getBoolean(indentCasesFromSwitch, getDefaultAsBoolean(indentCasesFromSwitch));
83.171 - }
83.172 -
83.173 - public int getRightMargin() {
83.174 - return preferences.getInt(rightMargin, getDefaultAsInt(rightMargin));
83.175 - }
83.176 -
83.177 - /*
83.178 - public boolean addLeadingStarInComment() {
83.179 - return preferences.getBoolean(addLeadingStarInComment, getDefaultAsBoolean(addLeadingStarInComment));
83.180 - }
83.181 -
83.182 - // Code generation ---------------------------------------------------------
83.183 -
83.184 - public boolean preferLongerNames() {
83.185 - return preferences.getBoolean(preferLongerNames, getDefaultAsBoolean(preferLongerNames));
83.186 - }
83.187 -
83.188 - public String getFieldNamePrefix() {
83.189 - return preferences.get(fieldNamePrefix, getDefaultAsString(fieldNamePrefix));
83.190 - }
83.191 -
83.192 - public String getFieldNameSuffix() {
83.193 - return preferences.get(fieldNameSuffix, getDefaultAsString(fieldNameSuffix));
83.194 - }
83.195 -
83.196 - public String getStaticFieldNamePrefix() {
83.197 - return preferences.get(staticFieldNamePrefix, getDefaultAsString(staticFieldNamePrefix));
83.198 - }
83.199 -
83.200 - public String getStaticFieldNameSuffix() {
83.201 - return preferences.get(staticFieldNameSuffix, getDefaultAsString(staticFieldNameSuffix));
83.202 - }
83.203 -
83.204 - public String getParameterNamePrefix() {
83.205 - return preferences.get(parameterNamePrefix, getDefaultAsString(parameterNamePrefix));
83.206 - }
83.207 -
83.208 - public String getParameterNameSuffix() {
83.209 - return preferences.get(parameterNameSuffix, getDefaultAsString(parameterNameSuffix));
83.210 - }
83.211 -
83.212 - public String getLocalVarNamePrefix() {
83.213 - return preferences.get(localVarNamePrefix, getDefaultAsString(localVarNamePrefix));
83.214 - }
83.215 -
83.216 - public String getLocalVarNameSuffix() {
83.217 - return preferences.get(localVarNameSuffix, getDefaultAsString(localVarNameSuffix));
83.218 - }
83.219 -
83.220 - public boolean qualifyFieldAccess() {
83.221 - return preferences.getBoolean(qualifyFieldAccess, getDefaultAsBoolean(qualifyFieldAccess));
83.222 - }
83.223 -
83.224 - public boolean useIsForBooleanGetters() {
83.225 - return preferences.getBoolean(useIsForBooleanGetters, getDefaultAsBoolean(useIsForBooleanGetters));
83.226 - }
83.227 -
83.228 - public boolean addOverrideAnnotation() {
83.229 - return preferences.getBoolean(addOverrideAnnotation, getDefaultAsBoolean(addOverrideAnnotation));
83.230 - }
83.231 -
83.232 - public boolean makeLocalVarsFinal() {
83.233 - return preferences.getBoolean(makeLocalVarsFinal, getDefaultAsBoolean(makeLocalVarsFinal));
83.234 - }
83.235 -
83.236 - // Alignment ----------------------------------------------------
83.237 -
83.238 - public boolean alignMultilineMethodParams() {
83.239 - return preferences.getBoolean(alignMultilineMethodParams, getDefaultAsBoolean(alignMultilineMethodParams));
83.240 - }
83.241 -
83.242 - public boolean alignMultilineCallArgs() {
83.243 - return preferences.getBoolean(alignMultilineCallArgs, getDefaultAsBoolean(alignMultilineCallArgs));
83.244 - }
83.245 -
83.246 - public boolean alignMultilineAnnotationArgs() {
83.247 - return preferences.getBoolean(alignMultilineAnnotationArgs, getDefaultAsBoolean(alignMultilineAnnotationArgs));
83.248 - }
83.249 -
83.250 - public boolean alignMultilineImplements() {
83.251 - return preferences.getBoolean(alignMultilineImplements, getDefaultAsBoolean(alignMultilineImplements));
83.252 - }
83.253 -
83.254 - public boolean alignMultilineThrows() {
83.255 - return preferences.getBoolean(alignMultilineThrows, getDefaultAsBoolean(alignMultilineThrows));
83.256 - }
83.257 -
83.258 - public boolean alignMultilineParenthesized() {
83.259 - return preferences.getBoolean(alignMultilineParenthesized, getDefaultAsBoolean(alignMultilineParenthesized));
83.260 - }
83.261 -
83.262 - public boolean alignMultilineBinaryOp() {
83.263 - return preferences.getBoolean(alignMultilineBinaryOp, getDefaultAsBoolean(alignMultilineBinaryOp));
83.264 - }
83.265 -
83.266 - public boolean alignMultilineTernaryOp() {
83.267 - return preferences.getBoolean(alignMultilineTernaryOp, getDefaultAsBoolean(alignMultilineTernaryOp));
83.268 - }
83.269 -
83.270 - public boolean alignMultilineAssignment() {
83.271 - return preferences.getBoolean(alignMultilineAssignment, getDefaultAsBoolean(alignMultilineAssignment));
83.272 - }
83.273 -
83.274 - public boolean alignMultilineFor() {
83.275 - return preferences.getBoolean(alignMultilineFor, getDefaultAsBoolean(alignMultilineFor));
83.276 - }
83.277 -
83.278 - public boolean alignMultilineArrayInit() {
83.279 - return preferences.getBoolean(alignMultilineArrayInit, getDefaultAsBoolean(alignMultilineArrayInit));
83.280 - }
83.281 -
83.282 - public boolean placeElseOnNewLine() {
83.283 - return preferences.getBoolean(placeElseOnNewLine, getDefaultAsBoolean(placeElseOnNewLine));
83.284 - }
83.285 -
83.286 - public boolean placeWhileOnNewLine() {
83.287 - return preferences.getBoolean(placeWhileOnNewLine, getDefaultAsBoolean(placeWhileOnNewLine));
83.288 - }
83.289 -
83.290 - public boolean placeCatchOnNewLine() {
83.291 - return preferences.getBoolean(placeCatchOnNewLine, getDefaultAsBoolean(placeCatchOnNewLine));
83.292 - }
83.293 -
83.294 - public boolean placeFinallyOnNewLine() {
83.295 - return preferences.getBoolean(placeFinallyOnNewLine, getDefaultAsBoolean(placeFinallyOnNewLine));
83.296 - }
83.297 -
83.298 - public boolean placeNewLineAfterModifiers() {
83.299 - return preferences.getBoolean(placeNewLineAfterModifiers, getDefaultAsBoolean(placeNewLineAfterModifiers));
83.300 - }
83.301 -
83.302 - // Wrapping ----------------------------------------------------------------
83.303 -
83.304 - public WrapStyle wrapExtendsImplementsKeyword() {
83.305 - String wrap = preferences.get(wrapExtendsImplementsKeyword, getDefaultAsString(wrapExtendsImplementsKeyword));
83.306 - return WrapStyle.valueOf(wrap);
83.307 - }
83.308 -
83.309 - public WrapStyle wrapExtendsImplementsList() {
83.310 - String wrap = preferences.get(wrapExtendsImplementsList, getDefaultAsString(wrapExtendsImplementsList));
83.311 - return WrapStyle.valueOf(wrap);
83.312 - }
83.313 -
83.314 - public WrapStyle wrapMethodParams() {
83.315 - String wrap = preferences.get(wrapMethodParams, getDefaultAsString(wrapMethodParams));
83.316 - return WrapStyle.valueOf(wrap);
83.317 - }
83.318 -
83.319 - public WrapStyle wrapThrowsKeyword() {
83.320 - String wrap = preferences.get(wrapThrowsKeyword, getDefaultAsString(wrapThrowsKeyword));
83.321 - return WrapStyle.valueOf(wrap);
83.322 - }
83.323 -
83.324 - public WrapStyle wrapThrowsList() {
83.325 - String wrap = preferences.get(wrapThrowsList, getDefaultAsString(wrapThrowsList));
83.326 - return WrapStyle.valueOf(wrap);
83.327 - }
83.328 -
83.329 - public WrapStyle wrapMethodCallArgs() {
83.330 - String wrap = preferences.get(wrapMethodCallArgs, getDefaultAsString(wrapMethodCallArgs));
83.331 - return WrapStyle.valueOf(wrap);
83.332 - }
83.333 -
83.334 - public WrapStyle wrapAnnotationArgs() {
83.335 - String wrap = preferences.get(wrapAnnotationArgs, getDefaultAsString(wrapAnnotationArgs));
83.336 - return WrapStyle.valueOf(wrap);
83.337 - }
83.338 -
83.339 - public WrapStyle wrapChainedMethodCalls() {
83.340 - String wrap = preferences.get(wrapChainedMethodCalls, getDefaultAsString(wrapChainedMethodCalls));
83.341 - return WrapStyle.valueOf(wrap);
83.342 - }
83.343 -
83.344 - public WrapStyle wrapArrayInit() {
83.345 - String wrap = preferences.get(wrapArrayInit, getDefaultAsString(wrapArrayInit));
83.346 - return WrapStyle.valueOf(wrap);
83.347 - }
83.348 -
83.349 - public WrapStyle wrapFor() {
83.350 - String wrap = preferences.get(wrapFor, getDefaultAsString(wrapFor));
83.351 - return WrapStyle.valueOf(wrap);
83.352 - }
83.353 -
83.354 - public WrapStyle wrapForStatement() {
83.355 - String wrap = preferences.get(wrapForStatement, getDefaultAsString(wrapForStatement));
83.356 - return WrapStyle.valueOf(wrap);
83.357 - }
83.358 -
83.359 - public WrapStyle wrapIfStatement() {
83.360 - String wrap = preferences.get(wrapIfStatement, getDefaultAsString(wrapIfStatement));
83.361 - return WrapStyle.valueOf(wrap);
83.362 - }
83.363 -
83.364 - public WrapStyle wrapWhileStatement() {
83.365 - String wrap = preferences.get(wrapWhileStatement, getDefaultAsString(wrapWhileStatement));
83.366 - return WrapStyle.valueOf(wrap);
83.367 - }
83.368 -
83.369 - public WrapStyle wrapDoWhileStatement() {
83.370 - String wrap = preferences.get(wrapDoWhileStatement, getDefaultAsString(wrapDoWhileStatement));
83.371 - return WrapStyle.valueOf(wrap);
83.372 - }
83.373 -
83.374 - public WrapStyle wrapAssert() {
83.375 - String wrap = preferences.get(wrapAssert, getDefaultAsString(wrapAssert));
83.376 - return WrapStyle.valueOf(wrap);
83.377 - }
83.378 -
83.379 - public WrapStyle wrapEnumConstants() {
83.380 - String wrap = preferences.get(wrapEnumConstants, getDefaultAsString(wrapEnumConstants));
83.381 - return WrapStyle.valueOf(wrap);
83.382 - }
83.383 -
83.384 - public WrapStyle wrapAnnotations() {
83.385 - String wrap = preferences.get(wrapAnnotations, getDefaultAsString(wrapAnnotations));
83.386 - return WrapStyle.valueOf(wrap);
83.387 - }
83.388 -
83.389 - public WrapStyle wrapBinaryOps() {
83.390 - String wrap = preferences.get(wrapBinaryOps, getDefaultAsString(wrapBinaryOps));
83.391 - return WrapStyle.valueOf(wrap);
83.392 - }
83.393 -
83.394 - public WrapStyle wrapTernaryOps() {
83.395 - String wrap = preferences.get(wrapTernaryOps, getDefaultAsString(wrapTernaryOps));
83.396 - return WrapStyle.valueOf(wrap);
83.397 - }
83.398 -
83.399 - public WrapStyle wrapAssignOps() {
83.400 - String wrap = preferences.get(wrapAssignOps, getDefaultAsString(wrapAssignOps));
83.401 - return WrapStyle.valueOf(wrap);
83.402 - }
83.403 -
83.404 - // Blank lines -------------------------------------------------------------
83.405 -
83.406 - public int getBlankLinesBeforePackage() {
83.407 - return preferences.getInt(blankLinesBeforePackage, getDefaultAsInt(blankLinesBeforePackage));
83.408 - }
83.409 -
83.410 - public int getBlankLinesAfterPackage() {
83.411 - return preferences.getInt(blankLinesAfterPackage, getDefaultAsInt(blankLinesAfterPackage));
83.412 - }
83.413 -
83.414 - public int getBlankLinesBeforeImports() {
83.415 - return preferences.getInt(blankLinesBeforeImports, getDefaultAsInt(blankLinesBeforeImports));
83.416 - }
83.417 -
83.418 - public int getBlankLinesAfterImports() {
83.419 - return preferences.getInt(blankLinesAfterImports, getDefaultAsInt(blankLinesAfterImports));
83.420 - }
83.421 -
83.422 - public int getBlankLinesBeforeClass() {
83.423 - return preferences.getInt(blankLinesBeforeClass, getDefaultAsInt(blankLinesBeforeClass));
83.424 - }
83.425 -
83.426 - public int getBlankLinesAfterClass() {
83.427 - return preferences.getInt(blankLinesAfterClass, getDefaultAsInt(blankLinesAfterClass));
83.428 - }
83.429 -
83.430 - public int getBlankLinesAfterClassHeader() {
83.431 - return preferences.getInt(blankLinesAfterClassHeader, getDefaultAsInt(blankLinesAfterClassHeader));
83.432 - }
83.433 -
83.434 - public int getBlankLinesBeforeFields() {
83.435 - return preferences.getInt(blankLinesBeforeFields, getDefaultAsInt(blankLinesBeforeFields));
83.436 - }
83.437 -
83.438 - public int getBlankLinesAfterFields() {
83.439 - return preferences.getInt(blankLinesAfterFields, getDefaultAsInt(blankLinesAfterFields));
83.440 - }
83.441 -
83.442 - public int getBlankLinesBeforeMethods() {
83.443 - return preferences.getInt(blankLinesBeforeMethods, getDefaultAsInt(blankLinesBeforeMethods));
83.444 - }
83.445 -
83.446 - public int getBlankLinesAfterMethods() {
83.447 - return preferences.getInt(blankLinesAfterMethods, getDefaultAsInt(blankLinesAfterMethods));
83.448 - }
83.449 -
83.450 - // Spaces ------------------------------------------------------------------
83.451 -
83.452 - public boolean spaceBeforeWhile() {
83.453 - return preferences.getBoolean(spaceBeforeWhile, getDefaultAsBoolean(spaceBeforeWhile));
83.454 - }
83.455 -
83.456 - public boolean spaceBeforeElse() {
83.457 - return preferences.getBoolean(spaceBeforeElse, getDefaultAsBoolean(spaceBeforeElse));
83.458 - }
83.459 -
83.460 - public boolean spaceBeforeCatch() {
83.461 - return preferences.getBoolean(spaceBeforeCatch, getDefaultAsBoolean(spaceBeforeCatch));
83.462 - }
83.463 -
83.464 - public boolean spaceBeforeFinally() {
83.465 - return preferences.getBoolean(spaceBeforeFinally, getDefaultAsBoolean(spaceBeforeFinally));
83.466 - }
83.467 -
83.468 - public boolean spaceBeforeMethodDeclParen() {
83.469 - return preferences.getBoolean(spaceBeforeMethodDeclParen, getDefaultAsBoolean(spaceBeforeMethodDeclParen));
83.470 - }
83.471 -
83.472 - public boolean spaceBeforeMethodCallParen() {
83.473 - return preferences.getBoolean(spaceBeforeMethodCallParen, getDefaultAsBoolean(spaceBeforeMethodCallParen));
83.474 - }
83.475 -
83.476 - public boolean spaceBeforeIfParen() {
83.477 - return preferences.getBoolean(spaceBeforeIfParen, getDefaultAsBoolean(spaceBeforeIfParen));
83.478 - }
83.479 -
83.480 - public boolean spaceBeforeForParen() {
83.481 - return preferences.getBoolean(spaceBeforeForParen, getDefaultAsBoolean(spaceBeforeForParen));
83.482 - }
83.483 -
83.484 - public boolean spaceBeforeWhileParen() {
83.485 - return preferences.getBoolean(spaceBeforeWhileParen, getDefaultAsBoolean(spaceBeforeWhileParen));
83.486 - }
83.487 -
83.488 - public boolean spaceBeforeCatchParen() {
83.489 - return preferences.getBoolean(spaceBeforeCatchParen, getDefaultAsBoolean(spaceBeforeCatchParen));
83.490 - }
83.491 -
83.492 - public boolean spaceBeforeSwitchParen() {
83.493 - return preferences.getBoolean(spaceBeforeSwitchParen, getDefaultAsBoolean(spaceBeforeSwitchParen));
83.494 - }
83.495 -
83.496 - public boolean spaceBeforeSynchronizedParen() {
83.497 - return preferences.getBoolean(spaceBeforeSynchronizedParen, getDefaultAsBoolean(spaceBeforeSynchronizedParen));
83.498 - }
83.499 -
83.500 - public boolean spaceBeforeAnnotationParen() {
83.501 - return preferences.getBoolean(spaceBeforeAnnotationParen, getDefaultAsBoolean(spaceBeforeAnnotationParen));
83.502 - }
83.503 -
83.504 - public boolean spaceAroundUnaryOps() {
83.505 - return preferences.getBoolean(spaceAroundUnaryOps, getDefaultAsBoolean(spaceAroundUnaryOps));
83.506 - }
83.507 -
83.508 - public boolean spaceAroundBinaryOps() {
83.509 - return preferences.getBoolean(spaceAroundBinaryOps, getDefaultAsBoolean(spaceAroundBinaryOps));
83.510 - }
83.511 -
83.512 - public boolean spaceAroundTernaryOps() {
83.513 - return preferences.getBoolean(spaceAroundTernaryOps, getDefaultAsBoolean(spaceAroundTernaryOps));
83.514 - }
83.515 -
83.516 - public boolean spaceAroundAssignOps() {
83.517 - return preferences.getBoolean(spaceAroundAssignOps, getDefaultAsBoolean(spaceAroundAssignOps));
83.518 - }
83.519 -
83.520 - public boolean spaceBeforeClassDeclLeftBrace() {
83.521 - return preferences.getBoolean(spaceBeforeClassDeclLeftBrace, getDefaultAsBoolean(spaceBeforeClassDeclLeftBrace));
83.522 - }
83.523 -
83.524 - public boolean spaceBeforeMethodDeclLeftBrace() {
83.525 - return preferences.getBoolean(spaceBeforeMethodDeclLeftBrace, getDefaultAsBoolean(spaceBeforeMethodDeclLeftBrace));
83.526 - }
83.527 -
83.528 - public boolean spaceBeforeIfLeftBrace() {
83.529 - return preferences.getBoolean(spaceBeforeIfLeftBrace, getDefaultAsBoolean(spaceBeforeIfLeftBrace));
83.530 - }
83.531 -
83.532 - public boolean spaceBeforeElseLeftBrace() {
83.533 - return preferences.getBoolean(spaceBeforeElseLeftBrace, getDefaultAsBoolean(spaceBeforeElseLeftBrace));
83.534 - }
83.535 -
83.536 - public boolean spaceBeforeWhileLeftBrace() {
83.537 - return preferences.getBoolean(spaceBeforeWhileLeftBrace, getDefaultAsBoolean(spaceBeforeWhileLeftBrace));
83.538 - }
83.539 -
83.540 - public boolean spaceBeforeForLeftBrace() {
83.541 - return preferences.getBoolean(spaceBeforeForLeftBrace, getDefaultAsBoolean(spaceBeforeForLeftBrace));
83.542 - }
83.543 -
83.544 - public boolean spaceBeforeDoLeftBrace() {
83.545 - return preferences.getBoolean(spaceBeforeDoLeftBrace, getDefaultAsBoolean(spaceBeforeDoLeftBrace));
83.546 - }
83.547 -
83.548 - public boolean spaceBeforeSwitchLeftBrace() {
83.549 - return preferences.getBoolean(spaceBeforeSwitchLeftBrace, getDefaultAsBoolean(spaceBeforeSwitchLeftBrace));
83.550 - }
83.551 -
83.552 - public boolean spaceBeforeTryLeftBrace() {
83.553 - return preferences.getBoolean(spaceBeforeTryLeftBrace, getDefaultAsBoolean(spaceBeforeTryLeftBrace));
83.554 - }
83.555 -
83.556 - public boolean spaceBeforeCatchLeftBrace() {
83.557 - return preferences.getBoolean(spaceBeforeCatchLeftBrace, getDefaultAsBoolean(spaceBeforeCatchLeftBrace));
83.558 - }
83.559 -
83.560 - public boolean spaceBeforeFinallyLeftBrace() {
83.561 - return preferences.getBoolean(spaceBeforeFinallyLeftBrace, getDefaultAsBoolean(spaceBeforeFinallyLeftBrace));
83.562 - }
83.563 -
83.564 - public boolean spaceBeforeSynchronizedLeftBrace() {
83.565 - return preferences.getBoolean(spaceBeforeSynchronizedLeftBrace, getDefaultAsBoolean(spaceBeforeSynchronizedLeftBrace));
83.566 - }
83.567 -
83.568 - public boolean spaceBeforeStaticInitLeftBrace() {
83.569 - return preferences.getBoolean(spaceBeforeStaticInitLeftBrace, getDefaultAsBoolean(spaceBeforeStaticInitLeftBrace));
83.570 - }
83.571 -
83.572 - public boolean spaceBeforeArrayInitLeftBrace() {
83.573 - return preferences.getBoolean(spaceBeforeArrayInitLeftBrace, getDefaultAsBoolean(spaceBeforeArrayInitLeftBrace));
83.574 - }
83.575 -
83.576 - public boolean spaceWithinParens() {
83.577 - return preferences.getBoolean(spaceWithinParens, getDefaultAsBoolean(spaceWithinParens));
83.578 - }
83.579 -
83.580 - public boolean spaceWithinMethodDeclParens() {
83.581 - return preferences.getBoolean(spaceWithinMethodDeclParens, getDefaultAsBoolean(spaceWithinMethodDeclParens));
83.582 - }
83.583 -
83.584 - public boolean spaceWithinMethodCallParens() {
83.585 - return preferences.getBoolean(spaceWithinMethodCallParens, getDefaultAsBoolean(spaceWithinMethodCallParens));
83.586 - }
83.587 -
83.588 - public boolean spaceWithinIfParens() {
83.589 - return preferences.getBoolean(spaceWithinIfParens, getDefaultAsBoolean(spaceWithinIfParens));
83.590 - }
83.591 -
83.592 - public boolean spaceWithinForParens() {
83.593 - return preferences.getBoolean(spaceWithinForParens, getDefaultAsBoolean(spaceWithinForParens));
83.594 - }
83.595 -
83.596 - public boolean spaceWithinWhileParens() {
83.597 - return preferences.getBoolean(spaceWithinWhileParens, getDefaultAsBoolean(spaceWithinWhileParens));
83.598 - }
83.599 -
83.600 - public boolean spaceWithinSwitchParens() {
83.601 - return preferences.getBoolean(spaceWithinSwitchParens, getDefaultAsBoolean(spaceWithinSwitchParens));
83.602 - }
83.603 -
83.604 - public boolean spaceWithinCatchParens() {
83.605 - return preferences.getBoolean(spaceWithinCatchParens, getDefaultAsBoolean(spaceWithinCatchParens));
83.606 - }
83.607 -
83.608 - public boolean spaceWithinSynchronizedParens() {
83.609 - return preferences.getBoolean(spaceWithinSynchronizedParens, getDefaultAsBoolean(spaceWithinSynchronizedParens));
83.610 - }
83.611 -
83.612 - public boolean spaceWithinTypeCastParens() {
83.613 - return preferences.getBoolean(spaceWithinTypeCastParens, getDefaultAsBoolean(spaceWithinTypeCastParens));
83.614 - }
83.615 -
83.616 - public boolean spaceWithinAnnotationParens() {
83.617 - return preferences.getBoolean(spaceWithinAnnotationParens, getDefaultAsBoolean(spaceWithinAnnotationParens));
83.618 - }
83.619 -
83.620 - public boolean spaceWithinBraces() {
83.621 - return preferences.getBoolean(spaceWithinBraces, getDefaultAsBoolean(spaceWithinBraces));
83.622 - }
83.623 -
83.624 - public boolean spaceWithinArrayInitBrackets() {
83.625 - return preferences.getBoolean(spaceWithinArrayInitBrackets, getDefaultAsBoolean(spaceWithinArrayInitBrackets));
83.626 - }
83.627 -
83.628 - public boolean spaceBeforeComma() {
83.629 - return preferences.getBoolean(spaceBeforeComma, getDefaultAsBoolean(spaceBeforeComma));
83.630 - }
83.631 -
83.632 - public boolean spaceAfterComma() {
83.633 - return preferences.getBoolean(spaceAfterComma, getDefaultAsBoolean(spaceAfterComma));
83.634 - }
83.635 -
83.636 - public boolean spaceBeforeSemi() {
83.637 - return preferences.getBoolean(spaceBeforeSemi, getDefaultAsBoolean(spaceBeforeSemi));
83.638 - }
83.639 -
83.640 - public boolean spaceAfterSemi() {
83.641 - return preferences.getBoolean(spaceAfterSemi, getDefaultAsBoolean(spaceAfterSemi));
83.642 - }
83.643 -
83.644 - public boolean spaceBeforeColon() {
83.645 - return preferences.getBoolean(spaceBeforeColon, getDefaultAsBoolean(spaceBeforeColon));
83.646 - }
83.647 -
83.648 - public boolean spaceAfterColon() {
83.649 - return preferences.getBoolean(spaceAfterColon, getDefaultAsBoolean(spaceAfterColon));
83.650 - }
83.651 -
83.652 - public boolean spaceAfterTypeCast() {
83.653 - return preferences.getBoolean(spaceAfterTypeCast, getDefaultAsBoolean(spaceAfterTypeCast));
83.654 - }
83.655 -
83.656 - */
83.657 - // Spaces -----------------------------------------------------------------
83.658 - public boolean addSpaceAroundOperators() {
83.659 - return preferences.getBoolean(addSpaceAroundOperators, getDefaultAsBoolean(addSpaceAroundOperators));
83.660 - }
83.661 -
83.662 - public boolean removeSpaceInsideParens() {
83.663 - return preferences.getBoolean(removeSpaceInParens, getDefaultAsBoolean(removeSpaceInParens));
83.664 - }
83.665 -
83.666 - public boolean addSpaceAfterComma() {
83.667 - return preferences.getBoolean(addSpaceAfterComma, getDefaultAsBoolean(addSpaceAfterComma));
83.668 - }
83.669 -
83.670 - public boolean removeSpaceBeforeSep() {
83.671 - return preferences.getBoolean(removeSpaceBeforeSep, getDefaultAsBoolean(removeSpaceBeforeSep));
83.672 - }
83.673 -
83.674 - public boolean removeSpaceInParamAssign() {
83.675 - return preferences.getBoolean(removeSpaceInParamAssign, getDefaultAsBoolean(removeSpaceInParamAssign));
83.676 - }
83.677 -
83.678 - public boolean collapseSpaces() {
83.679 - return preferences.getBoolean(collapseSpaces, getDefaultAsBoolean(collapseSpaces));
83.680 - }
83.681 -
83.682 - // Imports -----------------------------------------------------------------
83.683 - public boolean formatImports() {
83.684 - return preferences.getBoolean(formatImports, getDefaultAsBoolean(formatImports));
83.685 - }
83.686 -
83.687 - public boolean oneImportPerLine() {
83.688 - return preferences.getBoolean(oneImportPerLine, getDefaultAsBoolean(oneImportPerLine));
83.689 - }
83.690 -
83.691 - public boolean removeDuplicates() {
83.692 - return preferences.getBoolean(removeDuplicates, getDefaultAsBoolean(removeDuplicates));
83.693 - }
83.694 -
83.695 - public boolean systemLibsFirst() {
83.696 - return preferences.getBoolean(systemLibsFirst, getDefaultAsBoolean(systemLibsFirst));
83.697 - }
83.698 -
83.699 - public boolean preferSymbolImports() {
83.700 - return preferences.getBoolean(preferSymbolImports, getDefaultAsBoolean(preferSymbolImports));
83.701 - }
83.702 -
83.703 - public boolean sortImports() {
83.704 - return preferences.getBoolean(sortImports, getDefaultAsBoolean(sortImports));
83.705 - }
83.706 -
83.707 - public boolean separateFromImps() {
83.708 - return preferences.getBoolean(separateFromImps, getDefaultAsBoolean(separateFromImps));
83.709 - }
83.710 -
83.711 - public ImportCleanupStyle cleanupImports() {
83.712 - String cleanup = preferences.get(cleanupUnusedImports, getDefaultAsString(cleanupUnusedImports));
83.713 - return ImportCleanupStyle.valueOf(cleanup);
83.714 - }
83.715 -
83.716 - public String[] getPackagesForStarImport() {
83.717 - return null;
83.718 - }
83.719 -
83.720 - // Nested classes ----------------------------------------------------------
83.721 - public enum WrapStyle {
83.722 - WRAP_ALWAYS,
83.723 - WRAP_IF_LONG,
83.724 - WRAP_NEVER
83.725 - }
83.726 -
83.727 - public enum ImportCleanupStyle {
83.728 - LEAVE_ALONE,
83.729 - COMMENT_OUT,
83.730 - DELETE
83.731 - }
83.732 -
83.733 - // Communication with non public packages ----------------------------------
83.734 - private static class Producer implements FmtOptions.CodeStyleProducer {
83.735 - @Override
83.736 - public CodeStyle create(Preferences preferences) {
83.737 - return new CodeStyle(preferences);
83.738 - }
83.739 - }
83.740 -}
84.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtAlignment.form Fri Sep 18 16:20:24 2015 -0500
84.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
84.3 @@ -1,350 +0,0 @@
84.4 -<?xml version="1.0" encoding="UTF-8" ?>
84.5 -
84.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
84.7 - <Properties>
84.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Alignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.10 - </Property>
84.11 - <Property name="opaque" type="boolean" value="false"/>
84.12 - </Properties>
84.13 - <AuxValues>
84.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
84.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
84.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
84.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
84.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
84.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
84.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
84.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
84.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
84.23 - </AuxValues>
84.24 -
84.25 - <Layout>
84.26 - <DimensionLayout dim="0">
84.27 - <Group type="103" groupAlignment="0" attributes="0">
84.28 - <Group type="102" attributes="0">
84.29 - <Group type="103" groupAlignment="0" attributes="0">
84.30 - <Group type="102" alignment="0" attributes="0">
84.31 - <EmptySpace min="-2" max="-2" attributes="0"/>
84.32 - <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
84.33 - </Group>
84.34 - <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
84.35 - <Group type="102" alignment="0" attributes="1">
84.36 - <Component id="newLinesLabel" min="-2" max="-2" attributes="0"/>
84.37 - <EmptySpace max="-2" attributes="0"/>
84.38 - <Component id="jSeparator1" max="32767" attributes="0"/>
84.39 - </Group>
84.40 - <Group type="102" alignment="0" attributes="1">
84.41 - <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
84.42 - <EmptySpace max="-2" attributes="0"/>
84.43 - <Component id="jSeparator2" max="32767" attributes="1"/>
84.44 - </Group>
84.45 - <Group type="102" alignment="0" attributes="0">
84.46 - <EmptySpace max="-2" attributes="0"/>
84.47 - <Group type="103" groupAlignment="0" attributes="0">
84.48 - <Component id="amThrowsCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
84.49 - <Component id="amBinaryOpCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
84.50 - <Component id="amAssignCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
84.51 - <Component id="amAnnotationArgsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
84.52 - <Component id="nlElseCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
84.53 - <Component id="nlWhileCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
84.54 - <Component id="nlCatchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
84.55 - <Component id="amMethodParamsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
84.56 - </Group>
84.57 - <EmptySpace min="-2" max="-2" attributes="0"/>
84.58 - <Group type="103" groupAlignment="0" attributes="0">
84.59 - <Component id="amCallArgsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
84.60 - <Component id="nlModifiersCheckBox" min="-2" max="-2" attributes="0"/>
84.61 - <Component id="nlFinallyCheckBox" min="-2" max="-2" attributes="0"/>
84.62 - <Component id="amImplementsCheckBox1" min="-2" max="-2" attributes="0"/>
84.63 - <Component id="amArrayInitCheckBox1" min="-2" max="-2" attributes="0"/>
84.64 - <Component id="amTernaryOpCheckBox1" min="-2" max="-2" attributes="0"/>
84.65 - <Component id="amForCheckBox1" min="-2" max="-2" attributes="0"/>
84.66 - </Group>
84.67 - </Group>
84.68 - </Group>
84.69 - </Group>
84.70 - <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
84.71 - </Group>
84.72 - </Group>
84.73 - </DimensionLayout>
84.74 - <DimensionLayout dim="1">
84.75 - <Group type="103" groupAlignment="0" attributes="0">
84.76 - <Group type="102" alignment="0" attributes="0">
84.77 - <Group type="103" groupAlignment="0" attributes="0">
84.78 - <Group type="102" attributes="0">
84.79 - <EmptySpace max="-2" attributes="0"/>
84.80 - <Component id="newLinesLabel" min="-2" max="-2" attributes="1"/>
84.81 - </Group>
84.82 - <Group type="102" attributes="0">
84.83 - <EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
84.84 - <Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
84.85 - </Group>
84.86 - </Group>
84.87 - <EmptySpace max="-2" attributes="0"/>
84.88 - <Group type="103" groupAlignment="3" attributes="0">
84.89 - <Component id="nlElseCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.90 - <Component id="nlFinallyCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.91 - </Group>
84.92 - <EmptySpace max="-2" attributes="0"/>
84.93 - <Group type="103" groupAlignment="3" attributes="0">
84.94 - <Component id="nlWhileCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.95 - <Component id="nlModifiersCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.96 - </Group>
84.97 - <Group type="103" groupAlignment="0" attributes="0">
84.98 - <Group type="102" attributes="0">
84.99 - <EmptySpace max="-2" attributes="0"/>
84.100 - <Component id="nlCatchCheckBox" min="-2" max="-2" attributes="0"/>
84.101 - <EmptySpace type="separate" max="-2" attributes="0"/>
84.102 - <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
84.103 - </Group>
84.104 - <Group type="102" attributes="0">
84.105 - <EmptySpace min="-2" pref="44" max="-2" attributes="0"/>
84.106 - <Component id="jSeparator2" min="-2" pref="10" max="-2" attributes="0"/>
84.107 - </Group>
84.108 - </Group>
84.109 - <EmptySpace min="-2" max="-2" attributes="0"/>
84.110 - <Group type="103" groupAlignment="3" attributes="0">
84.111 - <Component id="amMethodParamsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.112 - <Component id="amCallArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.113 - </Group>
84.114 - <EmptySpace min="-2" max="-2" attributes="0"/>
84.115 - <Group type="103" groupAlignment="3" attributes="0">
84.116 - <Component id="amAnnotationArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
84.117 - <Component id="amImplementsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.118 - </Group>
84.119 - <EmptySpace max="-2" attributes="0"/>
84.120 - <Group type="103" groupAlignment="3" attributes="0">
84.121 - <Component id="amThrowsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.122 - <Component id="amArrayInitCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.123 - </Group>
84.124 - <EmptySpace max="-2" attributes="0"/>
84.125 - <Group type="103" groupAlignment="3" attributes="0">
84.126 - <Component id="amBinaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.127 - <Component id="amTernaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.128 - </Group>
84.129 - <EmptySpace max="-2" attributes="0"/>
84.130 - <Group type="103" groupAlignment="3" attributes="0">
84.131 - <Component id="amAssignCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.132 - <Component id="amForCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
84.133 - </Group>
84.134 - <EmptySpace min="-2" max="-2" attributes="0"/>
84.135 - <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
84.136 - <EmptySpace max="32767" attributes="0"/>
84.137 - </Group>
84.138 - </Group>
84.139 - </DimensionLayout>
84.140 - </Layout>
84.141 - <SubComponents>
84.142 - <Component class="javax.swing.JLabel" name="newLinesLabel">
84.143 - <Properties>
84.144 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.145 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_newLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.146 - </Property>
84.147 - </Properties>
84.148 - </Component>
84.149 - <Component class="javax.swing.JCheckBox" name="nlElseCheckBox">
84.150 - <Properties>
84.151 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.152 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Else" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.153 - </Property>
84.154 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.155 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.156 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.157 - </Border>
84.158 - </Property>
84.159 - </Properties>
84.160 - </Component>
84.161 - <Component class="javax.swing.JCheckBox" name="nlWhileCheckBox">
84.162 - <Properties>
84.163 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.164 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_While" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.165 - </Property>
84.166 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.167 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.168 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.169 - </Border>
84.170 - </Property>
84.171 - </Properties>
84.172 - </Component>
84.173 - <Component class="javax.swing.JCheckBox" name="nlCatchCheckBox">
84.174 - <Properties>
84.175 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.176 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Catch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.177 - </Property>
84.178 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.179 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.180 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.181 - </Border>
84.182 - </Property>
84.183 - </Properties>
84.184 - </Component>
84.185 - <Component class="javax.swing.JCheckBox" name="nlFinallyCheckBox">
84.186 - <Properties>
84.187 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.188 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Finally" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.189 - </Property>
84.190 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.191 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.192 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.193 - </Border>
84.194 - </Property>
84.195 - </Properties>
84.196 - </Component>
84.197 - <Component class="javax.swing.JCheckBox" name="nlModifiersCheckBox">
84.198 - <Properties>
84.199 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.200 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Modifiers" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.201 - </Property>
84.202 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.203 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.204 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.205 - </Border>
84.206 - </Property>
84.207 - </Properties>
84.208 - </Component>
84.209 - <Component class="javax.swing.JLabel" name="multilineAlignmentLabel">
84.210 - <Properties>
84.211 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.212 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_multilineAlignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.213 - </Property>
84.214 - </Properties>
84.215 - </Component>
84.216 - <Component class="javax.swing.JCheckBox" name="amMethodParamsCheckBox">
84.217 - <Properties>
84.218 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.219 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_MethodParams" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.220 - </Property>
84.221 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.222 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.223 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.224 - </Border>
84.225 - </Property>
84.226 - </Properties>
84.227 - </Component>
84.228 - <Component class="javax.swing.JCheckBox" name="amCallArgsCheckBox">
84.229 - <Properties>
84.230 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.231 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_CallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.232 - </Property>
84.233 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.234 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.235 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.236 - </Border>
84.237 - </Property>
84.238 - </Properties>
84.239 - </Component>
84.240 - <Component class="javax.swing.JCheckBox" name="amAnnotationArgsCheckBox">
84.241 - <Properties>
84.242 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.243 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_AnnotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.244 - </Property>
84.245 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.246 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.247 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.248 - </Border>
84.249 - </Property>
84.250 - </Properties>
84.251 - </Component>
84.252 - <Component class="javax.swing.JCheckBox" name="amImplementsCheckBox1">
84.253 - <Properties>
84.254 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.255 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_an_Implements" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.256 - </Property>
84.257 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.258 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.259 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.260 - </Border>
84.261 - </Property>
84.262 - </Properties>
84.263 - </Component>
84.264 - <Component class="javax.swing.JCheckBox" name="amThrowsCheckBox1">
84.265 - <Properties>
84.266 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.267 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Throws" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.268 - </Property>
84.269 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.270 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.271 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.272 - </Border>
84.273 - </Property>
84.274 - </Properties>
84.275 - </Component>
84.276 - <Component class="javax.swing.JCheckBox" name="amArrayInitCheckBox1">
84.277 - <Properties>
84.278 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.279 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_ArrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.280 - </Property>
84.281 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.282 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.283 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.284 - </Border>
84.285 - </Property>
84.286 - </Properties>
84.287 - </Component>
84.288 - <Component class="javax.swing.JCheckBox" name="amBinaryOpCheckBox1">
84.289 - <Properties>
84.290 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.291 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_BinaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.292 - </Property>
84.293 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.294 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.295 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.296 - </Border>
84.297 - </Property>
84.298 - </Properties>
84.299 - </Component>
84.300 - <Component class="javax.swing.JCheckBox" name="amTernaryOpCheckBox1">
84.301 - <Properties>
84.302 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.303 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_TernaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.304 - </Property>
84.305 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.306 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.307 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.308 - </Border>
84.309 - </Property>
84.310 - </Properties>
84.311 - </Component>
84.312 - <Component class="javax.swing.JCheckBox" name="amAssignCheckBox1">
84.313 - <Properties>
84.314 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.315 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Assign" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.316 - </Property>
84.317 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.318 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.319 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.320 - </Border>
84.321 - </Property>
84.322 - </Properties>
84.323 - </Component>
84.324 - <Component class="javax.swing.JCheckBox" name="amForCheckBox1">
84.325 - <Properties>
84.326 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.327 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_For" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.328 - </Property>
84.329 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.330 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.331 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.332 - </Border>
84.333 - </Property>
84.334 - </Properties>
84.335 - </Component>
84.336 - <Component class="javax.swing.JCheckBox" name="amParenthesizedCheckBox1">
84.337 - <Properties>
84.338 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
84.339 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Paren" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
84.340 - </Property>
84.341 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
84.342 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
84.343 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
84.344 - </Border>
84.345 - </Property>
84.346 - </Properties>
84.347 - </Component>
84.348 - <Component class="javax.swing.JSeparator" name="jSeparator1">
84.349 - </Component>
84.350 - <Component class="javax.swing.JSeparator" name="jSeparator2">
84.351 - </Component>
84.352 - </SubComponents>
84.353 -</Form>
85.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtAlignment.java Fri Sep 18 16:20:24 2015 -0500
85.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
85.3 @@ -1,309 +0,0 @@
85.4 -/*
85.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
85.6 - *
85.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
85.8 - *
85.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
85.10 - * Other names may be trademarks of their respective owners.
85.11 - *
85.12 - * The contents of this file are subject to the terms of either the GNU
85.13 - * General Public License Version 2 only ("GPL") or the Common
85.14 - * Development and Distribution License("CDDL") (collectively, the
85.15 - * "License"). You may not use this file except in compliance with the
85.16 - * License. You can obtain a copy of the License at
85.17 - * http://www.netbeans.org/cddl-gplv2.html
85.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
85.19 - * specific language governing permissions and limitations under the
85.20 - * License. When distributing the software, include this License Header
85.21 - * Notice in each file and include the License file at
85.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
85.23 - * particular file as subject to the "Classpath" exception as provided
85.24 - * by Oracle in the GPL Version 2 section of the License file that
85.25 - * accompanied this code. If applicable, add the following below the
85.26 - * License Header, with the fields enclosed by brackets [] replaced by
85.27 - * your own identifying information:
85.28 - * "Portions Copyrighted [year] [name of copyright owner]"
85.29 - *
85.30 - * Contributor(s):
85.31 - *
85.32 - * The Original Software is NetBeans. The Initial Developer of the Original
85.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
85.34 - * Microsystems, Inc. All Rights Reserved.
85.35 - *
85.36 - * If you wish your version of this file to be governed by only the CDDL
85.37 - * or only the GPL Version 2, indicate your decision by adding
85.38 - * "[Contributor] elects to include this software in this distribution
85.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
85.40 - * single choice of license, a recipient has the option to distribute
85.41 - * your version of this file under either the CDDL, the GPL Version 2 or
85.42 - * to extend the choice of license to its licensees as provided above.
85.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
85.44 - * Version 2 license, then the option applies only if the new code is
85.45 - * made subject to such option by the copyright holder.
85.46 - */
85.47 -
85.48 -package org.netbeans.modules.python.editor.options;
85.49 -
85.50 -import org.netbeans.modules.python.editor.options.CodeStyle.WrapStyle;
85.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
85.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
85.53 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
85.54 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
85.55 -
85.56 -
85.57 -/**
85.58 - *
85.59 - * @author phrebejk
85.60 - */
85.61 -public class FmtAlignment extends javax.swing.JPanel {
85.62 -
85.63 - /** Creates new form FmtAlignment */
85.64 - public FmtAlignment() {
85.65 - initComponents();
85.66 -/*
85.67 - nlElseCheckBox.putClientProperty(OPTION_ID, placeElseOnNewLine);
85.68 - nlWhileCheckBox.putClientProperty(OPTION_ID, placeWhileOnNewLine);
85.69 - nlCatchCheckBox.putClientProperty(OPTION_ID, placeCatchOnNewLine);
85.70 - nlFinallyCheckBox.putClientProperty(OPTION_ID, placeFinallyOnNewLine);
85.71 - nlModifiersCheckBox.putClientProperty(OPTION_ID, placeNewLineAfterModifiers);
85.72 - amMethodParamsCheckBox.putClientProperty(OPTION_ID, alignMultilineMethodParams);
85.73 - amCallArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineCallArgs);
85.74 - amAnnotationArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineAnnotationArgs);
85.75 - amArrayInitCheckBox1.putClientProperty(OPTION_ID, alignMultilineArrayInit);
85.76 - amAssignCheckBox1.putClientProperty(OPTION_ID, alignMultilineAssignment);
85.77 - amBinaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineBinaryOp);
85.78 - amForCheckBox1.putClientProperty(OPTION_ID, alignMultilineFor);
85.79 - amImplementsCheckBox1.putClientProperty(OPTION_ID, alignMultilineImplements);
85.80 - amParenthesizedCheckBox1.putClientProperty(OPTION_ID, alignMultilineParenthesized);
85.81 - amTernaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineTernaryOp);
85.82 - amThrowsCheckBox1.putClientProperty(OPTION_ID, alignMultilineThrows);
85.83 - }
85.84 -
85.85 - public static PreferencesCustomizer.Factory getController() {
85.86 - return new CategorySupport.Factory("alignment", FmtAlignment.class, //NOI18N
85.87 - org.openide.util.NbBundle.getMessage(FmtAlignment.class, "SAMPLE_AlignBraces"), // NOI18N
85.88 - new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
85.89 - new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
85.90 - new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
85.91 - new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
85.92 - new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
85.93 - new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
85.94 - new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
85.95 - new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
85.96 - new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
85.97 - new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
85.98 - new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
85.99 - new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
85.100 - new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
85.101 - new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
85.102 - new String[] { FmtOptions.wrapAnnotationArgs, WrapStyle.WRAP_ALWAYS.name() },
85.103 - new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
85.104 - new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
85.105 - new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
85.106 - new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
85.107 - new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() } );
85.108 - */
85.109 - }
85.110 -
85.111 - /** This method is called from within the constructor to
85.112 - * initialize the form.
85.113 - * WARNING: Do NOT modify this code. The content of this method is
85.114 - * always regenerated by the Form Editor.
85.115 - */
85.116 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
85.117 - private void initComponents() {
85.118 -
85.119 - newLinesLabel = new javax.swing.JLabel();
85.120 - nlElseCheckBox = new javax.swing.JCheckBox();
85.121 - nlWhileCheckBox = new javax.swing.JCheckBox();
85.122 - nlCatchCheckBox = new javax.swing.JCheckBox();
85.123 - nlFinallyCheckBox = new javax.swing.JCheckBox();
85.124 - nlModifiersCheckBox = new javax.swing.JCheckBox();
85.125 - multilineAlignmentLabel = new javax.swing.JLabel();
85.126 - amMethodParamsCheckBox = new javax.swing.JCheckBox();
85.127 - amCallArgsCheckBox = new javax.swing.JCheckBox();
85.128 - amAnnotationArgsCheckBox = new javax.swing.JCheckBox();
85.129 - amImplementsCheckBox1 = new javax.swing.JCheckBox();
85.130 - amThrowsCheckBox1 = new javax.swing.JCheckBox();
85.131 - amArrayInitCheckBox1 = new javax.swing.JCheckBox();
85.132 - amBinaryOpCheckBox1 = new javax.swing.JCheckBox();
85.133 - amTernaryOpCheckBox1 = new javax.swing.JCheckBox();
85.134 - amAssignCheckBox1 = new javax.swing.JCheckBox();
85.135 - amForCheckBox1 = new javax.swing.JCheckBox();
85.136 - amParenthesizedCheckBox1 = new javax.swing.JCheckBox();
85.137 - jSeparator1 = new javax.swing.JSeparator();
85.138 - jSeparator2 = new javax.swing.JSeparator();
85.139 -
85.140 - setName(org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_Alignment")); // NOI18N
85.141 - setOpaque(false);
85.142 -
85.143 - org.openide.awt.Mnemonics.setLocalizedText(newLinesLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_newLines")); // NOI18N
85.144 -
85.145 - org.openide.awt.Mnemonics.setLocalizedText(nlElseCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Else")); // NOI18N
85.146 - nlElseCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.147 -
85.148 - org.openide.awt.Mnemonics.setLocalizedText(nlWhileCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_While")); // NOI18N
85.149 - nlWhileCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.150 -
85.151 - org.openide.awt.Mnemonics.setLocalizedText(nlCatchCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Catch")); // NOI18N
85.152 - nlCatchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.153 -
85.154 - org.openide.awt.Mnemonics.setLocalizedText(nlFinallyCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Finally")); // NOI18N
85.155 - nlFinallyCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.156 -
85.157 - org.openide.awt.Mnemonics.setLocalizedText(nlModifiersCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Modifiers")); // NOI18N
85.158 - nlModifiersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.159 -
85.160 - org.openide.awt.Mnemonics.setLocalizedText(multilineAlignmentLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_multilineAlignment")); // NOI18N
85.161 -
85.162 - org.openide.awt.Mnemonics.setLocalizedText(amMethodParamsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_MethodParams")); // NOI18N
85.163 - amMethodParamsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.164 -
85.165 - org.openide.awt.Mnemonics.setLocalizedText(amCallArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_CallArgs")); // NOI18N
85.166 - amCallArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.167 -
85.168 - org.openide.awt.Mnemonics.setLocalizedText(amAnnotationArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_AnnotationArgs")); // NOI18N
85.169 - amAnnotationArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.170 -
85.171 - org.openide.awt.Mnemonics.setLocalizedText(amImplementsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_an_Implements")); // NOI18N
85.172 - amImplementsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.173 -
85.174 - org.openide.awt.Mnemonics.setLocalizedText(amThrowsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Throws")); // NOI18N
85.175 - amThrowsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.176 -
85.177 - org.openide.awt.Mnemonics.setLocalizedText(amArrayInitCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_ArrayInit")); // NOI18N
85.178 - amArrayInitCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.179 -
85.180 - org.openide.awt.Mnemonics.setLocalizedText(amBinaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_BinaryOp")); // NOI18N
85.181 - amBinaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.182 -
85.183 - org.openide.awt.Mnemonics.setLocalizedText(amTernaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_TernaryOp")); // NOI18N
85.184 - amTernaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.185 -
85.186 - org.openide.awt.Mnemonics.setLocalizedText(amAssignCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Assign")); // NOI18N
85.187 - amAssignCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.188 -
85.189 - org.openide.awt.Mnemonics.setLocalizedText(amForCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_For")); // NOI18N
85.190 - amForCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.191 -
85.192 - org.openide.awt.Mnemonics.setLocalizedText(amParenthesizedCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Paren")); // NOI18N
85.193 - amParenthesizedCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
85.194 -
85.195 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
85.196 - this.setLayout(layout);
85.197 - layout.setHorizontalGroup(
85.198 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.199 - .addGroup(layout.createSequentialGroup()
85.200 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.201 - .addGroup(layout.createSequentialGroup()
85.202 - .addContainerGap()
85.203 - .addComponent(amParenthesizedCheckBox1))
85.204 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
85.205 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
85.206 - .addComponent(newLinesLabel)
85.207 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.208 - .addComponent(jSeparator1))
85.209 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
85.210 - .addComponent(multilineAlignmentLabel)
85.211 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.212 - .addComponent(jSeparator2))
85.213 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
85.214 - .addContainerGap()
85.215 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.216 - .addComponent(amThrowsCheckBox1)
85.217 - .addComponent(amBinaryOpCheckBox1)
85.218 - .addComponent(amAssignCheckBox1)
85.219 - .addComponent(amAnnotationArgsCheckBox)
85.220 - .addComponent(nlElseCheckBox)
85.221 - .addComponent(nlWhileCheckBox)
85.222 - .addComponent(nlCatchCheckBox)
85.223 - .addComponent(amMethodParamsCheckBox))
85.224 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.225 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.226 - .addComponent(amCallArgsCheckBox)
85.227 - .addComponent(nlModifiersCheckBox)
85.228 - .addComponent(nlFinallyCheckBox)
85.229 - .addComponent(amImplementsCheckBox1)
85.230 - .addComponent(amArrayInitCheckBox1)
85.231 - .addComponent(amTernaryOpCheckBox1)
85.232 - .addComponent(amForCheckBox1)))))
85.233 - .addGap(0, 0, 0))
85.234 - );
85.235 - layout.setVerticalGroup(
85.236 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.237 - .addGroup(layout.createSequentialGroup()
85.238 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.239 - .addGroup(layout.createSequentialGroup()
85.240 - .addContainerGap()
85.241 - .addComponent(newLinesLabel))
85.242 - .addGroup(layout.createSequentialGroup()
85.243 - .addGap(17, 17, 17)
85.244 - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
85.245 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.246 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.247 - .addComponent(nlElseCheckBox)
85.248 - .addComponent(nlFinallyCheckBox))
85.249 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.250 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.251 - .addComponent(nlWhileCheckBox)
85.252 - .addComponent(nlModifiersCheckBox))
85.253 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
85.254 - .addGroup(layout.createSequentialGroup()
85.255 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.256 - .addComponent(nlCatchCheckBox)
85.257 - .addGap(18, 18, 18)
85.258 - .addComponent(multilineAlignmentLabel))
85.259 - .addGroup(layout.createSequentialGroup()
85.260 - .addGap(44, 44, 44)
85.261 - .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
85.262 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.263 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.264 - .addComponent(amMethodParamsCheckBox)
85.265 - .addComponent(amCallArgsCheckBox))
85.266 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.267 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.268 - .addComponent(amAnnotationArgsCheckBox)
85.269 - .addComponent(amImplementsCheckBox1))
85.270 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.271 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.272 - .addComponent(amThrowsCheckBox1)
85.273 - .addComponent(amArrayInitCheckBox1))
85.274 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.275 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.276 - .addComponent(amBinaryOpCheckBox1)
85.277 - .addComponent(amTernaryOpCheckBox1))
85.278 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.279 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
85.280 - .addComponent(amAssignCheckBox1)
85.281 - .addComponent(amForCheckBox1))
85.282 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85.283 - .addComponent(amParenthesizedCheckBox1)
85.284 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
85.285 - );
85.286 - }// </editor-fold>//GEN-END:initComponents
85.287 -
85.288 -
85.289 - // Variables declaration - do not modify//GEN-BEGIN:variables
85.290 - private javax.swing.JCheckBox amAnnotationArgsCheckBox;
85.291 - private javax.swing.JCheckBox amArrayInitCheckBox1;
85.292 - private javax.swing.JCheckBox amAssignCheckBox1;
85.293 - private javax.swing.JCheckBox amBinaryOpCheckBox1;
85.294 - private javax.swing.JCheckBox amCallArgsCheckBox;
85.295 - private javax.swing.JCheckBox amForCheckBox1;
85.296 - private javax.swing.JCheckBox amImplementsCheckBox1;
85.297 - private javax.swing.JCheckBox amMethodParamsCheckBox;
85.298 - private javax.swing.JCheckBox amParenthesizedCheckBox1;
85.299 - private javax.swing.JCheckBox amTernaryOpCheckBox1;
85.300 - private javax.swing.JCheckBox amThrowsCheckBox1;
85.301 - private javax.swing.JSeparator jSeparator1;
85.302 - private javax.swing.JSeparator jSeparator2;
85.303 - private javax.swing.JLabel multilineAlignmentLabel;
85.304 - private javax.swing.JLabel newLinesLabel;
85.305 - private javax.swing.JCheckBox nlCatchCheckBox;
85.306 - private javax.swing.JCheckBox nlElseCheckBox;
85.307 - private javax.swing.JCheckBox nlFinallyCheckBox;
85.308 - private javax.swing.JCheckBox nlModifiersCheckBox;
85.309 - private javax.swing.JCheckBox nlWhileCheckBox;
85.310 - // End of variables declaration//GEN-END:variables
85.311 -
85.312 -}
86.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtBlankLines.form Fri Sep 18 16:20:24 2015 -0500
86.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
86.3 @@ -1,284 +0,0 @@
86.4 -<?xml version="1.0" encoding="UTF-8" ?>
86.5 -
86.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
86.7 - <Properties>
86.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_BlankLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.10 - </Property>
86.11 - <Property name="opaque" type="boolean" value="false"/>
86.12 - </Properties>
86.13 - <AuxValues>
86.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
86.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
86.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
86.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
86.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
86.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
86.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
86.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
86.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
86.23 - </AuxValues>
86.24 -
86.25 - <Layout>
86.26 - <DimensionLayout dim="0">
86.27 - <Group type="103" groupAlignment="0" attributes="0">
86.28 - <Group type="102" attributes="0">
86.29 - <Group type="103" groupAlignment="0" attributes="0">
86.30 - <Component id="bPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.31 - <Component id="aPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.32 - <Component id="bImportsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.33 - <Component id="aImports" alignment="0" min="-2" max="-2" attributes="0"/>
86.34 - <Component id="bClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.35 - <Component id="aClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.36 - <Component id="aClassHeaderLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.37 - <Component id="bFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.38 - <Component id="aFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.39 - <Component id="bMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.40 - <Component id="aMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
86.41 - </Group>
86.42 - <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
86.43 - <Group type="103" groupAlignment="0" attributes="0">
86.44 - <Component id="aMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.45 - <Component id="bMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.46 - <Component id="aFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.47 - <Component id="bFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.48 - <Component id="aClassHeaderField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.49 - <Component id="aClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.50 - <Component id="bClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.51 - <Component id="aImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.52 - <Component id="bImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.53 - <Component id="aPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.54 - <Component id="bPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
86.55 - </Group>
86.56 - </Group>
86.57 - </Group>
86.58 - </DimensionLayout>
86.59 - <DimensionLayout dim="1">
86.60 - <Group type="103" groupAlignment="0" attributes="0">
86.61 - <Group type="102" attributes="0">
86.62 - <Group type="103" groupAlignment="3" attributes="0">
86.63 - <Component id="bPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.64 - <Component id="bPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.65 - </Group>
86.66 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.67 - <Group type="103" groupAlignment="3" attributes="0">
86.68 - <Component id="aPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.69 - <Component id="aPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.70 - </Group>
86.71 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.72 - <Group type="103" groupAlignment="3" attributes="0">
86.73 - <Component id="bImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.74 - <Component id="bImportsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.75 - </Group>
86.76 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.77 - <Group type="103" groupAlignment="3" attributes="0">
86.78 - <Component id="aImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.79 - <Component id="aImports" alignment="3" min="-2" max="-2" attributes="0"/>
86.80 - </Group>
86.81 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.82 - <Group type="103" groupAlignment="3" attributes="0">
86.83 - <Component id="bClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.84 - <Component id="bClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.85 - </Group>
86.86 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.87 - <Group type="103" groupAlignment="3" attributes="0">
86.88 - <Component id="aClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.89 - <Component id="aClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.90 - </Group>
86.91 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.92 - <Group type="103" groupAlignment="3" attributes="0">
86.93 - <Component id="aClassHeaderField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.94 - <Component id="aClassHeaderLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.95 - </Group>
86.96 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.97 - <Group type="103" groupAlignment="3" attributes="0">
86.98 - <Component id="bFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.99 - <Component id="bFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.100 - </Group>
86.101 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.102 - <Group type="103" groupAlignment="3" attributes="0">
86.103 - <Component id="aFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.104 - <Component id="aFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.105 - </Group>
86.106 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.107 - <Group type="103" groupAlignment="3" attributes="0">
86.108 - <Component id="bMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.109 - <Component id="bMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.110 - </Group>
86.111 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
86.112 - <Group type="103" groupAlignment="3" attributes="0">
86.113 - <Component id="aMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
86.114 - <Component id="aMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
86.115 - </Group>
86.116 - </Group>
86.117 - </Group>
86.118 - </DimensionLayout>
86.119 - </Layout>
86.120 - <SubComponents>
86.121 - <Component class="javax.swing.JLabel" name="bPackageLabel">
86.122 - <Properties>
86.123 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.124 - <ComponentRef name="bPackageField"/>
86.125 - </Property>
86.126 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.127 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforePackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.128 - </Property>
86.129 - </Properties>
86.130 - </Component>
86.131 - <Component class="javax.swing.JTextField" name="bPackageField">
86.132 - <Properties>
86.133 - <Property name="columns" type="int" value="5"/>
86.134 - </Properties>
86.135 - </Component>
86.136 - <Component class="javax.swing.JLabel" name="aPackageLabel">
86.137 - <Properties>
86.138 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.139 - <ComponentRef name="aPackageField"/>
86.140 - </Property>
86.141 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.142 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterPackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.143 - </Property>
86.144 - </Properties>
86.145 - </Component>
86.146 - <Component class="javax.swing.JTextField" name="aPackageField">
86.147 - <Properties>
86.148 - <Property name="columns" type="int" value="5"/>
86.149 - </Properties>
86.150 - </Component>
86.151 - <Component class="javax.swing.JLabel" name="bImportsLabel">
86.152 - <Properties>
86.153 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.154 - <ComponentRef name="bImportsField"/>
86.155 - </Property>
86.156 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.157 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.158 - </Property>
86.159 - </Properties>
86.160 - </Component>
86.161 - <Component class="javax.swing.JTextField" name="bImportsField">
86.162 - <Properties>
86.163 - <Property name="columns" type="int" value="5"/>
86.164 - </Properties>
86.165 - </Component>
86.166 - <Component class="javax.swing.JLabel" name="aImports">
86.167 - <Properties>
86.168 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.169 - <ComponentRef name="aImportsField"/>
86.170 - </Property>
86.171 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.172 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.173 - </Property>
86.174 - </Properties>
86.175 - </Component>
86.176 - <Component class="javax.swing.JTextField" name="aImportsField">
86.177 - <Properties>
86.178 - <Property name="columns" type="int" value="5"/>
86.179 - </Properties>
86.180 - </Component>
86.181 - <Component class="javax.swing.JLabel" name="bClassLabel">
86.182 - <Properties>
86.183 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.184 - <ComponentRef name="bClassField"/>
86.185 - </Property>
86.186 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.187 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.188 - </Property>
86.189 - </Properties>
86.190 - </Component>
86.191 - <Component class="javax.swing.JTextField" name="bClassField">
86.192 - <Properties>
86.193 - <Property name="columns" type="int" value="5"/>
86.194 - </Properties>
86.195 - </Component>
86.196 - <Component class="javax.swing.JLabel" name="aClassLabel">
86.197 - <Properties>
86.198 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.199 - <ComponentRef name="aClassField"/>
86.200 - </Property>
86.201 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.202 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.203 - </Property>
86.204 - </Properties>
86.205 - </Component>
86.206 - <Component class="javax.swing.JTextField" name="aClassField">
86.207 - <Properties>
86.208 - <Property name="columns" type="int" value="5"/>
86.209 - </Properties>
86.210 - </Component>
86.211 - <Component class="javax.swing.JLabel" name="aClassHeaderLabel">
86.212 - <Properties>
86.213 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.214 - <ComponentRef name="aClassHeaderField"/>
86.215 - </Property>
86.216 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.217 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClassHeader" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.218 - </Property>
86.219 - </Properties>
86.220 - </Component>
86.221 - <Component class="javax.swing.JTextField" name="aClassHeaderField">
86.222 - <Properties>
86.223 - <Property name="columns" type="int" value="5"/>
86.224 - </Properties>
86.225 - </Component>
86.226 - <Component class="javax.swing.JLabel" name="bFieldsLabel">
86.227 - <Properties>
86.228 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.229 - <ComponentRef name="bFieldsField"/>
86.230 - </Property>
86.231 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.232 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.233 - </Property>
86.234 - </Properties>
86.235 - </Component>
86.236 - <Component class="javax.swing.JTextField" name="bFieldsField">
86.237 - <Properties>
86.238 - <Property name="columns" type="int" value="5"/>
86.239 - </Properties>
86.240 - </Component>
86.241 - <Component class="javax.swing.JLabel" name="aFieldsLabel">
86.242 - <Properties>
86.243 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.244 - <ComponentRef name="aFieldsField"/>
86.245 - </Property>
86.246 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.247 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.248 - </Property>
86.249 - </Properties>
86.250 - </Component>
86.251 - <Component class="javax.swing.JTextField" name="aFieldsField">
86.252 - <Properties>
86.253 - <Property name="columns" type="int" value="5"/>
86.254 - </Properties>
86.255 - </Component>
86.256 - <Component class="javax.swing.JLabel" name="bMethodsLabel">
86.257 - <Properties>
86.258 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.259 - <ComponentRef name="bMethodsField"/>
86.260 - </Property>
86.261 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.262 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.263 - </Property>
86.264 - </Properties>
86.265 - </Component>
86.266 - <Component class="javax.swing.JTextField" name="bMethodsField">
86.267 - <Properties>
86.268 - <Property name="columns" type="int" value="5"/>
86.269 - </Properties>
86.270 - </Component>
86.271 - <Component class="javax.swing.JLabel" name="aMethodsLabel">
86.272 - <Properties>
86.273 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
86.274 - <ComponentRef name="aMethodsField"/>
86.275 - </Property>
86.276 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
86.277 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
86.278 - </Property>
86.279 - </Properties>
86.280 - </Component>
86.281 - <Component class="javax.swing.JTextField" name="aMethodsField">
86.282 - <Properties>
86.283 - <Property name="columns" type="int" value="5"/>
86.284 - </Properties>
86.285 - </Component>
86.286 - </SubComponents>
86.287 -</Form>
87.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtBlankLines.java Fri Sep 18 16:20:24 2015 -0500
87.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
87.3 @@ -1,295 +0,0 @@
87.4 -/*
87.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
87.6 - *
87.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
87.8 - *
87.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
87.10 - * Other names may be trademarks of their respective owners.
87.11 - *
87.12 - * The contents of this file are subject to the terms of either the GNU
87.13 - * General Public License Version 2 only ("GPL") or the Common
87.14 - * Development and Distribution License("CDDL") (collectively, the
87.15 - * "License"). You may not use this file except in compliance with the
87.16 - * License. You can obtain a copy of the License at
87.17 - * http://www.netbeans.org/cddl-gplv2.html
87.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
87.19 - * specific language governing permissions and limitations under the
87.20 - * License. When distributing the software, include this License Header
87.21 - * Notice in each file and include the License file at
87.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
87.23 - * particular file as subject to the "Classpath" exception as provided
87.24 - * by Oracle in the GPL Version 2 section of the License file that
87.25 - * accompanied this code. If applicable, add the following below the
87.26 - * License Header, with the fields enclosed by brackets [] replaced by
87.27 - * your own identifying information:
87.28 - * "Portions Copyrighted [year] [name of copyright owner]"
87.29 - *
87.30 - * Contributor(s):
87.31 - *
87.32 - * The Original Software is NetBeans. The Initial Developer of the Original
87.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
87.34 - * Microsystems, Inc. All Rights Reserved.
87.35 - *
87.36 - * If you wish your version of this file to be governed by only the CDDL
87.37 - * or only the GPL Version 2, indicate your decision by adding
87.38 - * "[Contributor] elects to include this software in this distribution
87.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
87.40 - * single choice of license, a recipient has the option to distribute
87.41 - * your version of this file under either the CDDL, the GPL Version 2 or
87.42 - * to extend the choice of license to its licensees as provided above.
87.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
87.44 - * Version 2 license, then the option applies only if the new code is
87.45 - * made subject to such option by the copyright holder.
87.46 - */
87.47 -
87.48 -package org.netbeans.modules.python.editor.options;
87.49 -
87.50 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
87.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
87.52 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
87.53 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
87.54 -
87.55 -/**
87.56 - *
87.57 - * @author phrebejk
87.58 - */
87.59 -public class FmtBlankLines extends javax.swing.JPanel {
87.60 -
87.61 - /** Creates new form FmtBlankLines */
87.62 - public FmtBlankLines() {
87.63 - initComponents();
87.64 -/*
87.65 - bPackageField.putClientProperty(OPTION_ID, blankLinesBeforePackage );
87.66 - aPackageField.putClientProperty(OPTION_ID, blankLinesAfterPackage);
87.67 - bImportsField.putClientProperty(OPTION_ID, blankLinesBeforeImports);
87.68 - aImportsField.putClientProperty(OPTION_ID, blankLinesAfterImports);
87.69 - bClassField.putClientProperty(OPTION_ID, blankLinesBeforeClass);
87.70 - aClassField.putClientProperty(OPTION_ID, blankLinesAfterClass);
87.71 - aClassHeaderField.putClientProperty(OPTION_ID, blankLinesAfterClassHeader);
87.72 - bFieldsField.putClientProperty(OPTION_ID, blankLinesBeforeFields);
87.73 - aFieldsField.putClientProperty(OPTION_ID, blankLinesAfterFields);
87.74 - bMethodsField.putClientProperty(OPTION_ID, blankLinesBeforeMethods );
87.75 - aMethodsField.putClientProperty(OPTION_ID, blankLinesAfterMethods);
87.76 -
87.77 - bPackageField.addKeyListener(new NumericKeyListener());
87.78 - aPackageField.addKeyListener(new NumericKeyListener());
87.79 - bImportsField.addKeyListener(new NumericKeyListener());
87.80 - aImportsField.addKeyListener(new NumericKeyListener());
87.81 - bClassField.addKeyListener(new NumericKeyListener());
87.82 - aClassField.addKeyListener(new NumericKeyListener());
87.83 - aClassHeaderField.addKeyListener(new NumericKeyListener());
87.84 - bFieldsField.addKeyListener(new NumericKeyListener());
87.85 - aFieldsField.addKeyListener(new NumericKeyListener());
87.86 - bMethodsField.addKeyListener(new NumericKeyListener());
87.87 - aMethodsField.addKeyListener(new NumericKeyListener());
87.88 -
87.89 - }
87.90 -
87.91 - public static PreferencesCustomizer.Factory getController() {
87.92 - return new CategorySupport.Factory("blank-lines", FmtBlankLines.class, //NOI18N
87.93 - org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "SAMPLE_BlankLines")); // NOI18N
87.94 - */
87.95 - }
87.96 -
87.97 - /** This method is called from within the constructor to
87.98 - * initialize the form.
87.99 - * WARNING: Do NOT modify this code. The content of this method is
87.100 - * always regenerated by the Form Editor.
87.101 - */
87.102 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
87.103 - private void initComponents() {
87.104 -
87.105 - bPackageLabel = new javax.swing.JLabel();
87.106 - bPackageField = new javax.swing.JTextField();
87.107 - aPackageLabel = new javax.swing.JLabel();
87.108 - aPackageField = new javax.swing.JTextField();
87.109 - bImportsLabel = new javax.swing.JLabel();
87.110 - bImportsField = new javax.swing.JTextField();
87.111 - aImports = new javax.swing.JLabel();
87.112 - aImportsField = new javax.swing.JTextField();
87.113 - bClassLabel = new javax.swing.JLabel();
87.114 - bClassField = new javax.swing.JTextField();
87.115 - aClassLabel = new javax.swing.JLabel();
87.116 - aClassField = new javax.swing.JTextField();
87.117 - aClassHeaderLabel = new javax.swing.JLabel();
87.118 - aClassHeaderField = new javax.swing.JTextField();
87.119 - bFieldsLabel = new javax.swing.JLabel();
87.120 - bFieldsField = new javax.swing.JTextField();
87.121 - aFieldsLabel = new javax.swing.JLabel();
87.122 - aFieldsField = new javax.swing.JTextField();
87.123 - bMethodsLabel = new javax.swing.JLabel();
87.124 - bMethodsField = new javax.swing.JTextField();
87.125 - aMethodsLabel = new javax.swing.JLabel();
87.126 - aMethodsField = new javax.swing.JTextField();
87.127 -
87.128 - setName(org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_BlankLines")); // NOI18N
87.129 - setOpaque(false);
87.130 -
87.131 - bPackageLabel.setLabelFor(bPackageField);
87.132 - org.openide.awt.Mnemonics.setLocalizedText(bPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforePackage")); // NOI18N
87.133 -
87.134 - bPackageField.setColumns(5);
87.135 -
87.136 - aPackageLabel.setLabelFor(aPackageField);
87.137 - org.openide.awt.Mnemonics.setLocalizedText(aPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterPackage")); // NOI18N
87.138 -
87.139 - aPackageField.setColumns(5);
87.140 -
87.141 - bImportsLabel.setLabelFor(bImportsField);
87.142 - org.openide.awt.Mnemonics.setLocalizedText(bImportsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeImports")); // NOI18N
87.143 -
87.144 - bImportsField.setColumns(5);
87.145 -
87.146 - aImports.setLabelFor(aImportsField);
87.147 - org.openide.awt.Mnemonics.setLocalizedText(aImports, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterImports")); // NOI18N
87.148 -
87.149 - aImportsField.setColumns(5);
87.150 -
87.151 - bClassLabel.setLabelFor(bClassField);
87.152 - org.openide.awt.Mnemonics.setLocalizedText(bClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeClass")); // NOI18N
87.153 -
87.154 - bClassField.setColumns(5);
87.155 -
87.156 - aClassLabel.setLabelFor(aClassField);
87.157 - org.openide.awt.Mnemonics.setLocalizedText(aClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClass")); // NOI18N
87.158 -
87.159 - aClassField.setColumns(5);
87.160 -
87.161 - aClassHeaderLabel.setLabelFor(aClassHeaderField);
87.162 - org.openide.awt.Mnemonics.setLocalizedText(aClassHeaderLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClassHeader")); // NOI18N
87.163 -
87.164 - aClassHeaderField.setColumns(5);
87.165 -
87.166 - bFieldsLabel.setLabelFor(bFieldsField);
87.167 - org.openide.awt.Mnemonics.setLocalizedText(bFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeFields")); // NOI18N
87.168 -
87.169 - bFieldsField.setColumns(5);
87.170 -
87.171 - aFieldsLabel.setLabelFor(aFieldsField);
87.172 - org.openide.awt.Mnemonics.setLocalizedText(aFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterFields")); // NOI18N
87.173 -
87.174 - aFieldsField.setColumns(5);
87.175 -
87.176 - bMethodsLabel.setLabelFor(bMethodsField);
87.177 - org.openide.awt.Mnemonics.setLocalizedText(bMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeMethods")); // NOI18N
87.178 -
87.179 - bMethodsField.setColumns(5);
87.180 -
87.181 - aMethodsLabel.setLabelFor(aMethodsField);
87.182 - org.openide.awt.Mnemonics.setLocalizedText(aMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterMethods")); // NOI18N
87.183 -
87.184 - aMethodsField.setColumns(5);
87.185 -
87.186 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
87.187 - this.setLayout(layout);
87.188 - layout.setHorizontalGroup(
87.189 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
87.190 - .addGroup(layout.createSequentialGroup()
87.191 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
87.192 - .addComponent(bPackageLabel)
87.193 - .addComponent(aPackageLabel)
87.194 - .addComponent(bImportsLabel)
87.195 - .addComponent(aImports)
87.196 - .addComponent(bClassLabel)
87.197 - .addComponent(aClassLabel)
87.198 - .addComponent(aClassHeaderLabel)
87.199 - .addComponent(bFieldsLabel)
87.200 - .addComponent(aFieldsLabel)
87.201 - .addComponent(bMethodsLabel)
87.202 - .addComponent(aMethodsLabel))
87.203 - .addGap(6, 6, 6)
87.204 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
87.205 - .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.206 - .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.207 - .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.208 - .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.209 - .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.210 - .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.211 - .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.212 - .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.213 - .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.214 - .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.215 - .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
87.216 - );
87.217 -
87.218 - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
87.219 -
87.220 - layout.setVerticalGroup(
87.221 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
87.222 - .addGroup(layout.createSequentialGroup()
87.223 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.224 - .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.225 - .addComponent(bPackageLabel))
87.226 - .addGap(4, 4, 4)
87.227 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.228 - .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.229 - .addComponent(aPackageLabel))
87.230 - .addGap(4, 4, 4)
87.231 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.232 - .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.233 - .addComponent(bImportsLabel))
87.234 - .addGap(4, 4, 4)
87.235 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.236 - .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.237 - .addComponent(aImports))
87.238 - .addGap(4, 4, 4)
87.239 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.240 - .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.241 - .addComponent(bClassLabel))
87.242 - .addGap(4, 4, 4)
87.243 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.244 - .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.245 - .addComponent(aClassLabel))
87.246 - .addGap(4, 4, 4)
87.247 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.248 - .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.249 - .addComponent(aClassHeaderLabel))
87.250 - .addGap(4, 4, 4)
87.251 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.252 - .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.253 - .addComponent(bFieldsLabel))
87.254 - .addGap(4, 4, 4)
87.255 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.256 - .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.257 - .addComponent(aFieldsLabel))
87.258 - .addGap(4, 4, 4)
87.259 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.260 - .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.261 - .addComponent(bMethodsLabel))
87.262 - .addGap(4, 4, 4)
87.263 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
87.264 - .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87.265 - .addComponent(aMethodsLabel)))
87.266 - );
87.267 -
87.268 - layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
87.269 -
87.270 - }// </editor-fold>//GEN-END:initComponents
87.271 -
87.272 -
87.273 - // Variables declaration - do not modify//GEN-BEGIN:variables
87.274 - private javax.swing.JTextField aClassField;
87.275 - private javax.swing.JTextField aClassHeaderField;
87.276 - private javax.swing.JLabel aClassHeaderLabel;
87.277 - private javax.swing.JLabel aClassLabel;
87.278 - private javax.swing.JTextField aFieldsField;
87.279 - private javax.swing.JLabel aFieldsLabel;
87.280 - private javax.swing.JLabel aImports;
87.281 - private javax.swing.JTextField aImportsField;
87.282 - private javax.swing.JTextField aMethodsField;
87.283 - private javax.swing.JLabel aMethodsLabel;
87.284 - private javax.swing.JTextField aPackageField;
87.285 - private javax.swing.JLabel aPackageLabel;
87.286 - private javax.swing.JTextField bClassField;
87.287 - private javax.swing.JLabel bClassLabel;
87.288 - private javax.swing.JTextField bFieldsField;
87.289 - private javax.swing.JLabel bFieldsLabel;
87.290 - private javax.swing.JTextField bImportsField;
87.291 - private javax.swing.JLabel bImportsLabel;
87.292 - private javax.swing.JTextField bMethodsField;
87.293 - private javax.swing.JLabel bMethodsLabel;
87.294 - private javax.swing.JTextField bPackageField;
87.295 - private javax.swing.JLabel bPackageLabel;
87.296 - // End of variables declaration//GEN-END:variables
87.297 -
87.298 -}
88.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtImports.form Fri Sep 18 16:20:24 2015 -0500
88.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
88.3 @@ -1,129 +0,0 @@
88.4 -<?xml version="1.0" encoding="UTF-8" ?>
88.5 -
88.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
88.7 - <Properties>
88.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Imports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.10 - </Property>
88.11 - </Properties>
88.12 - <AuxValues>
88.13 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
88.14 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
88.15 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
88.16 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
88.17 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
88.18 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
88.19 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
88.20 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
88.21 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
88.22 - </AuxValues>
88.23 -
88.24 - <Layout>
88.25 - <DimensionLayout dim="0">
88.26 - <Group type="103" groupAlignment="0" attributes="0">
88.27 - <Group type="102" attributes="0">
88.28 - <Group type="103" groupAlignment="0" attributes="0">
88.29 - <Component id="formatImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
88.30 - <Component id="onePerLineCb" alignment="0" min="-2" max="-2" attributes="0"/>
88.31 - <Component id="systemLibsCb" alignment="0" min="-2" max="-2" attributes="0"/>
88.32 - <Component id="sortImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
88.33 - <Component id="sepFromImpCb" alignment="0" min="-2" max="-2" attributes="0"/>
88.34 - <Component id="removeDuplicateCb" alignment="0" min="-2" max="-2" attributes="0"/>
88.35 - <Component id="preferSymbols" alignment="0" min="-2" max="-2" attributes="0"/>
88.36 - <Group type="102" alignment="0" attributes="0">
88.37 - <Component id="cleanupLabel" min="-2" max="-2" attributes="0"/>
88.38 - <EmptySpace max="-2" attributes="0"/>
88.39 - <Component id="cleanupCombo" min="-2" max="-2" attributes="0"/>
88.40 - </Group>
88.41 - </Group>
88.42 - <EmptySpace max="32767" attributes="0"/>
88.43 - </Group>
88.44 - </Group>
88.45 - </DimensionLayout>
88.46 - <DimensionLayout dim="1">
88.47 - <Group type="103" groupAlignment="0" attributes="0">
88.48 - <Group type="102" alignment="0" attributes="0">
88.49 - <Component id="formatImportsCb" min="-2" max="-2" attributes="0"/>
88.50 - <EmptySpace type="separate" max="-2" attributes="0"/>
88.51 - <Component id="onePerLineCb" min="-2" max="-2" attributes="0"/>
88.52 - <EmptySpace max="-2" attributes="0"/>
88.53 - <Component id="systemLibsCb" min="-2" max="-2" attributes="0"/>
88.54 - <EmptySpace max="-2" attributes="0"/>
88.55 - <Component id="sortImportsCb" min="-2" max="-2" attributes="0"/>
88.56 - <EmptySpace max="-2" attributes="0"/>
88.57 - <Component id="sepFromImpCb" min="-2" max="-2" attributes="0"/>
88.58 - <EmptySpace max="-2" attributes="0"/>
88.59 - <Component id="removeDuplicateCb" min="-2" max="-2" attributes="0"/>
88.60 - <EmptySpace max="-2" attributes="0"/>
88.61 - <Component id="preferSymbols" min="-2" max="-2" attributes="0"/>
88.62 - <EmptySpace type="separate" max="-2" attributes="0"/>
88.63 - <Group type="103" groupAlignment="3" attributes="0">
88.64 - <Component id="cleanupLabel" alignment="3" min="-2" max="-2" attributes="0"/>
88.65 - <Component id="cleanupCombo" alignment="3" min="-2" max="-2" attributes="0"/>
88.66 - </Group>
88.67 - <EmptySpace max="32767" attributes="0"/>
88.68 - </Group>
88.69 - </Group>
88.70 - </DimensionLayout>
88.71 - </Layout>
88.72 - <SubComponents>
88.73 - <Component class="javax.swing.JCheckBox" name="formatImportsCb">
88.74 - <Properties>
88.75 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.76 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.formatImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.77 - </Property>
88.78 - </Properties>
88.79 - </Component>
88.80 - <Component class="javax.swing.JCheckBox" name="onePerLineCb">
88.81 - <Properties>
88.82 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.83 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.onePerLineCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.84 - </Property>
88.85 - </Properties>
88.86 - </Component>
88.87 - <Component class="javax.swing.JCheckBox" name="systemLibsCb">
88.88 - <Properties>
88.89 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.90 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.systemLibsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.91 - </Property>
88.92 - </Properties>
88.93 - </Component>
88.94 - <Component class="javax.swing.JCheckBox" name="removeDuplicateCb">
88.95 - <Properties>
88.96 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.97 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.removeDuplicateCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.98 - </Property>
88.99 - </Properties>
88.100 - </Component>
88.101 - <Component class="javax.swing.JLabel" name="cleanupLabel">
88.102 - <Properties>
88.103 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.104 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.cleanupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.105 - </Property>
88.106 - </Properties>
88.107 - </Component>
88.108 - <Component class="javax.swing.JComboBox" name="cleanupCombo">
88.109 - </Component>
88.110 - <Component class="javax.swing.JCheckBox" name="preferSymbols">
88.111 - <Properties>
88.112 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.113 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.preferSymbols.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.114 - </Property>
88.115 - </Properties>
88.116 - </Component>
88.117 - <Component class="javax.swing.JCheckBox" name="sortImportsCb">
88.118 - <Properties>
88.119 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.120 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sortImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.121 - </Property>
88.122 - </Properties>
88.123 - </Component>
88.124 - <Component class="javax.swing.JCheckBox" name="sepFromImpCb">
88.125 - <Properties>
88.126 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
88.127 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sepFromImpCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
88.128 - </Property>
88.129 - </Properties>
88.130 - </Component>
88.131 - </SubComponents>
88.132 -</Form>
89.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtImports.java Fri Sep 18 16:20:24 2015 -0500
89.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
89.3 @@ -1,169 +0,0 @@
89.4 -/*
89.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
89.6 - *
89.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
89.8 - *
89.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
89.10 - * Other names may be trademarks of their respective owners.
89.11 - *
89.12 - * The contents of this file are subject to the terms of either the GNU
89.13 - * General Public License Version 2 only ("GPL") or the Common
89.14 - * Development and Distribution License("CDDL") (collectively, the
89.15 - * "License"). You may not use this file except in compliance with the
89.16 - * License. You can obtain a copy of the License at
89.17 - * http://www.netbeans.org/cddl-gplv2.html
89.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
89.19 - * specific language governing permissions and limitations under the
89.20 - * License. When distributing the software, include this License Header
89.21 - * Notice in each file and include the License file at
89.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
89.23 - * particular file as subject to the "Classpath" exception as provided
89.24 - * by Oracle in the GPL Version 2 section of the License file that
89.25 - * accompanied this code. If applicable, add the following below the
89.26 - * License Header, with the fields enclosed by brackets [] replaced by
89.27 - * your own identifying information:
89.28 - * "Portions Copyrighted [year] [name of copyright owner]"
89.29 - *
89.30 - * Contributor(s):
89.31 - *
89.32 - * The Original Software is NetBeans. The Initial Developer of the Original
89.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
89.34 - * Microsystems, Inc. All Rights Reserved.
89.35 - *
89.36 - * If you wish your version of this file to be governed by only the CDDL
89.37 - * or only the GPL Version 2, indicate your decision by adding
89.38 - * "[Contributor] elects to include this software in this distribution
89.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
89.40 - * single choice of license, a recipient has the option to distribute
89.41 - * your version of this file under either the CDDL, the GPL Version 2 or
89.42 - * to extend the choice of license to its licensees as provided above.
89.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
89.44 - * Version 2 license, then the option applies only if the new code is
89.45 - * made subject to such option by the copyright holder.
89.46 - */
89.47 -
89.48 -package org.netbeans.modules.python.editor.options;
89.49 -
89.50 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
89.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
89.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
89.53 -
89.54 -/**
89.55 - * Options related to imports
89.56 - *
89.57 - * @author Tor Norbye
89.58 - */
89.59 -public class FmtImports extends javax.swing.JPanel {
89.60 -
89.61 - /** Creates new form FmtImports */
89.62 - public FmtImports() {
89.63 - initComponents();
89.64 -
89.65 - formatImportsCb.putClientProperty(OPTION_ID, formatImports);
89.66 - onePerLineCb.putClientProperty(OPTION_ID, oneImportPerLine);
89.67 - removeDuplicateCb.putClientProperty(OPTION_ID, removeDuplicates);
89.68 - systemLibsCb.putClientProperty(OPTION_ID, systemLibsFirst);
89.69 - cleanupCombo.putClientProperty(OPTION_ID, cleanupUnusedImports);
89.70 - preferSymbols.putClientProperty(OPTION_ID, preferSymbolImports);
89.71 - sortImportsCb.putClientProperty(OPTION_ID, sortImports);
89.72 - sepFromImpCb.putClientProperty(OPTION_ID, separateFromImps);
89.73 - }
89.74 -
89.75 - public static PreferencesCustomizer.Factory getController() {
89.76 - return new CategorySupport.Factory("imports", FmtImports.class,
89.77 - org.openide.util.NbBundle.getMessage(FmtImports.class, "SAMPLE_Imports"));
89.78 - }
89.79 -
89.80 - /** This method is called from within the constructor to
89.81 - * initialize the form.
89.82 - * WARNING: Do NOT modify this code. The content of this method is
89.83 - * always regenerated by the Form Editor.
89.84 - */
89.85 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
89.86 - private void initComponents() {
89.87 -
89.88 - formatImportsCb = new javax.swing.JCheckBox();
89.89 - onePerLineCb = new javax.swing.JCheckBox();
89.90 - systemLibsCb = new javax.swing.JCheckBox();
89.91 - removeDuplicateCb = new javax.swing.JCheckBox();
89.92 - cleanupLabel = new javax.swing.JLabel();
89.93 - cleanupCombo = new javax.swing.JComboBox();
89.94 - preferSymbols = new javax.swing.JCheckBox();
89.95 - sortImportsCb = new javax.swing.JCheckBox();
89.96 - sepFromImpCb = new javax.swing.JCheckBox();
89.97 -
89.98 - setName(org.openide.util.NbBundle.getMessage(FmtImports.class, "LBL_Imports")); // NOI18N
89.99 -
89.100 - org.openide.awt.Mnemonics.setLocalizedText(formatImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.formatImportsCb.text")); // NOI18N
89.101 -
89.102 - org.openide.awt.Mnemonics.setLocalizedText(onePerLineCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.onePerLineCb.text")); // NOI18N
89.103 -
89.104 - org.openide.awt.Mnemonics.setLocalizedText(systemLibsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.systemLibsCb.text")); // NOI18N
89.105 -
89.106 - org.openide.awt.Mnemonics.setLocalizedText(removeDuplicateCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.removeDuplicateCb.text")); // NOI18N
89.107 -
89.108 - org.openide.awt.Mnemonics.setLocalizedText(cleanupLabel, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.cleanupLabel.text")); // NOI18N
89.109 -
89.110 - org.openide.awt.Mnemonics.setLocalizedText(preferSymbols, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.preferSymbols.text")); // NOI18N
89.111 -
89.112 - org.openide.awt.Mnemonics.setLocalizedText(sortImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sortImportsCb.text")); // NOI18N
89.113 -
89.114 - org.openide.awt.Mnemonics.setLocalizedText(sepFromImpCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sepFromImpCb.text")); // NOI18N
89.115 -
89.116 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
89.117 - this.setLayout(layout);
89.118 - layout.setHorizontalGroup(
89.119 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
89.120 - .addGroup(layout.createSequentialGroup()
89.121 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
89.122 - .addComponent(formatImportsCb)
89.123 - .addComponent(onePerLineCb)
89.124 - .addComponent(systemLibsCb)
89.125 - .addComponent(sortImportsCb)
89.126 - .addComponent(sepFromImpCb)
89.127 - .addComponent(removeDuplicateCb)
89.128 - .addComponent(preferSymbols)
89.129 - .addGroup(layout.createSequentialGroup()
89.130 - .addComponent(cleanupLabel)
89.131 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
89.132 - .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
89.133 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
89.134 - );
89.135 - layout.setVerticalGroup(
89.136 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
89.137 - .addGroup(layout.createSequentialGroup()
89.138 - .addComponent(formatImportsCb)
89.139 - .addGap(18, 18, 18)
89.140 - .addComponent(onePerLineCb)
89.141 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
89.142 - .addComponent(systemLibsCb)
89.143 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
89.144 - .addComponent(sortImportsCb)
89.145 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
89.146 - .addComponent(sepFromImpCb)
89.147 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
89.148 - .addComponent(removeDuplicateCb)
89.149 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
89.150 - .addComponent(preferSymbols)
89.151 - .addGap(18, 18, 18)
89.152 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
89.153 - .addComponent(cleanupLabel)
89.154 - .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
89.155 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
89.156 - );
89.157 - }// </editor-fold>//GEN-END:initComponents
89.158 -
89.159 -
89.160 - // Variables declaration - do not modify//GEN-BEGIN:variables
89.161 - private javax.swing.JComboBox cleanupCombo;
89.162 - private javax.swing.JLabel cleanupLabel;
89.163 - private javax.swing.JCheckBox formatImportsCb;
89.164 - private javax.swing.JCheckBox onePerLineCb;
89.165 - private javax.swing.JCheckBox preferSymbols;
89.166 - private javax.swing.JCheckBox removeDuplicateCb;
89.167 - private javax.swing.JCheckBox sepFromImpCb;
89.168 - private javax.swing.JCheckBox sortImportsCb;
89.169 - private javax.swing.JCheckBox systemLibsCb;
89.170 - // End of variables declaration//GEN-END:variables
89.171 -
89.172 -}
90.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtOptions.java Fri Sep 18 16:20:24 2015 -0500
90.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
90.3 @@ -1,1035 +0,0 @@
90.4 -/*
90.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
90.6 - *
90.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
90.8 - *
90.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
90.10 - * Other names may be trademarks of their respective owners.
90.11 - *
90.12 - * The contents of this file are subject to the terms of either the GNU
90.13 - * General Public License Version 2 only ("GPL") or the Common
90.14 - * Development and Distribution License("CDDL") (collectively, the
90.15 - * "License"). You may not use this file except in compliance with the
90.16 - * License. You can obtain a copy of the License at
90.17 - * http://www.netbeans.org/cddl-gplv2.html
90.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
90.19 - * specific language governing permissions and limitations under the
90.20 - * License. When distributing the software, include this License Header
90.21 - * Notice in each file and include the License file at
90.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
90.23 - * particular file as subject to the "Classpath" exception as provided
90.24 - * by Oracle in the GPL Version 2 section of the License file that
90.25 - * accompanied this code. If applicable, add the following below the
90.26 - * License Header, with the fields enclosed by brackets [] replaced by
90.27 - * your own identifying information:
90.28 - * "Portions Copyrighted [year] [name of copyright owner]"
90.29 - *
90.30 - * Contributor(s):
90.31 - *
90.32 - * The Original Software is NetBeans. The Initial Developer of the Original
90.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
90.34 - * Microsystems, Inc. All Rights Reserved.
90.35 - *
90.36 - * If you wish your version of this file to be governed by only the CDDL
90.37 - * or only the GPL Version 2, indicate your decision by adding
90.38 - * "[Contributor] elects to include this software in this distribution
90.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
90.40 - * single choice of license, a recipient has the option to distribute
90.41 - * your version of this file under either the CDDL, the GPL Version 2 or
90.42 - * to extend the choice of license to its licensees as provided above.
90.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
90.44 - * Version 2 license, then the option applies only if the new code is
90.45 - * made subject to such option by the copyright holder.
90.46 - */
90.47 -package org.netbeans.modules.python.editor.options;
90.48 -
90.49 -import java.awt.Component;
90.50 -import java.awt.Container;
90.51 -import java.awt.Rectangle;
90.52 -import java.awt.event.ActionEvent;
90.53 -import java.awt.event.ActionListener;
90.54 -import java.io.BufferedWriter;
90.55 -import java.io.File;
90.56 -import java.io.FileWriter;
90.57 -import java.io.IOException;
90.58 -import java.util.Arrays;
90.59 -import java.util.HashMap;
90.60 -import java.util.HashSet;
90.61 -import java.util.LinkedList;
90.62 -import java.util.List;
90.63 -import java.util.Map;
90.64 -import java.util.Set;
90.65 -import java.util.prefs.AbstractPreferences;
90.66 -import java.util.prefs.BackingStoreException;
90.67 -import java.util.prefs.Preferences;
90.68 -import javax.swing.ComboBoxModel;
90.69 -import javax.swing.DefaultComboBoxModel;
90.70 -import javax.swing.JCheckBox;
90.71 -import javax.swing.JComboBox;
90.72 -import javax.swing.JComponent;
90.73 -import javax.swing.JEditorPane;
90.74 -import javax.swing.JPanel;
90.75 -import javax.swing.JTextField;
90.76 -import javax.swing.event.DocumentEvent;
90.77 -import javax.swing.event.DocumentListener;
90.78 -import javax.swing.text.BadLocationException;
90.79 -import javax.swing.text.Document;
90.80 -import org.netbeans.api.editor.settings.SimpleValueNames;
90.81 -import static org.netbeans.modules.python.editor.options.CodeStyle.*;
90.82 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
90.83 -import org.netbeans.modules.options.editor.spi.PreviewProvider;
90.84 -import org.netbeans.modules.python.api.PythonMIMEResolver;
90.85 -import org.netbeans.modules.python.editor.PythonFormatter;
90.86 -import org.netbeans.modules.python.editor.PythonParserResult;
90.87 -import org.openide.cookies.SaveCookie;
90.88 -import org.openide.filesystems.FileObject;
90.89 -import org.openide.filesystems.FileUtil;
90.90 -import org.openide.loaders.DataObject;
90.91 -import org.openide.loaders.DataObjectNotFoundException;
90.92 -import org.openide.text.CloneableEditorSupport;
90.93 -import org.openide.util.Exceptions;
90.94 -import org.openide.util.HelpCtx;
90.95 -import org.openide.util.NbBundle;
90.96 -
90.97 -/**
90.98 - *
90.99 - * @author phrebejk
90.100 - */
90.101 -public class FmtOptions {
90.102 - public static final String expandTabToSpaces = SimpleValueNames.EXPAND_TABS;
90.103 - public static final String tabSize = SimpleValueNames.TAB_SIZE;
90.104 - public static final String spacesPerTab = SimpleValueNames.SPACES_PER_TAB;
90.105 - public static final String indentSize = SimpleValueNames.INDENT_SHIFT_WIDTH;
90.106 - public static final String continuationIndentSize = "continuationIndentSize"; //NOI18N
90.107 - public static final String labelIndent = "labelIndent"; //NOI18N
90.108 - public static final String absoluteLabelIndent = "absoluteLabelIndent"; //NOI18N
90.109 - public static final String indentTopLevelClassMembers = "indentTopLevelClassMembers"; //NOI18N
90.110 - public static final String indentCasesFromSwitch = "indentCasesFromSwitch"; //NOI18N
90.111 - public static final String rightMargin = SimpleValueNames.TEXT_LIMIT_WIDTH;
90.112 -
90.113 - /*
90.114 - public static final String addLeadingStarInComment = "addLeadingStarInComment"; //NOI18N
90.115 -
90.116 - public static final String preferLongerNames = "preferLongerNames"; //NOI18N
90.117 - public static final String fieldNamePrefix = "fieldNamePrefix"; //NOI18N
90.118 - public static final String fieldNameSuffix = "fieldNameSuffix"; //NOI18N
90.119 - public static final String staticFieldNamePrefix = "staticFieldNamePrefix"; //NOI18N
90.120 - public static final String staticFieldNameSuffix = "staticFieldNameSuffix"; //NOI18N
90.121 - public static final String parameterNamePrefix = "parameterNamePrefix"; //NOI18N
90.122 - public static final String parameterNameSuffix = "parameterNameSuffix"; //NOI18N
90.123 - public static final String localVarNamePrefix = "localVarNamePrefix"; //NOI18N
90.124 - public static final String localVarNameSuffix = "localVarNameSuffix"; //NOI18N
90.125 - public static final String qualifyFieldAccess = "qualifyFieldAccess"; //NOI18N
90.126 - public static final String useIsForBooleanGetters = "useIsForBooleanGetters"; //NOI18N
90.127 - public static final String addOverrideAnnotation = "addOverrideAnnotation"; //NOI18N
90.128 - public static final String makeLocalVarsFinal = "makeLocalVarsFinal"; //NOI18N
90.129 - public static final String makeParametersFinal = "makeParametersFinal"; //NOI18N
90.130 - public static final String classMembersOrder = "classMembersOrder"; //NOI18N
90.131 -
90.132 - public static final String alignMultilineMethodParams = "alignMultilineMethodParams"; //NOI18N
90.133 - public static final String alignMultilineCallArgs = "alignMultilineCallArgs"; //NOI18N
90.134 - public static final String alignMultilineAnnotationArgs = "alignMultilineAnnotationArgs"; //NOI18N
90.135 - public static final String alignMultilineImplements = "alignMultilineImplements"; //NOI18N
90.136 - public static final String alignMultilineThrows = "alignMultilineThrows"; //NOI18N
90.137 - public static final String alignMultilineParenthesized = "alignMultilineParenthesized"; //NOI18N
90.138 - public static final String alignMultilineBinaryOp = "alignMultilineBinaryOp"; //NOI18N
90.139 - public static final String alignMultilineTernaryOp = "alignMultilineTernaryOp"; //NOI18N
90.140 - public static final String alignMultilineAssignment = "alignMultilineAssignment"; //NOI18N
90.141 - public static final String alignMultilineFor = "alignMultilineFor"; //NOI18N
90.142 - public static final String alignMultilineArrayInit = "alignMultilineArrayInit"; //NOI18N
90.143 - public static final String placeElseOnNewLine = "placeElseOnNewLine"; //NOI18N
90.144 - public static final String placeWhileOnNewLine = "placeWhileOnNewLine"; //NOI18N
90.145 - public static final String placeCatchOnNewLine = "placeCatchOnNewLine"; //NOI18N
90.146 - public static final String placeFinallyOnNewLine = "placeFinallyOnNewLine"; //NOI18N
90.147 - public static final String placeNewLineAfterModifiers = "placeNewLineAfterModifiers"; //NOI18N
90.148 -
90.149 - public static final String wrapExtendsImplementsKeyword = "wrapExtendsImplementsKeyword"; //NOI18N
90.150 - public static final String wrapExtendsImplementsList = "wrapExtendsImplementsList"; //NOI18N
90.151 - public static final String wrapMethodParams = "wrapMethodParams"; //NOI18N
90.152 - public static final String wrapThrowsKeyword = "wrapThrowsKeyword"; //NOI18N
90.153 - public static final String wrapThrowsList = "wrapThrowsList"; //NOI18N
90.154 - public static final String wrapMethodCallArgs = "wrapMethodCallArgs"; //NOI18N
90.155 - public static final String wrapAnnotationArgs = "wrapAnnotationArgs"; //NOI18N
90.156 - public static final String wrapChainedMethodCalls = "wrapChainedMethodCalls"; //NOI18N
90.157 - public static final String wrapArrayInit = "wrapArrayInit"; //NOI18N
90.158 - public static final String wrapFor = "wrapFor"; //NOI18N
90.159 - public static final String wrapForStatement = "wrapForStatement"; //NOI18N
90.160 - public static final String wrapIfStatement = "wrapIfStatement"; //NOI18N
90.161 - public static final String wrapWhileStatement = "wrapWhileStatement"; //NOI18N
90.162 - public static final String wrapDoWhileStatement = "wrapDoWhileStatement"; //NOI18N
90.163 - public static final String wrapAssert = "wrapAssert"; //NOI18N
90.164 - public static final String wrapEnumConstants = "wrapEnumConstants"; //NOI18N
90.165 - public static final String wrapAnnotations = "wrapAnnotations"; //NOI18N
90.166 - public static final String wrapBinaryOps = "wrapBinaryOps"; //NOI18N
90.167 - public static final String wrapTernaryOps = "wrapTernaryOps"; //NOI18N
90.168 - public static final String wrapAssignOps = "wrapAssignOps"; //NOI18N
90.169 -
90.170 - public static final String blankLinesBeforePackage = "blankLinesBeforePackage"; //NOI18N
90.171 - public static final String blankLinesAfterPackage = "blankLinesAfterPackage"; //NOI18N
90.172 - public static final String blankLinesBeforeImports = "blankLinesBeforeImports"; //NOI18N
90.173 - public static final String blankLinesAfterImports = "blankLinesAfterImports"; //NOI18N
90.174 - public static final String blankLinesBeforeClass = "blankLinesBeforeClass"; //NOI18N
90.175 - public static final String blankLinesAfterClass = "blankLinesAfterClass"; //NOI18N
90.176 - public static final String blankLinesAfterClassHeader = "blankLinesAfterClassHeader"; //NOI18N
90.177 - public static final String blankLinesBeforeFields = "blankLinesBeforeFields"; //NOI18N
90.178 - public static final String blankLinesAfterFields = "blankLinesAfterFields"; //NOI18N
90.179 - public static final String blankLinesBeforeMethods = "blankLinesBeforeMethods"; //NOI18N
90.180 - public static final String blankLinesAfterMethods = "blankLinesAfterMethods"; //NOI18N
90.181 -
90.182 - public static final String spaceBeforeWhile = "spaceBeforeWhile"; //NOI18N
90.183 - public static final String spaceBeforeElse = "spaceBeforeElse"; //NOI18N
90.184 - public static final String spaceBeforeCatch = "spaceBeforeCatch"; //NOI18N
90.185 - public static final String spaceBeforeFinally = "spaceBeforeFinally"; //NOI18N
90.186 - public static final String spaceBeforeMethodDeclParen = "spaceBeforeMethodDeclParen"; //NOI18N
90.187 - public static final String spaceBeforeMethodCallParen = "spaceBeforeMethodCallParen"; //NOI18N
90.188 - public static final String spaceBeforeIfParen = "spaceBeforeIfParen"; //NOI18N
90.189 - public static final String spaceBeforeForParen = "spaceBeforeForParen"; //NOI18N
90.190 - public static final String spaceBeforeWhileParen = "spaceBeforeWhileParen"; //NOI18N
90.191 - public static final String spaceBeforeCatchParen = "spaceBeforeCatchParen"; //NOI18N
90.192 - public static final String spaceBeforeSwitchParen = "spaceBeforeSwitchParen"; //NOI18N
90.193 - public static final String spaceBeforeSynchronizedParen = "spaceBeforeSynchronizedParen"; //NOI18N
90.194 - public static final String spaceBeforeAnnotationParen = "spaceBeforeAnnotationParen"; //NOI18N
90.195 - public static final String spaceAroundUnaryOps = "spaceAroundUnaryOps"; //NOI18N
90.196 - public static final String spaceAroundBinaryOps = "spaceAroundBinaryOps"; //NOI18N
90.197 - public static final String spaceAroundTernaryOps = "spaceAroundTernaryOps"; //NOI18N
90.198 - public static final String spaceAroundAssignOps = "spaceAroundAssignOps"; //NOI18N
90.199 - public static final String spaceBeforeClassDeclLeftBrace = "spaceBeforeClassDeclLeftBrace"; //NOI18N
90.200 - public static final String spaceBeforeMethodDeclLeftBrace = "spaceBeforeMethodDeclLeftBrace"; //NOI18N
90.201 - public static final String spaceBeforeIfLeftBrace = "spaceBeforeIfLeftBrace"; //NOI18N
90.202 - public static final String spaceBeforeElseLeftBrace = "spaceBeforeElseLeftBrace"; //NOI18N
90.203 - public static final String spaceBeforeWhileLeftBrace = "spaceBeforeWhileLeftBrace"; //NOI18N
90.204 - public static final String spaceBeforeForLeftBrace = "spaceBeforeForLeftBrace"; //NOI18N
90.205 - public static final String spaceBeforeDoLeftBrace = "spaceBeforeDoLeftBrace"; //NOI18N
90.206 - public static final String spaceBeforeSwitchLeftBrace = "spaceBeforeSwitchLeftBrace"; //NOI18N
90.207 - public static final String spaceBeforeTryLeftBrace = "spaceBeforeTryLeftBrace"; //NOI18N
90.208 - public static final String spaceBeforeCatchLeftBrace = "spaceBeforeCatchLeftBrace"; //NOI18N
90.209 - public static final String spaceBeforeFinallyLeftBrace = "spaceBeforeFinallyLeftBrace"; //NOI18N
90.210 - public static final String spaceBeforeSynchronizedLeftBrace = "spaceBeforeSynchronizedLeftBrace"; //NOI18N
90.211 - public static final String spaceBeforeStaticInitLeftBrace = "spaceBeforeStaticInitLeftBrace"; //NOI18N
90.212 - public static final String spaceBeforeArrayInitLeftBrace = "spaceBeforeArrayInitLeftBrace"; //NOI18N
90.213 - public static final String spaceWithinParens = "spaceWithinParens"; //NOI18N
90.214 - public static final String spaceWithinMethodDeclParens = "spaceWithinMethodDeclParens"; //NOI18N
90.215 - public static final String spaceWithinMethodCallParens = "spaceWithinMethodCallParens"; //NOI18N
90.216 - public static final String spaceWithinIfParens = "spaceWithinIfParens"; //NOI18N
90.217 - public static final String spaceWithinForParens = "spaceWithinForParens"; //NOI18N
90.218 - public static final String spaceWithinWhileParens = "spaceWithinWhileParens"; //NOI18N
90.219 - public static final String spaceWithinSwitchParens = "spaceWithinSwitchParens"; //NOI18N
90.220 - public static final String spaceWithinCatchParens = "spaceWithinCatchParens"; //NOI18N
90.221 - public static final String spaceWithinSynchronizedParens = "spaceWithinSynchronizedParens"; //NOI18N
90.222 - public static final String spaceWithinTypeCastParens = "spaceWithinTypeCastParens"; //NOI18N
90.223 - public static final String spaceWithinAnnotationParens = "spaceWithinAnnotationParens"; //NOI18N
90.224 - public static final String spaceWithinBraces = "spaceWithinBraces"; //NOI18N
90.225 - public static final String spaceWithinArrayInitBrackets = "spaceWithinArrayInitBrackets"; //NOI18N
90.226 - public static final String spaceBeforeComma = "spaceBeforeComma"; //NOI18N
90.227 - public static final String spaceAfterComma = "spaceAfterComma"; //NOI18N
90.228 - public static final String spaceBeforeSemi = "spaceBeforeSemi"; //NOI18N
90.229 - public static final String spaceAfterSemi = "spaceAfterSemi"; //NOI18N
90.230 - public static final String spaceBeforeColon = "spaceBeforeColon"; //NOI18N
90.231 - public static final String spaceAfterColon = "spaceAfterColon"; //NOI18N
90.232 - public static final String spaceAfterTypeCast = "spaceAfterTypeCast"; //NOI18N
90.233 - */
90.234 -
90.235 - // Spaces
90.236 - public static final String addSpaceAroundOperators = "spaceAroundOperators"; //NOI18N
90.237 - public static final String removeSpaceInParens = "spaceInsideParens"; //NOI18N
90.238 - public static final String addSpaceAfterComma = "spaceAfterComma"; //NOI18N
90.239 - public static final String removeSpaceBeforeSep = "spaceBeforeSeparator"; //NOI18N
90.240 - public static final String removeSpaceInParamAssign = "spaceInKeywordAssign"; //NOI18N
90.241 - public static final String collapseSpaces = "collapseSpaces"; //NOI18N
90.242 - // Imports
90.243 - public static final String formatImports = "formatImports"; //NOI18N
90.244 - public static final String oneImportPerLine = "oneImportPerLine"; //NOI18N
90.245 - public static final String removeDuplicates = "removeDuplicates"; //NOI18N
90.246 - public static final String systemLibsFirst = "systemLibsFirst"; //NOI18N
90.247 - public static final String cleanupUnusedImports = "cleanupUnusedImports"; //NOI18N
90.248 - public static final String preferSymbolImports = "preferSymbolImports"; //NOI18N
90.249 - public static final String sortImports = "sortImports"; //NOI18N
90.250 - public static final String separateFromImps = "separateFromImps"; //NOI18N
90.251 - public static CodeStyleProducer codeStyleProducer;
90.252 - static final String CODE_STYLE_PROFILE = "CodeStyle"; // NOI18N
90.253 - static final String DEFAULT_PROFILE = "default"; // NOI18N
90.254 - static final String PROJECT_PROFILE = "project"; // NOI18N
90.255 - static final String usedProfile = "usedProfile"; // NOI18N
90.256 -
90.257 - private FmtOptions() {
90.258 - }
90.259 -
90.260 - public static int getDefaultAsInt(String key) {
90.261 - return Integer.parseInt(defaults.get(key));
90.262 - }
90.263 -
90.264 - public static boolean getDefaultAsBoolean(String key) {
90.265 - return Boolean.parseBoolean(defaults.get(key));
90.266 - }
90.267 -
90.268 - public static String getDefaultAsString(String key) {
90.269 - return defaults.get(key);
90.270 - }
90.271 -
90.272 - public static boolean isInteger(String optionID) {
90.273 - String value = defaults.get(optionID);
90.274 -
90.275 - try {
90.276 - Integer.parseInt(value);
90.277 - return true;
90.278 - } catch (NumberFormatException numberFormatException) {
90.279 - return false;
90.280 - }
90.281 - }
90.282 - // Private section ---------------------------------------------------------
90.283 - private static final String TRUE = "true"; // NOI18N
90.284 - private static final String FALSE = "false"; // NOI18N
90.285 - private static final String WRAP_ALWAYS = WrapStyle.WRAP_ALWAYS.name();
90.286 - //private static final String WRAP_IF_LONG = WrapStyle.WRAP_IF_LONG.name();
90.287 - private static final String WRAP_NEVER = WrapStyle.WRAP_NEVER.name();
90.288 -
90.289 - //private static final String CLEANUP_COMMENT = ImportCleanupStyle.COMMENT_OUT.name();
90.290 - private static final String IMP_LEAVE_ALONE = ImportCleanupStyle.LEAVE_ALONE.name();
90.291 - private static Map<String, String> defaults;
90.292 -
90.293 -
90.294 - static {
90.295 - createDefaults();
90.296 - }
90.297 -
90.298 - private static void createDefaults() {
90.299 - String defaultValues[][] = {
90.300 - {expandTabToSpaces, TRUE}, //NOI18N
90.301 - {tabSize, "4"}, //NOI18N
90.302 - {spacesPerTab, "4"}, //NOI18N
90.303 - {indentSize, "4"}, //NOI18N
90.304 - {continuationIndentSize, "8"}, //NOI18N
90.305 - {labelIndent, "0"}, //NOI18N
90.306 - {absoluteLabelIndent, FALSE}, //NOI18N
90.307 - {indentTopLevelClassMembers, TRUE}, //NOI18N
90.308 - {indentCasesFromSwitch, TRUE}, //NOI18N
90.309 - {rightMargin, "80"}, //NOI18N
90.310 -
90.311 - /*
90.312 - { addLeadingStarInComment, TRUE}, //NOI18N
90.313 -
90.314 - { preferLongerNames, TRUE}, //NOI18N
90.315 - { fieldNamePrefix, ""}, //NOI18N // XXX null
90.316 - { fieldNameSuffix, ""}, //NOI18N // XXX null
90.317 - { staticFieldNamePrefix, ""}, //NOI18N // XXX null
90.318 - { staticFieldNameSuffix, ""}, //NOI18N // XXX null
90.319 - { parameterNamePrefix, ""}, //NOI18N // XXX null
90.320 - { parameterNameSuffix, ""}, //NOI18N // XXX null
90.321 - { localVarNamePrefix, ""}, //NOI18N // XXX null
90.322 - { localVarNameSuffix, ""}, //NOI18N // XXX null
90.323 - { qualifyFieldAccess, FALSE}, //NOI18N // XXX
90.324 - { useIsForBooleanGetters, TRUE}, //NOI18N
90.325 - { addOverrideAnnotation, TRUE}, //NOI18N
90.326 - { makeLocalVarsFinal, FALSE}, //NOI18N
90.327 - { makeParametersFinal, FALSE}, //NOI18N
90.328 - { classMembersOrder, ""}, //NOI18N // XXX
90.329 -
90.330 - { alignMultilineMethodParams, FALSE}, //NOI18N
90.331 - { alignMultilineCallArgs, FALSE}, //NOI18N
90.332 - { alignMultilineAnnotationArgs, FALSE}, //NOI18N
90.333 - { alignMultilineImplements, FALSE}, //NOI18N
90.334 - { alignMultilineThrows, FALSE}, //NOI18N
90.335 - { alignMultilineParenthesized, FALSE}, //NOI18N
90.336 - { alignMultilineBinaryOp, FALSE}, //NOI18N
90.337 - { alignMultilineTernaryOp, FALSE}, //NOI18N
90.338 - { alignMultilineAssignment, FALSE}, //NOI18N
90.339 - { alignMultilineFor, FALSE}, //NOI18N
90.340 - { alignMultilineArrayInit, FALSE}, //NOI18N
90.341 - { placeElseOnNewLine, FALSE}, //NOI18N
90.342 - { placeWhileOnNewLine, FALSE}, //NOI18N
90.343 - { placeCatchOnNewLine, FALSE}, //NOI18N
90.344 - { placeFinallyOnNewLine, FALSE}, //NOI18N
90.345 - { placeNewLineAfterModifiers, FALSE}, //NOI18N
90.346 -
90.347 - { wrapExtendsImplementsKeyword, WRAP_NEVER}, //NOI18N
90.348 - { wrapExtendsImplementsList, WRAP_NEVER}, //NOI18N
90.349 - { wrapMethodParams, WRAP_NEVER}, //NOI18N
90.350 - { wrapThrowsKeyword, WRAP_NEVER}, //NOI18N
90.351 - { wrapThrowsList, WRAP_NEVER}, //NOI18N
90.352 - { wrapMethodCallArgs, WRAP_NEVER}, //NOI18N
90.353 - { wrapAnnotationArgs, WRAP_NEVER}, //NOI18N
90.354 - { wrapChainedMethodCalls, WRAP_NEVER}, //NOI18N
90.355 - { wrapArrayInit, WRAP_NEVER}, //NOI18N
90.356 - { wrapFor, WRAP_NEVER}, //NOI18N
90.357 - { wrapForStatement, WRAP_ALWAYS}, //NOI18N
90.358 - { wrapIfStatement, WRAP_ALWAYS}, //NOI18N
90.359 - { wrapWhileStatement, WRAP_ALWAYS}, //NOI18N
90.360 - { wrapDoWhileStatement, WRAP_ALWAYS}, //NOI18N
90.361 - { wrapAssert, WRAP_NEVER}, //NOI18N
90.362 - { wrapEnumConstants, WRAP_NEVER}, //NOI18N
90.363 - { wrapAnnotations, WRAP_ALWAYS}, //NOI18N
90.364 - { wrapBinaryOps, WRAP_NEVER}, //NOI18N
90.365 - { wrapTernaryOps, WRAP_NEVER}, //NOI18N
90.366 - { wrapAssignOps, WRAP_NEVER}, //NOI18N
90.367 -
90.368 - { blankLinesBeforePackage, "0"}, //NOI18N
90.369 - { blankLinesAfterPackage, "1"}, //NOI18N
90.370 - { blankLinesBeforeImports, "1"}, //NOI18N
90.371 - { blankLinesAfterImports, "1"}, //NOI18N
90.372 - { blankLinesBeforeClass, "1"}, //NOI18N
90.373 - { blankLinesAfterClass, "0"}, //NOI18N
90.374 - { blankLinesAfterClassHeader, "1"}, //NOI18N
90.375 - { blankLinesBeforeFields, "0"}, //NOI18N
90.376 - { blankLinesAfterFields, "0"}, //NOI18N
90.377 - { blankLinesBeforeMethods, "1"}, //NOI18N
90.378 - { blankLinesAfterMethods, "0"}, //NOI18N
90.379 -
90.380 - { spaceBeforeWhile, TRUE}, //NOI18N // XXX
90.381 - { spaceBeforeElse, TRUE}, //NOI18N // XXX
90.382 - { spaceBeforeCatch, TRUE}, //NOI18N // XXX
90.383 - { spaceBeforeFinally, TRUE}, //NOI18N // XXX
90.384 - { spaceBeforeMethodDeclParen, FALSE}, //NOI18N
90.385 - { spaceBeforeMethodCallParen, FALSE}, //NOI18N
90.386 - { spaceBeforeIfParen, TRUE}, //NOI18N
90.387 - { spaceBeforeForParen, TRUE}, //NOI18N
90.388 - { spaceBeforeWhileParen, TRUE}, //NOI18N
90.389 - { spaceBeforeCatchParen, TRUE}, //NOI18N
90.390 - { spaceBeforeSwitchParen, TRUE}, //NOI18N
90.391 - { spaceBeforeSynchronizedParen, TRUE}, //NOI18N
90.392 - { spaceBeforeAnnotationParen, FALSE}, //NOI18N
90.393 - { spaceAroundUnaryOps, FALSE}, //NOI18N
90.394 - { spaceAroundBinaryOps, TRUE}, //NOI18N
90.395 - { spaceAroundTernaryOps, TRUE}, //NOI18N
90.396 - { spaceAroundAssignOps, TRUE}, //NOI18N
90.397 - { spaceBeforeClassDeclLeftBrace, TRUE}, //NOI18N
90.398 - { spaceBeforeMethodDeclLeftBrace, TRUE}, //NOI18N
90.399 - { spaceBeforeIfLeftBrace, TRUE}, //NOI18N
90.400 - { spaceBeforeElseLeftBrace, TRUE}, //NOI18N
90.401 - { spaceBeforeWhileLeftBrace, TRUE}, //NOI18N
90.402 - { spaceBeforeForLeftBrace, TRUE}, //NOI18N
90.403 - { spaceBeforeDoLeftBrace, TRUE}, //NOI18N
90.404 - { spaceBeforeSwitchLeftBrace, TRUE}, //NOI18N
90.405 - { spaceBeforeTryLeftBrace, TRUE}, //NOI18N
90.406 - { spaceBeforeCatchLeftBrace, TRUE}, //NOI18N
90.407 - { spaceBeforeFinallyLeftBrace, TRUE}, //NOI18N
90.408 - { spaceBeforeSynchronizedLeftBrace, TRUE}, //NOI18N
90.409 - { spaceBeforeStaticInitLeftBrace, TRUE}, //NOI18N
90.410 - { spaceBeforeArrayInitLeftBrace, FALSE}, //NOI18N
90.411 - { spaceWithinParens, FALSE}, //NOI18N
90.412 - { spaceWithinMethodDeclParens, FALSE}, //NOI18N
90.413 - { spaceWithinMethodCallParens, FALSE}, //NOI18N
90.414 - { spaceWithinIfParens, FALSE}, //NOI18N
90.415 - { spaceWithinForParens, FALSE}, //NOI18N
90.416 - { spaceWithinWhileParens, FALSE}, //NOI18N
90.417 - { spaceWithinSwitchParens, FALSE}, //NOI18N
90.418 - { spaceWithinCatchParens, FALSE}, //NOI18N
90.419 - { spaceWithinSynchronizedParens, FALSE}, //NOI18N
90.420 - { spaceWithinTypeCastParens, FALSE}, //NOI18N
90.421 - { spaceWithinAnnotationParens, FALSE}, //NOI18N
90.422 - { spaceWithinBraces, FALSE}, //NOI18N
90.423 - { spaceWithinArrayInitBrackets, FALSE}, //NOI18N
90.424 - { spaceBeforeComma, FALSE}, //NOI18N
90.425 - { spaceAfterComma, TRUE}, //NOI18N
90.426 - { spaceBeforeSemi, FALSE}, //NOI18N
90.427 - { spaceAfterSemi, TRUE}, //NOI18N
90.428 - { spaceBeforeColon, TRUE}, //NOI18N
90.429 - { spaceAfterColon, TRUE}, //NOI18N
90.430 - { spaceAfterTypeCast, TRUE}, //NOI18N
90.431 - */
90.432 - // Spaces
90.433 - {addSpaceAroundOperators, TRUE},
90.434 - {removeSpaceInParens, TRUE},
90.435 - {addSpaceAfterComma, TRUE},
90.436 - {removeSpaceBeforeSep, TRUE},
90.437 - {removeSpaceInParamAssign, TRUE},
90.438 - {collapseSpaces, TRUE},
90.439 - // Imports
90.440 - {formatImports, TRUE},
90.441 - {oneImportPerLine, TRUE},
90.442 - {removeDuplicates, TRUE},
90.443 - {systemLibsFirst, TRUE},
90.444 - {preferSymbolImports, TRUE},
90.445 - {sortImports, TRUE},
90.446 - {cleanupUnusedImports, IMP_LEAVE_ALONE},
90.447 - {separateFromImps, FALSE},};
90.448 -
90.449 - defaults = new HashMap<>();
90.450 -
90.451 - for (java.lang.String[] strings : defaultValues) {
90.452 - defaults.put(strings[0], strings[1]);
90.453 - }
90.454 -
90.455 - }
90.456 -
90.457 - // Support section ---------------------------------------------------------
90.458 - public static class CategorySupport implements ActionListener, DocumentListener, PreviewProvider, PreferencesCustomizer {
90.459 - public static final String OPTION_ID = "org.netbeans.modules.python.editor.options.FormatingOptions.ID";
90.460 - private static final int LOAD = 0;
90.461 - private static final int STORE = 1;
90.462 - private static final int ADD_LISTENERS = 2;
90.463 - private static final ComboItem wrap[] = new ComboItem[]{
90.464 - new ComboItem(WrapStyle.WRAP_ALWAYS.name(), "LBL_wrp_WRAP_ALWAYS"), // NOI18N
90.465 - new ComboItem(WrapStyle.WRAP_IF_LONG.name(), "LBL_wrp_WRAP_IF_LONG"), // NOI18N
90.466 - new ComboItem(WrapStyle.WRAP_NEVER.name(), "LBL_wrp_WRAP_NEVER") // NOI18N
90.467 - };
90.468 - private static final ComboItem cleanupImports[] = new ComboItem[]{
90.469 - new ComboItem(ImportCleanupStyle.LEAVE_ALONE.name(), "LBL_imp_LEAVE_ALONE"), // NOI18N
90.470 - new ComboItem(ImportCleanupStyle.COMMENT_OUT.name(), "LBL_imp_COMMENT_OUT"), // NOI18N
90.471 - new ComboItem(ImportCleanupStyle.DELETE.name(), "LBL_imp_DELETE") // NOI18N
90.472 - };
90.473 - private final String previewText;
90.474 - private final String id;
90.475 - protected final JPanel panel;
90.476 - private final List<JComponent> components = new LinkedList<>();
90.477 - private JEditorPane previewPane;
90.478 - private final Preferences preferences;
90.479 - private final Preferences previewPrefs;
90.480 -
90.481 - protected CategorySupport(Preferences preferences, String id, JPanel panel, String previewText, String[]... forcedOptions) {
90.482 - this.preferences = preferences;
90.483 - this.id = id;
90.484 - this.panel = panel;
90.485 - this.previewText = previewText != null ? previewText : NbBundle.getMessage(FmtOptions.class, "SAMPLE_Default"); //NOI18N
90.486 -
90.487 - // Scan the panel for its components
90.488 - scan(panel, components);
90.489 -
90.490 - // Initialize the preview preferences
90.491 - Preferences forcedPrefs = new PreviewPreferences();
90.492 - for (String[] option : forcedOptions) {
90.493 - forcedPrefs.put(option[0], option[1]);
90.494 - }
90.495 - this.previewPrefs = new ProxyPreferences(preferences, forcedPrefs);
90.496 -
90.497 - // Load and hook up all the components
90.498 - loadFrom(preferences);
90.499 - addListeners();
90.500 - }
90.501 -
90.502 - protected void addListeners() {
90.503 - scan(ADD_LISTENERS, null);
90.504 - }
90.505 -
90.506 - protected void loadFrom(Preferences preferences) {
90.507 -// loaded = true;
90.508 - scan(LOAD, preferences);
90.509 -// loaded = false;
90.510 - }
90.511 -//
90.512 -// public void applyChanges() {
90.513 -// storeTo(preferences);
90.514 -// }
90.515 -//
90.516 -
90.517 - protected void storeTo(Preferences p) {
90.518 - scan(STORE, p);
90.519 - }
90.520 -
90.521 - protected void notifyChanged() {
90.522 -// if (loaded)
90.523 -// return;
90.524 - storeTo(preferences);
90.525 - refreshPreview();
90.526 - }
90.527 -
90.528 - // ActionListener implementation ---------------------------------------
90.529 - @Override
90.530 - public void actionPerformed(ActionEvent e) {
90.531 - notifyChanged();
90.532 - }
90.533 -
90.534 - // DocumentListener implementation -------------------------------------
90.535 - @Override
90.536 - public void insertUpdate(DocumentEvent e) {
90.537 - notifyChanged();
90.538 - }
90.539 -
90.540 - @Override
90.541 - public void removeUpdate(DocumentEvent e) {
90.542 - notifyChanged();
90.543 - }
90.544 -
90.545 - @Override
90.546 - public void changedUpdate(DocumentEvent e) {
90.547 - notifyChanged();
90.548 - }
90.549 -
90.550 - // PreviewProvider methods -----------------------------------------------------
90.551 - @Override
90.552 - public JComponent getPreviewComponent() {
90.553 - if (previewPane == null) {
90.554 - previewPane = new JEditorPane();
90.555 - previewPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtOptions.class, "AN_Preview")); //NOI18N
90.556 - previewPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtOptions.class, "AD_Preview")); //NOI18N
90.557 - previewPane.putClientProperty("HighlightsLayerIncludes", "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.SyntaxHighlighting$"); //NOI18N
90.558 - previewPane.setEditorKit(CloneableEditorSupport.getEditorKit(PythonMIMEResolver.PYTHON_MIME_TYPE));
90.559 - previewPane.setEditable(false);
90.560 - }
90.561 - return previewPane;
90.562 - }
90.563 -
90.564 - @Override
90.565 - public void refreshPreview() {
90.566 - JEditorPane jep = (JEditorPane)getPreviewComponent();
90.567 - try {
90.568 - int rm = previewPrefs.getInt(rightMargin, getDefaultAsInt(rightMargin));
90.569 - jep.putClientProperty("TextLimitLine", rm); //NOI18N
90.570 - } catch (NumberFormatException e) {
90.571 - // Ignore it
90.572 - }
90.573 - try {
90.574 - Class.forName(CodeStyle.class.getName(), true, CodeStyle.class.getClassLoader());
90.575 - } catch (ClassNotFoundException cnfe) {
90.576 - // ignore
90.577 - }
90.578 -
90.579 - CodeStyle codeStyle = codeStyleProducer.create(previewPrefs);
90.580 - jep.setIgnoreRepaint(true);
90.581 -
90.582 -// if (jep.getDocument() instanceof BaseDocument) {
90.583 -// BaseDocument document = (BaseDocument) jep.getDocument();
90.584 -// final org.netbeans.editor.Formatter f = document.getFormatter();
90.585 -// try {
90.586 -// f.reformatLock();
90.587 -// try {
90.588 -// int reformattedLen = f.reformat(document, 0, document.getLength());
90.589 -// } catch (BadLocationException ex) {
90.590 -// Exceptions.printStackTrace(ex);
90.591 -// }
90.592 -// } finally {
90.593 -// f.reformatUnlock();
90.594 -// }
90.595 -// }
90.596 -
90.597 - // Hacky code to do preview: We want to preview blank text without
90.598 - // a data object... this doesn't work very well so requires some hacks
90.599 - // to create a temp file, format it, then save it and delete it
90.600 - // (to avoid save confirmation dialogs on the modified file etc)
90.601 - PythonFormatter formatter = new PythonFormatter(codeStyle);
90.602 - PythonParserResult info = null;
90.603 - File tmp = null;
90.604 - FileObject tmpFo = null;
90.605 - if (formatter.needsParserResult()) {
90.606 - try {
90.607 - tmp = File.createTempFile("preview", ".py"); // NOI18N
90.608 - BufferedWriter writer = new BufferedWriter(new FileWriter(tmp));
90.609 - writer.write(previewText);
90.610 - writer.close();
90.611 - final FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(tmp));
90.612 - tmpFo = fo;
90.613 - // TODO - I need to get the classpath involved here such that it can
90.614 - // find used/unused libraries
90.615 -// if (!SourceUtils.isScanInProgress()) {
90.616 -// // I'm using custom GSF code here because I want to set up an explicit
90.617 -// // source path for the fake file object which includes the Python
90.618 -// // libraries (since we need them for the isSystemModule lookup
90.619 -// //SourceModel model = SourceModelFactory.getInstance().getModel(fo);
90.620 -// //if (model != null && !model.isScanInProgress()) {
90.621 -// List<FileObject> roots = new ArrayList<FileObject>(new PythonLanguage().getCoreLibraries());
90.622 -//
90.623 -// final PythonPlatformManager manager = PythonPlatformManager.getInstance();
90.624 -// final String platformName = manager.getDefaultPlatform();
90.625 -// PythonPlatform activePlatform = manager.getPlatform(platformName);
90.626 -// if (activePlatform != null) {
90.627 -// roots.addAll(activePlatform.getUniqueLibraryRoots());
90.628 -// ClassPath boot = ClassPathSupport.createClassPath(roots.toArray(new FileObject[roots.size()]));
90.629 -// ClassPath source = ClassPathSupport.createClassPath(new FileObject[]{fo.getParent()});
90.630 -// ClassPath compile = source;
90.631 -//
90.632 -// ClasspathInfo cpInfo = ClasspathInfo.create(boot, compile, source);
90.633 -// Source model = Source.create(cpInfo, fo);
90.634 -// if (model != null) {
90.635 -// final CompilationInfo[] infoHolder = new CompilationInfo[1];
90.636 -// //model.runUserActionTask(new CancellableTask<CompilationInfo>() {
90.637 -// model.runUserActionTask(new CancellableTask<CompilationController>() {
90.638 -// public void cancel() {
90.639 -// }
90.640 -//
90.641 -// //public void run(CompilationInfo info) throws Exception {
90.642 -// public void run(CompilationController info) throws Exception {
90.643 -// info.toPhase(Phase.RESOLVED);
90.644 -// infoHolder[0] = info;
90.645 -// // Force open so info.getFileObject will succeed
90.646 -// GsfUtilities.getDocument(fo, true);
90.647 -// }
90.648 -// }, false);
90.649 -// info = infoHolder[0];
90.650 -// }
90.651 -// }
90.652 -// }
90.653 - } catch (IOException ex) {
90.654 - Exceptions.printStackTrace(ex);
90.655 - }
90.656 - }
90.657 - try {
90.658 - if (info != null && info.getSnapshot().getSource().getDocument(false) != null) {
90.659 - Document doc = info.getSnapshot().getSource().getDocument(false);
90.660 - formatter.reformat(null, doc, 0, doc.getLength(), info);
90.661 - jep.setText(doc.getText(0, doc.getLength()));
90.662 - // Save file to avoid warning on exit
90.663 - DataObject dobj = DataObject.find(info.getSnapshot().getSource().getFileObject());
90.664 - SaveCookie cookie = dobj.getCookie(SaveCookie.class);
90.665 - if (cookie != null) {
90.666 - cookie.save();
90.667 - }
90.668 - } else {
90.669 - Document doc = jep.getDocument();
90.670 - if (doc.getLength() > 0) {
90.671 - doc.remove(0, doc.getLength());
90.672 - }
90.673 - doc.insertString(0, previewText, null);
90.674 - formatter.reformat(null, doc, 0, doc.getLength(), null);
90.675 - jep.setText(doc.getText(0, doc.getLength()));
90.676 - }
90.677 - } catch (DataObjectNotFoundException dof) {
90.678 - Exceptions.printStackTrace(dof);
90.679 - } catch (IOException | BadLocationException ioe) {
90.680 - Exceptions.printStackTrace(ioe);
90.681 - }
90.682 -
90.683 - if (tmpFo != null) {
90.684 - try {
90.685 - tmpFo.delete();
90.686 - } catch (IOException ex) {
90.687 - Exceptions.printStackTrace(ex);
90.688 - }
90.689 - } else if (tmp != null) {
90.690 - tmp.delete();
90.691 - }
90.692 -
90.693 -
90.694 - jep.setIgnoreRepaint(false);
90.695 - jep.scrollRectToVisible(new Rectangle(0, 0, 10, 10));
90.696 - jep.repaint(100);
90.697 - }
90.698 -
90.699 - // PreferencesCustomizer implementation --------------------------------
90.700 - @Override
90.701 - public JComponent getComponent() {
90.702 - return panel;
90.703 - }
90.704 -
90.705 - @Override
90.706 - public String getDisplayName() {
90.707 - return panel.getName();
90.708 - }
90.709 -
90.710 - @Override
90.711 - public String getId() {
90.712 - return id;
90.713 - }
90.714 -
90.715 - @Override
90.716 - public HelpCtx getHelpCtx() {
90.717 - return null;
90.718 - }
90.719 -
90.720 - // PreferencesCustomizer.Factory implementation ------------------------
90.721 - public static final class Factory implements PreferencesCustomizer.Factory {
90.722 - private final String id;
90.723 - private final Class<? extends JPanel> panelClass;
90.724 - private final String previewText;
90.725 - private final String[][] forcedOptions;
90.726 -
90.727 - public Factory(String id, Class<? extends JPanel> panelClass, String previewText, String[]... forcedOptions) {
90.728 - this.id = id;
90.729 - this.panelClass = panelClass;
90.730 - this.previewText = previewText;
90.731 - this.forcedOptions = forcedOptions;
90.732 - }
90.733 -
90.734 - @Override
90.735 - public PreferencesCustomizer create(Preferences preferences) {
90.736 - try {
90.737 - return new CategorySupport(preferences, id, panelClass.newInstance(), previewText, forcedOptions);
90.738 - } catch (IllegalAccessException | InstantiationException e) {
90.739 - return null;
90.740 - }
90.741 - }
90.742 - } // End of CategorySupport.Factory class
90.743 -
90.744 - // Private methods -----------------------------------------------------
90.745 - private void performOperation(int operation, JComponent jc, String optionID, Preferences p) {
90.746 - switch (operation) {
90.747 - case LOAD:
90.748 - loadData(jc, optionID, p);
90.749 - break;
90.750 - case STORE:
90.751 - storeData(jc, optionID, p);
90.752 - break;
90.753 - case ADD_LISTENERS:
90.754 - addListener(jc);
90.755 - break;
90.756 - }
90.757 - }
90.758 -
90.759 - private void scan(int what, Preferences p) {
90.760 - for (JComponent jc : components) {
90.761 - Object o = jc.getClientProperty(OPTION_ID);
90.762 - if (o instanceof String) {
90.763 - performOperation(what, jc, (String)o, p);
90.764 - } else if (o instanceof String[]) {
90.765 - for (String oid : (String[])o) {
90.766 - performOperation(what, jc, oid, p);
90.767 - }
90.768 - }
90.769 - }
90.770 - }
90.771 -
90.772 - private void scan(Container container, List<JComponent> components) {
90.773 - for (Component c : container.getComponents()) {
90.774 - if (c instanceof JComponent) {
90.775 - JComponent jc = (JComponent)c;
90.776 - Object o = jc.getClientProperty(OPTION_ID);
90.777 - if (o instanceof String || o instanceof String[]) {
90.778 - components.add(jc);
90.779 - }
90.780 - }
90.781 - if (c instanceof Container) {
90.782 - scan((Container)c, components);
90.783 - }
90.784 - }
90.785 - }
90.786 -
90.787 - /** Very smart method which tries to set the values in the components correctly
90.788 - */
90.789 - private void loadData(JComponent jc, String optionID, Preferences node) {
90.790 -
90.791 - if (jc instanceof JTextField) {
90.792 - JTextField field = (JTextField)jc;
90.793 - field.setText(node.get(optionID, getDefaultAsString(optionID)));
90.794 - } else if (jc instanceof JCheckBox) {
90.795 - JCheckBox checkBox = (JCheckBox)jc;
90.796 - boolean df = getDefaultAsBoolean(optionID);
90.797 - checkBox.setSelected(node.getBoolean(optionID, df));
90.798 - } else if (jc instanceof JComboBox) {
90.799 - JComboBox cb = (JComboBox)jc;
90.800 - String value = node.get(optionID, getDefaultAsString(optionID));
90.801 - ComboBoxModel model = createModel(value);
90.802 - cb.setModel(model);
90.803 - ComboItem item = whichItem(value, model);
90.804 - cb.setSelectedItem(item);
90.805 - }
90.806 -
90.807 - }
90.808 -
90.809 - private void storeData(JComponent jc, String optionID, Preferences node) {
90.810 -
90.811 - if (jc instanceof JTextField) {
90.812 - JTextField field = (JTextField)jc;
90.813 -
90.814 - String text = field.getText();
90.815 -
90.816 - // XXX test for numbers
90.817 - if (isInteger(optionID)) {
90.818 - try {
90.819 - int i = Integer.parseInt(text);
90.820 - } catch (NumberFormatException e) {
90.821 - return;
90.822 - }
90.823 - }
90.824 -
90.825 - // XXX: watch out, tabSize, spacesPerTab, indentSize and expandTabToSpaces
90.826 - // fall back on getGlopalXXX() values and not getDefaultAsXXX value,
90.827 - // which is why we must not remove them. Proper solution would be to
90.828 - // store formatting preferences to MimeLookup and not use NbPreferences.
90.829 - // The problem currently is that MimeLookup based Preferences do not support subnodes.
90.830 - if (!optionID.equals(tabSize) &&
90.831 - !optionID.equals(spacesPerTab) && !optionID.equals(indentSize) &&
90.832 - getDefaultAsString(optionID).equals(text)) {
90.833 - node.remove(optionID);
90.834 - } else {
90.835 - node.put(optionID, text);
90.836 - }
90.837 - } else if (jc instanceof JCheckBox) {
90.838 - JCheckBox checkBox = (JCheckBox)jc;
90.839 - if (!optionID.equals(expandTabToSpaces) && getDefaultAsBoolean(optionID) == checkBox.isSelected()) {
90.840 - node.remove(optionID);
90.841 - } else {
90.842 - node.putBoolean(optionID, checkBox.isSelected());
90.843 - }
90.844 - } else if (jc instanceof JComboBox) {
90.845 - JComboBox cb = (JComboBox)jc;
90.846 - // Logger.global.info( cb.getSelectedItem() + " " + optionID);
90.847 - String value = ((ComboItem)cb.getSelectedItem()).value;
90.848 - if (getDefaultAsString(optionID).equals(value)) {
90.849 - node.remove(optionID);
90.850 - } else {
90.851 - node.put(optionID, value);
90.852 - }
90.853 - }
90.854 - }
90.855 -
90.856 - private void addListener(JComponent jc) {
90.857 - if (jc instanceof JTextField) {
90.858 - JTextField field = (JTextField)jc;
90.859 - field.addActionListener(this);
90.860 - field.getDocument().addDocumentListener(this);
90.861 - } else if (jc instanceof JCheckBox) {
90.862 - JCheckBox checkBox = (JCheckBox)jc;
90.863 - checkBox.addActionListener(this);
90.864 - } else if (jc instanceof JComboBox) {
90.865 - JComboBox cb = (JComboBox)jc;
90.866 - cb.addActionListener(this);
90.867 - }
90.868 - }
90.869 -
90.870 - private ComboBoxModel createModel(String value) {
90.871 -
90.872 - // is it imports?
90.873 - for (ComboItem comboItem : cleanupImports) {
90.874 - if (value.equals(comboItem.value)) {
90.875 - return new DefaultComboBoxModel(cleanupImports);
90.876 - }
90.877 - }
90.878 -
90.879 - // is it wrap
90.880 - for (ComboItem comboItem : wrap) {
90.881 - if (value.equals(comboItem.value)) {
90.882 - return new DefaultComboBoxModel(wrap);
90.883 - }
90.884 - }
90.885 -
90.886 - return null;
90.887 - }
90.888 -
90.889 - private static ComboItem whichItem(String value, ComboBoxModel model) {
90.890 -
90.891 - for (int i = 0; i < model.getSize(); i++) {
90.892 - ComboItem item = (ComboItem)model.getElementAt(i);
90.893 - if (value.equals(item.value)) {
90.894 - return item;
90.895 - }
90.896 - }
90.897 - return null;
90.898 - }
90.899 -
90.900 - private static class ComboItem {
90.901 - String value;
90.902 - String displayName;
90.903 -
90.904 - public ComboItem(String value, String key) {
90.905 - this.value = value;
90.906 - this.displayName = NbBundle.getMessage(FmtOptions.class, key);
90.907 - }
90.908 -
90.909 - @Override
90.910 - public String toString() {
90.911 - return displayName;
90.912 - }
90.913 - }
90.914 - }
90.915 -
90.916 - public static class PreviewPreferences extends AbstractPreferences {
90.917 - private Map<String, Object> map = new HashMap<>();
90.918 -
90.919 - public PreviewPreferences() {
90.920 - super(null, ""); // NOI18N
90.921 - }
90.922 -
90.923 - @Override
90.924 - protected void putSpi(String key, String value) {
90.925 - map.put(key, value);
90.926 - }
90.927 -
90.928 - @Override
90.929 - protected String getSpi(String key) {
90.930 - return (String)map.get(key);
90.931 - }
90.932 -
90.933 - @Override
90.934 - protected void removeSpi(String key) {
90.935 - map.remove(key);
90.936 - }
90.937 -
90.938 - @Override
90.939 - protected void removeNodeSpi() throws BackingStoreException {
90.940 - throw new UnsupportedOperationException("Not supported yet.");
90.941 - }
90.942 -
90.943 - @Override
90.944 - protected String[] keysSpi() throws BackingStoreException {
90.945 - String array[] = new String[map.keySet().size()];
90.946 - return map.keySet().toArray(array);
90.947 - }
90.948 -
90.949 - @Override
90.950 - protected String[] childrenNamesSpi() throws BackingStoreException {
90.951 - throw new UnsupportedOperationException("Not supported yet.");
90.952 - }
90.953 -
90.954 - @Override
90.955 - protected AbstractPreferences childSpi(String name) {
90.956 - throw new UnsupportedOperationException("Not supported yet.");
90.957 - }
90.958 -
90.959 - @Override
90.960 - protected void syncSpi() throws BackingStoreException {
90.961 - throw new UnsupportedOperationException("Not supported yet.");
90.962 - }
90.963 -
90.964 - @Override
90.965 - protected void flushSpi() throws BackingStoreException {
90.966 - throw new UnsupportedOperationException("Not supported yet.");
90.967 - }
90.968 - }
90.969 -
90.970 - // read-only, no subnodes
90.971 - public static final class ProxyPreferences extends AbstractPreferences {
90.972 - private final Preferences[] delegates;
90.973 -
90.974 - public ProxyPreferences(Preferences... delegates) {
90.975 - super(null, ""); // NOI18N
90.976 - this.delegates = delegates;
90.977 - }
90.978 -
90.979 - @Override
90.980 - protected void putSpi(String key, String value) {
90.981 - throw new UnsupportedOperationException("Not supported yet.");
90.982 - }
90.983 -
90.984 - @Override
90.985 - protected String getSpi(String key) {
90.986 - for (Preferences p : delegates) {
90.987 - String value = p.get(key, null);
90.988 - if (value != null) {
90.989 - return value;
90.990 - }
90.991 - }
90.992 - return null;
90.993 - }
90.994 -
90.995 - @Override
90.996 - protected void removeSpi(String key) {
90.997 - throw new UnsupportedOperationException("Not supported yet.");
90.998 - }
90.999 -
90.1000 - @Override
90.1001 - protected void removeNodeSpi() throws BackingStoreException {
90.1002 - throw new UnsupportedOperationException("Not supported yet.");
90.1003 - }
90.1004 -
90.1005 - @Override
90.1006 - protected String[] keysSpi() throws BackingStoreException {
90.1007 - Set<String> keys = new HashSet<>();
90.1008 - for (Preferences p : delegates) {
90.1009 - keys.addAll(Arrays.asList(p.keys()));
90.1010 - }
90.1011 - return keys.toArray(new String[keys.size()]);
90.1012 - }
90.1013 -
90.1014 - @Override
90.1015 - protected String[] childrenNamesSpi() throws BackingStoreException {
90.1016 - throw new UnsupportedOperationException("Not supported yet.");
90.1017 - }
90.1018 -
90.1019 - @Override
90.1020 - protected AbstractPreferences childSpi(String name) {
90.1021 - throw new UnsupportedOperationException("Not supported yet.");
90.1022 - }
90.1023 -
90.1024 - @Override
90.1025 - protected void syncSpi() throws BackingStoreException {
90.1026 - throw new UnsupportedOperationException("Not supported yet.");
90.1027 - }
90.1028 -
90.1029 - @Override
90.1030 - protected void flushSpi() throws BackingStoreException {
90.1031 - throw new UnsupportedOperationException("Not supported yet.");
90.1032 - }
90.1033 - } // End of ProxyPreferences class
90.1034 -
90.1035 - public static interface CodeStyleProducer {
90.1036 - public CodeStyle create(Preferences preferences);
90.1037 - }
90.1038 -}
91.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtSpaces.form Fri Sep 18 16:20:24 2015 -0500
91.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
91.3 @@ -1,104 +0,0 @@
91.4 -<?xml version="1.0" encoding="UTF-8" ?>
91.5 -
91.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
91.7 - <Properties>
91.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Spaces" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.10 - </Property>
91.11 - <Property name="opaque" type="boolean" value="false"/>
91.12 - </Properties>
91.13 - <AuxValues>
91.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
91.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
91.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
91.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
91.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
91.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
91.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
91.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
91.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
91.23 - </AuxValues>
91.24 -
91.25 - <Layout>
91.26 - <DimensionLayout dim="0">
91.27 - <Group type="103" groupAlignment="0" attributes="0">
91.28 - <Group type="102" attributes="0">
91.29 - <Group type="103" groupAlignment="0" attributes="0">
91.30 - <Component id="addAroundOp" alignment="0" min="-2" max="-2" attributes="0"/>
91.31 - <Group type="102" alignment="0" attributes="0">
91.32 - <EmptySpace min="27" pref="27" max="27" attributes="0"/>
91.33 - <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
91.34 - </Group>
91.35 - <Component id="removeInParen" alignment="0" min="-2" max="-2" attributes="0"/>
91.36 - <Component id="addAfterComma" alignment="0" min="-2" max="-2" attributes="0"/>
91.37 - <Component id="removeBeforeSep" alignment="0" min="-2" max="-2" attributes="0"/>
91.38 - <Component id="collapseSpacesCb" alignment="0" min="-2" max="-2" attributes="0"/>
91.39 - </Group>
91.40 - <EmptySpace max="32767" attributes="0"/>
91.41 - </Group>
91.42 - </Group>
91.43 - </DimensionLayout>
91.44 - <DimensionLayout dim="1">
91.45 - <Group type="103" groupAlignment="0" attributes="0">
91.46 - <Group type="102" alignment="0" attributes="0">
91.47 - <Component id="addAroundOp" min="-2" max="-2" attributes="0"/>
91.48 - <EmptySpace max="-2" attributes="0"/>
91.49 - <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
91.50 - <EmptySpace max="-2" attributes="0"/>
91.51 - <Component id="removeInParen" min="-2" max="-2" attributes="0"/>
91.52 - <EmptySpace max="-2" attributes="0"/>
91.53 - <Component id="addAfterComma" min="-2" max="-2" attributes="0"/>
91.54 - <EmptySpace max="-2" attributes="0"/>
91.55 - <Component id="removeBeforeSep" min="-2" max="-2" attributes="0"/>
91.56 - <EmptySpace max="-2" attributes="0"/>
91.57 - <Component id="collapseSpacesCb" min="-2" max="-2" attributes="0"/>
91.58 - <EmptySpace max="32767" attributes="0"/>
91.59 - </Group>
91.60 - </Group>
91.61 - </DimensionLayout>
91.62 - </Layout>
91.63 - <SubComponents>
91.64 - <Component class="javax.swing.JCheckBox" name="addAroundOp">
91.65 - <Properties>
91.66 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.67 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAroundOp.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.68 - </Property>
91.69 - </Properties>
91.70 - </Component>
91.71 - <Component class="javax.swing.JCheckBox" name="removeInParam">
91.72 - <Properties>
91.73 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.74 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParam.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.75 - </Property>
91.76 - </Properties>
91.77 - </Component>
91.78 - <Component class="javax.swing.JCheckBox" name="removeInParen">
91.79 - <Properties>
91.80 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.81 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.82 - </Property>
91.83 - </Properties>
91.84 - </Component>
91.85 - <Component class="javax.swing.JCheckBox" name="addAfterComma">
91.86 - <Properties>
91.87 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.88 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAfterComma.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.89 - </Property>
91.90 - </Properties>
91.91 - </Component>
91.92 - <Component class="javax.swing.JCheckBox" name="removeBeforeSep">
91.93 - <Properties>
91.94 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.95 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeBeforeSep.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.96 - </Property>
91.97 - </Properties>
91.98 - </Component>
91.99 - <Component class="javax.swing.JCheckBox" name="collapseSpacesCb">
91.100 - <Properties>
91.101 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
91.102 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.collapseSpacesCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
91.103 - </Property>
91.104 - </Properties>
91.105 - </Component>
91.106 - </SubComponents>
91.107 -</Form>
92.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtSpaces.java Fri Sep 18 16:20:24 2015 -0500
92.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
92.3 @@ -1,143 +0,0 @@
92.4 -/*
92.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
92.6 - *
92.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
92.8 - *
92.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
92.10 - * Other names may be trademarks of their respective owners.
92.11 - *
92.12 - * The contents of this file are subject to the terms of either the GNU
92.13 - * General Public License Version 2 only ("GPL") or the Common
92.14 - * Development and Distribution License("CDDL") (collectively, the
92.15 - * "License"). You may not use this file except in compliance with the
92.16 - * License. You can obtain a copy of the License at
92.17 - * http://www.netbeans.org/cddl-gplv2.html
92.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
92.19 - * specific language governing permissions and limitations under the
92.20 - * License. When distributing the software, include this License Header
92.21 - * Notice in each file and include the License file at
92.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
92.23 - * particular file as subject to the "Classpath" exception as provided
92.24 - * by Oracle in the GPL Version 2 section of the License file that
92.25 - * accompanied this code. If applicable, add the following below the
92.26 - * License Header, with the fields enclosed by brackets [] replaced by
92.27 - * your own identifying information:
92.28 - * "Portions Copyrighted [year] [name of copyright owner]"
92.29 - *
92.30 - * Contributor(s):
92.31 - *
92.32 - * The Original Software is NetBeans. The Initial Developer of the Original
92.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
92.34 - * Microsystems, Inc. All Rights Reserved.
92.35 - *
92.36 - * If you wish your version of this file to be governed by only the CDDL
92.37 - * or only the GPL Version 2, indicate your decision by adding
92.38 - * "[Contributor] elects to include this software in this distribution
92.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
92.40 - * single choice of license, a recipient has the option to distribute
92.41 - * your version of this file under either the CDDL, the GPL Version 2 or
92.42 - * to extend the choice of license to its licensees as provided above.
92.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
92.44 - * Version 2 license, then the option applies only if the new code is
92.45 - * made subject to such option by the copyright holder.
92.46 - */
92.47 -
92.48 -package org.netbeans.modules.python.editor.options;
92.49 -
92.50 -import javax.swing.JPanel;
92.51 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
92.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
92.53 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
92.54 -
92.55 -/**
92.56 - * Preferences for formatting related to spaces
92.57 - *
92.58 - * @author Tor Norbye
92.59 - */
92.60 -public class FmtSpaces extends JPanel {
92.61 - public FmtSpaces() {
92.62 - initComponents();
92.63 -
92.64 - addAroundOp.putClientProperty(OPTION_ID, addSpaceAroundOperators);
92.65 - addAfterComma.putClientProperty(OPTION_ID, addSpaceAfterComma);
92.66 - removeBeforeSep.putClientProperty(OPTION_ID, removeSpaceBeforeSep);
92.67 - removeInParam.putClientProperty(OPTION_ID, removeSpaceInParamAssign);
92.68 - removeInParen.putClientProperty(OPTION_ID, removeSpaceInParens);
92.69 - collapseSpacesCb.putClientProperty(OPTION_ID, collapseSpaces);
92.70 - }
92.71 -
92.72 - public static PreferencesCustomizer.Factory getController() {
92.73 - return new CategorySupport.Factory("spaces", FmtSpaces.class, // NOI18N
92.74 - org.openide.util.NbBundle.getMessage(FmtSpaces.class, "SAMPLE_Spaces"));
92.75 - }
92.76 -
92.77 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
92.78 - private void initComponents() {
92.79 -
92.80 - addAroundOp = new javax.swing.JCheckBox();
92.81 - removeInParam = new javax.swing.JCheckBox();
92.82 - removeInParen = new javax.swing.JCheckBox();
92.83 - addAfterComma = new javax.swing.JCheckBox();
92.84 - removeBeforeSep = new javax.swing.JCheckBox();
92.85 - collapseSpacesCb = new javax.swing.JCheckBox();
92.86 -
92.87 - setName(org.openide.util.NbBundle.getMessage(FmtSpaces.class, "LBL_Spaces")); // NOI18N
92.88 - setOpaque(false);
92.89 -
92.90 - org.openide.awt.Mnemonics.setLocalizedText(addAroundOp, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAroundOp.text")); // NOI18N
92.91 -
92.92 - org.openide.awt.Mnemonics.setLocalizedText(removeInParam, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParam.text")); // NOI18N
92.93 -
92.94 - org.openide.awt.Mnemonics.setLocalizedText(removeInParen, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParen.text")); // NOI18N
92.95 -
92.96 - org.openide.awt.Mnemonics.setLocalizedText(addAfterComma, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAfterComma.text")); // NOI18N
92.97 -
92.98 - org.openide.awt.Mnemonics.setLocalizedText(removeBeforeSep, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeBeforeSep.text")); // NOI18N
92.99 -
92.100 - org.openide.awt.Mnemonics.setLocalizedText(collapseSpacesCb, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.collapseSpacesCb.text")); // NOI18N
92.101 -
92.102 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
92.103 - this.setLayout(layout);
92.104 - layout.setHorizontalGroup(
92.105 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
92.106 - .addGroup(layout.createSequentialGroup()
92.107 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
92.108 - .addComponent(addAroundOp)
92.109 - .addGroup(layout.createSequentialGroup()
92.110 - .addGap(27, 27, 27)
92.111 - .addComponent(removeInParam))
92.112 - .addComponent(removeInParen)
92.113 - .addComponent(addAfterComma)
92.114 - .addComponent(removeBeforeSep)
92.115 - .addComponent(collapseSpacesCb))
92.116 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
92.117 - );
92.118 - layout.setVerticalGroup(
92.119 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
92.120 - .addGroup(layout.createSequentialGroup()
92.121 - .addComponent(addAroundOp)
92.122 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
92.123 - .addComponent(removeInParam)
92.124 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
92.125 - .addComponent(removeInParen)
92.126 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
92.127 - .addComponent(addAfterComma)
92.128 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
92.129 - .addComponent(removeBeforeSep)
92.130 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
92.131 - .addComponent(collapseSpacesCb)
92.132 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
92.133 - );
92.134 - }// </editor-fold>//GEN-END:initComponents
92.135 -
92.136 -
92.137 - // Variables declaration - do not modify//GEN-BEGIN:variables
92.138 - private javax.swing.JCheckBox addAfterComma;
92.139 - private javax.swing.JCheckBox addAroundOp;
92.140 - private javax.swing.JCheckBox collapseSpacesCb;
92.141 - private javax.swing.JCheckBox removeBeforeSep;
92.142 - private javax.swing.JCheckBox removeInParam;
92.143 - private javax.swing.JCheckBox removeInParen;
92.144 - // End of variables declaration//GEN-END:variables
92.145 -
92.146 -}
93.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtTabsIndents.form Fri Sep 18 16:20:24 2015 -0500
93.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
93.3 @@ -1,127 +0,0 @@
93.4 -<?xml version="1.0" encoding="UTF-8" ?>
93.5 -
93.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
93.7 - <Properties>
93.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
93.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_TabsAndIndents" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
93.10 - </Property>
93.11 - <Property name="opaque" type="boolean" value="false"/>
93.12 - </Properties>
93.13 - <AuxValues>
93.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
93.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
93.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
93.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
93.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
93.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
93.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
93.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
93.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
93.23 - </AuxValues>
93.24 -
93.25 - <Layout>
93.26 - <DimensionLayout dim="0">
93.27 - <Group type="103" groupAlignment="0" attributes="0">
93.28 - <Group type="102" alignment="0" attributes="0">
93.29 - <Group type="103" groupAlignment="0" attributes="0">
93.30 - <Component id="continuationIndentSizeLabel" max="32767" attributes="0"/>
93.31 - <Component id="labelIndentLabel" min="-2" max="-2" attributes="0"/>
93.32 - </Group>
93.33 - <EmptySpace max="-2" attributes="0"/>
93.34 - <Group type="103" groupAlignment="1" attributes="0">
93.35 - <Component id="continuationIndentSizeField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
93.36 - <Component id="labelIndentField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
93.37 - </Group>
93.38 - </Group>
93.39 - <Component id="indentCasesFromSwitchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
93.40 - <Component id="indentTopLevelClassMembersCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
93.41 - <Component id="absoluteLabelIndentCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
93.42 - </Group>
93.43 - </DimensionLayout>
93.44 - <DimensionLayout dim="1">
93.45 - <Group type="103" groupAlignment="0" attributes="0">
93.46 - <Group type="102" attributes="0">
93.47 - <EmptySpace max="-2" attributes="0"/>
93.48 - <Group type="103" groupAlignment="3" attributes="0">
93.49 - <Component id="continuationIndentSizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
93.50 - <Component id="continuationIndentSizeField" alignment="3" min="-2" max="-2" attributes="0"/>
93.51 - </Group>
93.52 - <EmptySpace min="-2" max="-2" attributes="0"/>
93.53 - <Group type="103" groupAlignment="3" attributes="0">
93.54 - <Component id="labelIndentLabel" alignment="3" min="-2" max="-2" attributes="0"/>
93.55 - <Component id="labelIndentField" alignment="3" min="-2" max="-2" attributes="0"/>
93.56 - </Group>
93.57 - <EmptySpace type="unrelated" max="-2" attributes="0"/>
93.58 - <Component id="absoluteLabelIndentCheckBox" min="-2" max="-2" attributes="0"/>
93.59 - <EmptySpace max="-2" attributes="0"/>
93.60 - <Component id="indentTopLevelClassMembersCheckBox" min="-2" max="-2" attributes="0"/>
93.61 - <EmptySpace max="-2" attributes="0"/>
93.62 - <Component id="indentCasesFromSwitchCheckBox" min="-2" max="-2" attributes="0"/>
93.63 - <EmptySpace max="32767" attributes="0"/>
93.64 - </Group>
93.65 - </Group>
93.66 - </DimensionLayout>
93.67 - </Layout>
93.68 - <SubComponents>
93.69 - <Component class="javax.swing.JLabel" name="continuationIndentSizeLabel">
93.70 - <Properties>
93.71 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
93.72 - <ComponentRef name="continuationIndentSizeField"/>
93.73 - </Property>
93.74 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
93.75 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_ContinuationIndentSize" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
93.76 - </Property>
93.77 - </Properties>
93.78 - </Component>
93.79 - <Component class="javax.swing.JTextField" name="continuationIndentSizeField">
93.80 - </Component>
93.81 - <Component class="javax.swing.JLabel" name="labelIndentLabel">
93.82 - <Properties>
93.83 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
93.84 - <ComponentRef name="labelIndentField"/>
93.85 - </Property>
93.86 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
93.87 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_LabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
93.88 - </Property>
93.89 - </Properties>
93.90 - </Component>
93.91 - <Component class="javax.swing.JTextField" name="labelIndentField">
93.92 - </Component>
93.93 - <Component class="javax.swing.JCheckBox" name="absoluteLabelIndentCheckBox">
93.94 - <Properties>
93.95 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
93.96 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_AbsoluteLabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
93.97 - </Property>
93.98 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
93.99 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
93.100 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
93.101 - </Border>
93.102 - </Property>
93.103 - </Properties>
93.104 - </Component>
93.105 - <Component class="javax.swing.JCheckBox" name="indentTopLevelClassMembersCheckBox">
93.106 - <Properties>
93.107 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
93.108 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentTopLevelClassMemberts" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
93.109 - </Property>
93.110 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
93.111 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
93.112 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
93.113 - </Border>
93.114 - </Property>
93.115 - </Properties>
93.116 - </Component>
93.117 - <Component class="javax.swing.JCheckBox" name="indentCasesFromSwitchCheckBox">
93.118 - <Properties>
93.119 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
93.120 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentCasesFromSwitch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
93.121 - </Property>
93.122 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
93.123 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
93.124 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
93.125 - </Border>
93.126 - </Property>
93.127 - </Properties>
93.128 - </Component>
93.129 - </SubComponents>
93.130 -</Form>
94.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtTabsIndents.java Fri Sep 18 16:20:24 2015 -0500
94.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
94.3 @@ -1,196 +0,0 @@
94.4 -/*
94.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
94.6 - *
94.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
94.8 - *
94.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
94.10 - * Other names may be trademarks of their respective owners.
94.11 - *
94.12 - * The contents of this file are subject to the terms of either the GNU
94.13 - * General Public License Version 2 only ("GPL") or the Common
94.14 - * Development and Distribution License("CDDL") (collectively, the
94.15 - * "License"). You may not use this file except in compliance with the
94.16 - * License. You can obtain a copy of the License at
94.17 - * http://www.netbeans.org/cddl-gplv2.html
94.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
94.19 - * specific language governing permissions and limitations under the
94.20 - * License. When distributing the software, include this License Header
94.21 - * Notice in each file and include the License file at
94.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
94.23 - * particular file as subject to the "Classpath" exception as provided
94.24 - * by Oracle in the GPL Version 2 section of the License file that
94.25 - * accompanied this code. If applicable, add the following below the
94.26 - * License Header, with the fields enclosed by brackets [] replaced by
94.27 - * your own identifying information:
94.28 - * "Portions Copyrighted [year] [name of copyright owner]"
94.29 - *
94.30 - * Contributor(s):
94.31 - *
94.32 - * The Original Software is NetBeans. The Initial Developer of the Original
94.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
94.34 - * Microsystems, Inc. All Rights Reserved.
94.35 - *
94.36 - * If you wish your version of this file to be governed by only the CDDL
94.37 - * or only the GPL Version 2, indicate your decision by adding
94.38 - * "[Contributor] elects to include this software in this distribution
94.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
94.40 - * single choice of license, a recipient has the option to distribute
94.41 - * your version of this file under either the CDDL, the GPL Version 2 or
94.42 - * to extend the choice of license to its licensees as provided above.
94.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
94.44 - * Version 2 license, then the option applies only if the new code is
94.45 - * made subject to such option by the copyright holder.
94.46 - */
94.47 -
94.48 -package org.netbeans.modules.python.editor.options;
94.49 -
94.50 -import org.netbeans.modules.python.editor.options.CodeStyle.WrapStyle;
94.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
94.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
94.53 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
94.54 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
94.55 -
94.56 -/**
94.57 - *
94.58 - * @author phrebejk
94.59 - */
94.60 -public class FmtTabsIndents extends javax.swing.JPanel {
94.61 -
94.62 - /** Creates new form FmtTabsIndents */
94.63 - public FmtTabsIndents() {
94.64 - initComponents();
94.65 -/*
94.66 -// expandTabCheckBox.putClientProperty(OPTION_ID, expandTabToSpaces);
94.67 -// tabSizeField.putClientProperty(OPTION_ID, tabSize);
94.68 -// indentSizeField.putClientProperty(OPTION_ID, new String [] { indentSize, spacesPerTab });
94.69 - continuationIndentSizeField.putClientProperty(OPTION_ID, continuationIndentSize);
94.70 - labelIndentField.putClientProperty(OPTION_ID, labelIndent);
94.71 - absoluteLabelIndentCheckBox.putClientProperty(OPTION_ID, absoluteLabelIndent);
94.72 - indentTopLevelClassMembersCheckBox.putClientProperty(OPTION_ID, indentTopLevelClassMembers);
94.73 - indentCasesFromSwitchCheckBox.putClientProperty(OPTION_ID, indentCasesFromSwitch);
94.74 -// rightMarginField.putClientProperty(OPTION_ID, rightMargin);
94.75 - }
94.76 -
94.77 - public static PreferencesCustomizer.Factory getController() {
94.78 - return new CategorySupport.Factory(PreferencesCustomizer.TABS_AND_INDENTS_ID, FmtTabsIndents.class, //NOI18N
94.79 - org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "SAMPLE_TabsIndents"), // NOI18N
94.80 - new String[] { FmtOptions.rightMargin, "30" }, //NOI18N
94.81 - new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
94.82 - new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
94.83 - new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
94.84 - new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
94.85 - new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
94.86 - new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
94.87 - new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
94.88 - new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
94.89 - new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
94.90 - new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
94.91 - new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
94.92 - new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
94.93 - new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
94.94 - new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
94.95 - new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
94.96 - new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
94.97 - new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
94.98 - new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
94.99 - new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
94.100 - new String[] { FmtOptions.alignMultilineArrayInit, Boolean.FALSE.toString() },
94.101 - new String[] { FmtOptions.alignMultilineAssignment, Boolean.FALSE.toString() },
94.102 - new String[] { FmtOptions.alignMultilineBinaryOp, Boolean.FALSE.toString() },
94.103 - new String[] { FmtOptions.alignMultilineCallArgs, Boolean.FALSE.toString() },
94.104 - new String[] { FmtOptions.alignMultilineFor, Boolean.FALSE.toString() },
94.105 - new String[] { FmtOptions.alignMultilineImplements, Boolean.FALSE.toString() },
94.106 - new String[] { FmtOptions.alignMultilineMethodParams, Boolean.FALSE.toString() },
94.107 - new String[] { FmtOptions.alignMultilineParenthesized, Boolean.FALSE.toString() },
94.108 - new String[] { FmtOptions.alignMultilineTernaryOp, Boolean.FALSE.toString() },
94.109 - new String[] { FmtOptions.alignMultilineThrows, Boolean.FALSE.toString() }
94.110 - );
94.111 - */
94.112 - }
94.113 -
94.114 - /** This method is called from within the constructor to
94.115 - * initialize the form.
94.116 - * WARNING: Do NOT modify this code. The content of this method is
94.117 - * always regenerated by the Form Editor.
94.118 - */
94.119 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
94.120 - private void initComponents() {
94.121 -
94.122 - continuationIndentSizeLabel = new javax.swing.JLabel();
94.123 - continuationIndentSizeField = new javax.swing.JTextField();
94.124 - labelIndentLabel = new javax.swing.JLabel();
94.125 - labelIndentField = new javax.swing.JTextField();
94.126 - absoluteLabelIndentCheckBox = new javax.swing.JCheckBox();
94.127 - indentTopLevelClassMembersCheckBox = new javax.swing.JCheckBox();
94.128 - indentCasesFromSwitchCheckBox = new javax.swing.JCheckBox();
94.129 -
94.130 - setName(org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_TabsAndIndents")); // NOI18N
94.131 - setOpaque(false);
94.132 -
94.133 - continuationIndentSizeLabel.setLabelFor(continuationIndentSizeField);
94.134 - org.openide.awt.Mnemonics.setLocalizedText(continuationIndentSizeLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_ContinuationIndentSize")); // NOI18N
94.135 -
94.136 - labelIndentLabel.setLabelFor(labelIndentField);
94.137 - org.openide.awt.Mnemonics.setLocalizedText(labelIndentLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_LabelIndent")); // NOI18N
94.138 -
94.139 - org.openide.awt.Mnemonics.setLocalizedText(absoluteLabelIndentCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_AbsoluteLabelIndent")); // NOI18N
94.140 - absoluteLabelIndentCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
94.141 -
94.142 - org.openide.awt.Mnemonics.setLocalizedText(indentTopLevelClassMembersCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentTopLevelClassMemberts")); // NOI18N
94.143 - indentTopLevelClassMembersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
94.144 -
94.145 - org.openide.awt.Mnemonics.setLocalizedText(indentCasesFromSwitchCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentCasesFromSwitch")); // NOI18N
94.146 - indentCasesFromSwitchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
94.147 -
94.148 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
94.149 - this.setLayout(layout);
94.150 - layout.setHorizontalGroup(
94.151 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
94.152 - .addGroup(layout.createSequentialGroup()
94.153 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
94.154 - .addComponent(continuationIndentSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
94.155 - .addComponent(labelIndentLabel))
94.156 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
94.157 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
94.158 - .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
94.159 - .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)))
94.160 - .addComponent(indentCasesFromSwitchCheckBox)
94.161 - .addComponent(indentTopLevelClassMembersCheckBox)
94.162 - .addComponent(absoluteLabelIndentCheckBox)
94.163 - );
94.164 -
94.165 - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {continuationIndentSizeField, labelIndentField});
94.166 -
94.167 - layout.setVerticalGroup(
94.168 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
94.169 - .addGroup(layout.createSequentialGroup()
94.170 - .addContainerGap()
94.171 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
94.172 - .addComponent(continuationIndentSizeLabel)
94.173 - .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
94.174 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
94.175 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
94.176 - .addComponent(labelIndentLabel)
94.177 - .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
94.178 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
94.179 - .addComponent(absoluteLabelIndentCheckBox)
94.180 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
94.181 - .addComponent(indentTopLevelClassMembersCheckBox)
94.182 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
94.183 - .addComponent(indentCasesFromSwitchCheckBox)
94.184 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
94.185 - );
94.186 - }// </editor-fold>//GEN-END:initComponents
94.187 -
94.188 -
94.189 - // Variables declaration - do not modify//GEN-BEGIN:variables
94.190 - private javax.swing.JCheckBox absoluteLabelIndentCheckBox;
94.191 - private javax.swing.JTextField continuationIndentSizeField;
94.192 - private javax.swing.JLabel continuationIndentSizeLabel;
94.193 - private javax.swing.JCheckBox indentCasesFromSwitchCheckBox;
94.194 - private javax.swing.JCheckBox indentTopLevelClassMembersCheckBox;
94.195 - private javax.swing.JTextField labelIndentField;
94.196 - private javax.swing.JLabel labelIndentLabel;
94.197 - // End of variables declaration//GEN-END:variables
94.198 -
94.199 -}
95.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtWrapping.form Fri Sep 18 16:20:24 2015 -0500
95.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
95.3 @@ -1,706 +0,0 @@
95.4 -<?xml version="1.0" encoding="UTF-8" ?>
95.5 -
95.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
95.7 - <Properties>
95.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Wrapping" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.10 - </Property>
95.11 - <Property name="opaque" type="boolean" value="false"/>
95.12 - </Properties>
95.13 - <AuxValues>
95.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
95.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
95.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
95.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
95.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
95.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
95.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
95.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
95.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
95.23 - <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,45,0,0,1,42"/>
95.24 - </AuxValues>
95.25 -
95.26 - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
95.27 - <SubComponents>
95.28 - <Container class="javax.swing.JScrollPane" name="scrollPane">
95.29 - <Properties>
95.30 - <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
95.31 - <Dimension value="[300, 200]"/>
95.32 - </Property>
95.33 - <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
95.34 - <Dimension value="[350, 600]"/>
95.35 - </Property>
95.36 - </Properties>
95.37 - <Constraints>
95.38 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
95.39 - <BorderConstraints direction="Center"/>
95.40 - </Constraint>
95.41 - </Constraints>
95.42 -
95.43 - <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
95.44 - <SubComponents>
95.45 - <Container class="javax.swing.JPanel" name="panel1">
95.46 - <Properties>
95.47 - <Property name="opaque" type="boolean" value="false"/>
95.48 - </Properties>
95.49 -
95.50 - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
95.51 - <SubComponents>
95.52 - <Component class="javax.swing.JLabel" name="extendsImplemetsKeywordLabel">
95.53 - <Properties>
95.54 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.55 - <ComponentRef name="extendsImplementsKeywordCombo"/>
95.56 - </Property>
95.57 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.58 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.59 - </Property>
95.60 - </Properties>
95.61 - <Constraints>
95.62 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.63 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="8" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.64 - </Constraint>
95.65 - </Constraints>
95.66 - </Component>
95.67 - <Component class="javax.swing.JComboBox" name="extendsImplementsKeywordCombo">
95.68 - <Properties>
95.69 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.70 - <StringArray count="4">
95.71 - <StringItem index="0" value="Item 1"/>
95.72 - <StringItem index="1" value="Item 2"/>
95.73 - <StringItem index="2" value="Item 3"/>
95.74 - <StringItem index="3" value="Item 4"/>
95.75 - </StringArray>
95.76 - </Property>
95.77 - </Properties>
95.78 - <Constraints>
95.79 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.80 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="8" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="1.0" weightY="0.0"/>
95.81 - </Constraint>
95.82 - </Constraints>
95.83 - </Component>
95.84 - <Component class="javax.swing.JLabel" name="extendsImplementsListLabel">
95.85 - <Properties>
95.86 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.87 - <ComponentRef name="extendsImplementsListCombo"/>
95.88 - </Property>
95.89 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.90 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.91 - </Property>
95.92 - </Properties>
95.93 - <Constraints>
95.94 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.95 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.96 - </Constraint>
95.97 - </Constraints>
95.98 - </Component>
95.99 - <Component class="javax.swing.JComboBox" name="extendsImplementsListCombo">
95.100 - <Properties>
95.101 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.102 - <StringArray count="4">
95.103 - <StringItem index="0" value="Item 1"/>
95.104 - <StringItem index="1" value="Item 2"/>
95.105 - <StringItem index="2" value="Item 3"/>
95.106 - <StringItem index="3" value="Item 4"/>
95.107 - </StringArray>
95.108 - </Property>
95.109 - </Properties>
95.110 - <Constraints>
95.111 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.112 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.113 - </Constraint>
95.114 - </Constraints>
95.115 - </Component>
95.116 - <Component class="javax.swing.JLabel" name="methodParamsLabel">
95.117 - <Properties>
95.118 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.119 - <ComponentRef name="methodParamsCombo"/>
95.120 - </Property>
95.121 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.122 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodParameters" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.123 - </Property>
95.124 - </Properties>
95.125 - <Constraints>
95.126 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.127 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.128 - </Constraint>
95.129 - </Constraints>
95.130 - </Component>
95.131 - <Component class="javax.swing.JComboBox" name="methodParamsCombo">
95.132 - <Properties>
95.133 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.134 - <StringArray count="4">
95.135 - <StringItem index="0" value="Item 1"/>
95.136 - <StringItem index="1" value="Item 2"/>
95.137 - <StringItem index="2" value="Item 3"/>
95.138 - <StringItem index="3" value="Item 4"/>
95.139 - </StringArray>
95.140 - </Property>
95.141 - </Properties>
95.142 - <Constraints>
95.143 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.144 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.145 - </Constraint>
95.146 - </Constraints>
95.147 - </Component>
95.148 - <Component class="javax.swing.JLabel" name="methodCallArgsLabel">
95.149 - <Properties>
95.150 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.151 - <ComponentRef name="methodCallArgsCombo"/>
95.152 - </Property>
95.153 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.154 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodCallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.155 - </Property>
95.156 - </Properties>
95.157 - <Constraints>
95.158 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.159 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.160 - </Constraint>
95.161 - </Constraints>
95.162 - </Component>
95.163 - <Component class="javax.swing.JComboBox" name="methodCallArgsCombo">
95.164 - <Properties>
95.165 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.166 - <StringArray count="4">
95.167 - <StringItem index="0" value="Item 1"/>
95.168 - <StringItem index="1" value="Item 2"/>
95.169 - <StringItem index="2" value="Item 3"/>
95.170 - <StringItem index="3" value="Item 4"/>
95.171 - </StringArray>
95.172 - </Property>
95.173 - </Properties>
95.174 - <Constraints>
95.175 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.176 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.177 - </Constraint>
95.178 - </Constraints>
95.179 - </Component>
95.180 - <Component class="javax.swing.JLabel" name="annotationArgsLabel">
95.181 - <Properties>
95.182 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.183 - <ComponentRef name="annotationArgsCombo"/>
95.184 - </Property>
95.185 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.186 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.187 - </Property>
95.188 - </Properties>
95.189 - <Constraints>
95.190 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.191 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.192 - </Constraint>
95.193 - </Constraints>
95.194 - </Component>
95.195 - <Component class="javax.swing.JComboBox" name="annotationArgsCombo">
95.196 - <Properties>
95.197 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.198 - <StringArray count="4">
95.199 - <StringItem index="0" value="Item 1"/>
95.200 - <StringItem index="1" value="Item 2"/>
95.201 - <StringItem index="2" value="Item 3"/>
95.202 - <StringItem index="3" value="Item 4"/>
95.203 - </StringArray>
95.204 - </Property>
95.205 - </Properties>
95.206 - <Constraints>
95.207 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.208 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.209 - </Constraint>
95.210 - </Constraints>
95.211 - </Component>
95.212 - <Component class="javax.swing.JLabel" name="chainedMethodCallsLabel">
95.213 - <Properties>
95.214 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.215 - <ComponentRef name="chainedMethodCallsCombo"/>
95.216 - </Property>
95.217 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.218 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_chainedMethodCalls" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.219 - </Property>
95.220 - </Properties>
95.221 - <Constraints>
95.222 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.223 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.224 - </Constraint>
95.225 - </Constraints>
95.226 - </Component>
95.227 - <Component class="javax.swing.JComboBox" name="chainedMethodCallsCombo">
95.228 - <Properties>
95.229 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.230 - <StringArray count="4">
95.231 - <StringItem index="0" value="Item 1"/>
95.232 - <StringItem index="1" value="Item 2"/>
95.233 - <StringItem index="2" value="Item 3"/>
95.234 - <StringItem index="3" value="Item 4"/>
95.235 - </StringArray>
95.236 - </Property>
95.237 - </Properties>
95.238 - <Constraints>
95.239 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.240 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.241 - </Constraint>
95.242 - </Constraints>
95.243 - </Component>
95.244 - <Component class="javax.swing.JLabel" name="throwsKeywordLabel">
95.245 - <Properties>
95.246 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.247 - <ComponentRef name="throwsKeywordCombo"/>
95.248 - </Property>
95.249 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.250 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.251 - </Property>
95.252 - </Properties>
95.253 - <Constraints>
95.254 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.255 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.256 - </Constraint>
95.257 - </Constraints>
95.258 - </Component>
95.259 - <Component class="javax.swing.JComboBox" name="throwsKeywordCombo">
95.260 - <Properties>
95.261 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.262 - <StringArray count="4">
95.263 - <StringItem index="0" value="Item 1"/>
95.264 - <StringItem index="1" value="Item 2"/>
95.265 - <StringItem index="2" value="Item 3"/>
95.266 - <StringItem index="3" value="Item 4"/>
95.267 - </StringArray>
95.268 - </Property>
95.269 - </Properties>
95.270 - <Constraints>
95.271 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.272 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.273 - </Constraint>
95.274 - </Constraints>
95.275 - </Component>
95.276 - <Component class="javax.swing.JLabel" name="throwsListLabel">
95.277 - <Properties>
95.278 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.279 - <ComponentRef name="throwsListCombo"/>
95.280 - </Property>
95.281 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.282 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.283 - </Property>
95.284 - </Properties>
95.285 - <Constraints>
95.286 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.287 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.288 - </Constraint>
95.289 - </Constraints>
95.290 - </Component>
95.291 - <Component class="javax.swing.JComboBox" name="throwsListCombo">
95.292 - <Properties>
95.293 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.294 - <StringArray count="4">
95.295 - <StringItem index="0" value="Item 1"/>
95.296 - <StringItem index="1" value="Item 2"/>
95.297 - <StringItem index="2" value="Item 3"/>
95.298 - <StringItem index="3" value="Item 4"/>
95.299 - </StringArray>
95.300 - </Property>
95.301 - </Properties>
95.302 - <Constraints>
95.303 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.304 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.305 - </Constraint>
95.306 - </Constraints>
95.307 - </Component>
95.308 - <Component class="javax.swing.JLabel" name="arrayInitLabel">
95.309 - <Properties>
95.310 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.311 - <ComponentRef name="arrayInitCombo"/>
95.312 - </Property>
95.313 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.314 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_arrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.315 - </Property>
95.316 - </Properties>
95.317 - <Constraints>
95.318 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.319 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.320 - </Constraint>
95.321 - </Constraints>
95.322 - </Component>
95.323 - <Component class="javax.swing.JComboBox" name="arrayInitCombo">
95.324 - <Properties>
95.325 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.326 - <StringArray count="4">
95.327 - <StringItem index="0" value="Item 1"/>
95.328 - <StringItem index="1" value="Item 2"/>
95.329 - <StringItem index="2" value="Item 3"/>
95.330 - <StringItem index="3" value="Item 4"/>
95.331 - </StringArray>
95.332 - </Property>
95.333 - </Properties>
95.334 - <Constraints>
95.335 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.336 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.337 - </Constraint>
95.338 - </Constraints>
95.339 - </Component>
95.340 - <Component class="javax.swing.JLabel" name="forLabel">
95.341 - <Properties>
95.342 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.343 - <ComponentRef name="forCombo"/>
95.344 - </Property>
95.345 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.346 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_for" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.347 - </Property>
95.348 - </Properties>
95.349 - <Constraints>
95.350 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.351 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.352 - </Constraint>
95.353 - </Constraints>
95.354 - </Component>
95.355 - <Component class="javax.swing.JComboBox" name="forCombo">
95.356 - <Properties>
95.357 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.358 - <StringArray count="4">
95.359 - <StringItem index="0" value="Item 1"/>
95.360 - <StringItem index="1" value="Item 2"/>
95.361 - <StringItem index="2" value="Item 3"/>
95.362 - <StringItem index="3" value="Item 4"/>
95.363 - </StringArray>
95.364 - </Property>
95.365 - </Properties>
95.366 - <Constraints>
95.367 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.368 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.369 - </Constraint>
95.370 - </Constraints>
95.371 - </Component>
95.372 - <Component class="javax.swing.JLabel" name="forStatementLabel">
95.373 - <Properties>
95.374 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.375 - <ComponentRef name="forStatementCombo"/>
95.376 - </Property>
95.377 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.378 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_forStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.379 - </Property>
95.380 - </Properties>
95.381 - <Constraints>
95.382 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.383 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.384 - </Constraint>
95.385 - </Constraints>
95.386 - </Component>
95.387 - <Component class="javax.swing.JComboBox" name="forStatementCombo">
95.388 - <Properties>
95.389 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.390 - <StringArray count="4">
95.391 - <StringItem index="0" value="Item 1"/>
95.392 - <StringItem index="1" value="Item 2"/>
95.393 - <StringItem index="2" value="Item 3"/>
95.394 - <StringItem index="3" value="Item 4"/>
95.395 - </StringArray>
95.396 - </Property>
95.397 - </Properties>
95.398 - <Constraints>
95.399 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.400 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="1.0" weightY="0.0"/>
95.401 - </Constraint>
95.402 - </Constraints>
95.403 - </Component>
95.404 - <Component class="javax.swing.JLabel" name="ifStatementLabel">
95.405 - <Properties>
95.406 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.407 - <ComponentRef name="ifStatementCombo"/>
95.408 - </Property>
95.409 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.410 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ifStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.411 - </Property>
95.412 - </Properties>
95.413 - <Constraints>
95.414 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.415 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.416 - </Constraint>
95.417 - </Constraints>
95.418 - </Component>
95.419 - <Component class="javax.swing.JComboBox" name="ifStatementCombo">
95.420 - <Properties>
95.421 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.422 - <StringArray count="4">
95.423 - <StringItem index="0" value="Item 1"/>
95.424 - <StringItem index="1" value="Item 2"/>
95.425 - <StringItem index="2" value="Item 3"/>
95.426 - <StringItem index="3" value="Item 4"/>
95.427 - </StringArray>
95.428 - </Property>
95.429 - </Properties>
95.430 - <Constraints>
95.431 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.432 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.433 - </Constraint>
95.434 - </Constraints>
95.435 - </Component>
95.436 - <Component class="javax.swing.JLabel" name="whileStatementLabel">
95.437 - <Properties>
95.438 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.439 - <ComponentRef name="whileStatementComboBox"/>
95.440 - </Property>
95.441 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.442 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_whileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.443 - </Property>
95.444 - </Properties>
95.445 - <Constraints>
95.446 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.447 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.448 - </Constraint>
95.449 - </Constraints>
95.450 - </Component>
95.451 - <Component class="javax.swing.JComboBox" name="whileStatementComboBox">
95.452 - <Properties>
95.453 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.454 - <StringArray count="4">
95.455 - <StringItem index="0" value="Item 1"/>
95.456 - <StringItem index="1" value="Item 2"/>
95.457 - <StringItem index="2" value="Item 3"/>
95.458 - <StringItem index="3" value="Item 4"/>
95.459 - </StringArray>
95.460 - </Property>
95.461 - </Properties>
95.462 - <Constraints>
95.463 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.464 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.465 - </Constraint>
95.466 - </Constraints>
95.467 - </Component>
95.468 - <Component class="javax.swing.JLabel" name="doWhileStatementLabel">
95.469 - <Properties>
95.470 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.471 - <ComponentRef name="doWhileStatementCombo"/>
95.472 - </Property>
95.473 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.474 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_doWhileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.475 - </Property>
95.476 - </Properties>
95.477 - <Constraints>
95.478 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.479 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.480 - </Constraint>
95.481 - </Constraints>
95.482 - </Component>
95.483 - <Component class="javax.swing.JComboBox" name="doWhileStatementCombo">
95.484 - <Properties>
95.485 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.486 - <StringArray count="4">
95.487 - <StringItem index="0" value="Item 1"/>
95.488 - <StringItem index="1" value="Item 2"/>
95.489 - <StringItem index="2" value="Item 3"/>
95.490 - <StringItem index="3" value="Item 4"/>
95.491 - </StringArray>
95.492 - </Property>
95.493 - </Properties>
95.494 - <Constraints>
95.495 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.496 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.497 - </Constraint>
95.498 - </Constraints>
95.499 - </Component>
95.500 - <Component class="javax.swing.JLabel" name="assertLabel">
95.501 - <Properties>
95.502 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.503 - <ComponentRef name="assertCombo"/>
95.504 - </Property>
95.505 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.506 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assert" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.507 - </Property>
95.508 - </Properties>
95.509 - <Constraints>
95.510 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.511 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.512 - </Constraint>
95.513 - </Constraints>
95.514 - </Component>
95.515 - <Component class="javax.swing.JComboBox" name="assertCombo">
95.516 - <Properties>
95.517 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.518 - <StringArray count="4">
95.519 - <StringItem index="0" value="Item 1"/>
95.520 - <StringItem index="1" value="Item 2"/>
95.521 - <StringItem index="2" value="Item 3"/>
95.522 - <StringItem index="3" value="Item 4"/>
95.523 - </StringArray>
95.524 - </Property>
95.525 - </Properties>
95.526 - <Constraints>
95.527 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.528 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.529 - </Constraint>
95.530 - </Constraints>
95.531 - </Component>
95.532 - <Component class="javax.swing.JLabel" name="enumConstantsLabel">
95.533 - <Properties>
95.534 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.535 - <ComponentRef name="enumConstantsCombo"/>
95.536 - </Property>
95.537 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.538 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_enumConstants" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.539 - </Property>
95.540 - </Properties>
95.541 - <Constraints>
95.542 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.543 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.544 - </Constraint>
95.545 - </Constraints>
95.546 - </Component>
95.547 - <Component class="javax.swing.JComboBox" name="enumConstantsCombo">
95.548 - <Properties>
95.549 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.550 - <StringArray count="4">
95.551 - <StringItem index="0" value="Item 1"/>
95.552 - <StringItem index="1" value="Item 2"/>
95.553 - <StringItem index="2" value="Item 3"/>
95.554 - <StringItem index="3" value="Item 4"/>
95.555 - </StringArray>
95.556 - </Property>
95.557 - </Properties>
95.558 - <Constraints>
95.559 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.560 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.561 - </Constraint>
95.562 - </Constraints>
95.563 - </Component>
95.564 - <Component class="javax.swing.JLabel" name="annotationsLabel">
95.565 - <Properties>
95.566 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.567 - <ComponentRef name="annotationsCombo"/>
95.568 - </Property>
95.569 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.570 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotations" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.571 - </Property>
95.572 - </Properties>
95.573 - <Constraints>
95.574 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.575 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.576 - </Constraint>
95.577 - </Constraints>
95.578 - </Component>
95.579 - <Component class="javax.swing.JComboBox" name="annotationsCombo">
95.580 - <Properties>
95.581 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.582 - <StringArray count="4">
95.583 - <StringItem index="0" value="Item 1"/>
95.584 - <StringItem index="1" value="Item 2"/>
95.585 - <StringItem index="2" value="Item 3"/>
95.586 - <StringItem index="3" value="Item 4"/>
95.587 - </StringArray>
95.588 - </Property>
95.589 - </Properties>
95.590 - <Constraints>
95.591 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.592 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.593 - </Constraint>
95.594 - </Constraints>
95.595 - </Component>
95.596 - <Component class="javax.swing.JLabel" name="binaryOpsLabel">
95.597 - <Properties>
95.598 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.599 - <ComponentRef name="binaryOpsCombo"/>
95.600 - </Property>
95.601 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.602 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_binaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.603 - </Property>
95.604 - </Properties>
95.605 - <Constraints>
95.606 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.607 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.608 - </Constraint>
95.609 - </Constraints>
95.610 - </Component>
95.611 - <Component class="javax.swing.JComboBox" name="binaryOpsCombo">
95.612 - <Properties>
95.613 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.614 - <StringArray count="4">
95.615 - <StringItem index="0" value="Item 1"/>
95.616 - <StringItem index="1" value="Item 2"/>
95.617 - <StringItem index="2" value="Item 3"/>
95.618 - <StringItem index="3" value="Item 4"/>
95.619 - </StringArray>
95.620 - </Property>
95.621 - </Properties>
95.622 - <Constraints>
95.623 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.624 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.625 - </Constraint>
95.626 - </Constraints>
95.627 - </Component>
95.628 - <Component class="javax.swing.JLabel" name="ternaryOpsLabel">
95.629 - <Properties>
95.630 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.631 - <ComponentRef name="ternaryOpsCombo"/>
95.632 - </Property>
95.633 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.634 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ternaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.635 - </Property>
95.636 - </Properties>
95.637 - <Constraints>
95.638 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.639 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.640 - </Constraint>
95.641 - </Constraints>
95.642 - </Component>
95.643 - <Component class="javax.swing.JComboBox" name="ternaryOpsCombo">
95.644 - <Properties>
95.645 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.646 - <StringArray count="4">
95.647 - <StringItem index="0" value="Item 1"/>
95.648 - <StringItem index="1" value="Item 2"/>
95.649 - <StringItem index="2" value="Item 3"/>
95.650 - <StringItem index="3" value="Item 4"/>
95.651 - </StringArray>
95.652 - </Property>
95.653 - </Properties>
95.654 - <Constraints>
95.655 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.656 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.657 - </Constraint>
95.658 - </Constraints>
95.659 - </Component>
95.660 - <Component class="javax.swing.JLabel" name="assignOpsLabel">
95.661 - <Properties>
95.662 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
95.663 - <ComponentRef name="assignOpsCombo"/>
95.664 - </Property>
95.665 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95.666 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assignOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
95.667 - </Property>
95.668 - </Properties>
95.669 - <Constraints>
95.670 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.671 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
95.672 - </Constraint>
95.673 - </Constraints>
95.674 - </Component>
95.675 - <Component class="javax.swing.JComboBox" name="assignOpsCombo">
95.676 - <Properties>
95.677 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
95.678 - <StringArray count="4">
95.679 - <StringItem index="0" value="Item 1"/>
95.680 - <StringItem index="1" value="Item 2"/>
95.681 - <StringItem index="2" value="Item 3"/>
95.682 - <StringItem index="3" value="Item 4"/>
95.683 - </StringArray>
95.684 - </Property>
95.685 - </Properties>
95.686 - <Constraints>
95.687 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.688 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
95.689 - </Constraint>
95.690 - </Constraints>
95.691 - </Component>
95.692 - <Container class="javax.swing.JPanel" name="spacerPanel1">
95.693 - <Properties>
95.694 - <Property name="opaque" type="boolean" value="false"/>
95.695 - </Properties>
95.696 - <Constraints>
95.697 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
95.698 - <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="0" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0" insetsRight="8" anchor="10" weightX="0.0" weightY="1.0"/>
95.699 - </Constraint>
95.700 - </Constraints>
95.701 -
95.702 - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
95.703 - </Container>
95.704 - </SubComponents>
95.705 - </Container>
95.706 - </SubComponents>
95.707 - </Container>
95.708 - </SubComponents>
95.709 -</Form>
96.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtWrapping.java Fri Sep 18 16:20:24 2015 -0500
96.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
96.3 @@ -1,505 +0,0 @@
96.4 -/*
96.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
96.6 - *
96.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
96.8 - *
96.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
96.10 - * Other names may be trademarks of their respective owners.
96.11 - *
96.12 - * The contents of this file are subject to the terms of either the GNU
96.13 - * General Public License Version 2 only ("GPL") or the Common
96.14 - * Development and Distribution License("CDDL") (collectively, the
96.15 - * "License"). You may not use this file except in compliance with the
96.16 - * License. You can obtain a copy of the License at
96.17 - * http://www.netbeans.org/cddl-gplv2.html
96.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
96.19 - * specific language governing permissions and limitations under the
96.20 - * License. When distributing the software, include this License Header
96.21 - * Notice in each file and include the License file at
96.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
96.23 - * particular file as subject to the "Classpath" exception as provided
96.24 - * by Oracle in the GPL Version 2 section of the License file that
96.25 - * accompanied this code. If applicable, add the following below the
96.26 - * License Header, with the fields enclosed by brackets [] replaced by
96.27 - * your own identifying information:
96.28 - * "Portions Copyrighted [year] [name of copyright owner]"
96.29 - *
96.30 - * Contributor(s):
96.31 - *
96.32 - * The Original Software is NetBeans. The Initial Developer of the Original
96.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
96.34 - * Microsystems, Inc. All Rights Reserved.
96.35 - *
96.36 - * If you wish your version of this file to be governed by only the CDDL
96.37 - * or only the GPL Version 2, indicate your decision by adding
96.38 - * "[Contributor] elects to include this software in this distribution
96.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
96.40 - * single choice of license, a recipient has the option to distribute
96.41 - * your version of this file under either the CDDL, the GPL Version 2 or
96.42 - * to extend the choice of license to its licensees as provided above.
96.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
96.44 - * Version 2 license, then the option applies only if the new code is
96.45 - * made subject to such option by the copyright holder.
96.46 - */
96.47 -
96.48 -package org.netbeans.modules.python.editor.options;
96.49 -
96.50 -import org.netbeans.modules.python.editor.options.CodeStyle;
96.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
96.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
96.53 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
96.54 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
96.55 -
96.56 -
96.57 -/**
96.58 - *
96.59 - * @author phrebejk
96.60 - */
96.61 -public class FmtWrapping extends javax.swing.JPanel {
96.62 -
96.63 - /** Creates new form FmtWrapping */
96.64 - public FmtWrapping() {
96.65 - initComponents();
96.66 -
96.67 - scrollPane.getViewport().setBackground(java.awt.SystemColor.controlLtHighlight);
96.68 -
96.69 -/*
96.70 - extendsImplementsKeywordCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsKeyword);
96.71 - extendsImplementsListCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsList);
96.72 - methodParamsCombo.putClientProperty(OPTION_ID, wrapMethodParams);
96.73 - methodCallArgsCombo.putClientProperty(OPTION_ID, wrapMethodCallArgs);
96.74 - annotationArgsCombo.putClientProperty(OPTION_ID, wrapAnnotationArgs);
96.75 - chainedMethodCallsCombo.putClientProperty(OPTION_ID, wrapChainedMethodCalls);
96.76 - throwsKeywordCombo.putClientProperty(OPTION_ID, wrapThrowsKeyword);
96.77 - throwsListCombo.putClientProperty(OPTION_ID, wrapThrowsList);
96.78 - arrayInitCombo.putClientProperty(OPTION_ID, wrapArrayInit);
96.79 - forCombo.putClientProperty(OPTION_ID, wrapFor);
96.80 - forStatementCombo.putClientProperty(OPTION_ID, wrapForStatement );
96.81 - ifStatementCombo.putClientProperty(OPTION_ID, wrapIfStatement);
96.82 - whileStatementComboBox.putClientProperty(OPTION_ID, wrapWhileStatement);
96.83 - doWhileStatementCombo.putClientProperty(OPTION_ID, wrapDoWhileStatement);
96.84 - assertCombo.putClientProperty(OPTION_ID, wrapAssert);
96.85 - enumConstantsCombo.putClientProperty(OPTION_ID, wrapEnumConstants);
96.86 - annotationsCombo.putClientProperty(OPTION_ID, wrapAnnotations);
96.87 - binaryOpsCombo.putClientProperty(OPTION_ID, wrapBinaryOps);
96.88 - ternaryOpsCombo.putClientProperty(OPTION_ID, wrapTernaryOps);
96.89 - assignOpsCombo.putClientProperty(OPTION_ID, wrapAssignOps);
96.90 - }
96.91 -
96.92 - public static PreferencesCustomizer.Factory getController() {
96.93 - return new CategorySupport.Factory("wrapping", FmtWrapping.class, //NOI18N
96.94 - org.openide.util.NbBundle.getMessage(FmtWrapping.class, "SAMPLE_Wrapping"), //NOI18N
96.95 - new String[] { FmtOptions.rightMargin, "30" } //NOI18N
96.96 -// new String[] { FmtOptions.redundantDoWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
96.97 -// new String[] { FmtOptions.redundantForBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
96.98 -// new String[] { FmtOptions.redundantIfBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
96.99 -// new String[] { FmtOptions.redundantWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() }
96.100 - ); // NOI18N
96.101 - */
96.102 - }
96.103 -
96.104 - /** This method is called from within the constructor to
96.105 - * initialize the form.
96.106 - * WARNING: Do NOT modify this code. The content of this method is
96.107 - * always regenerated by the Form Editor.
96.108 - */
96.109 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
96.110 - private void initComponents() {
96.111 - java.awt.GridBagConstraints gridBagConstraints;
96.112 -
96.113 - scrollPane = new javax.swing.JScrollPane();
96.114 - panel1 = new javax.swing.JPanel();
96.115 - extendsImplemetsKeywordLabel = new javax.swing.JLabel();
96.116 - extendsImplementsKeywordCombo = new javax.swing.JComboBox();
96.117 - extendsImplementsListLabel = new javax.swing.JLabel();
96.118 - extendsImplementsListCombo = new javax.swing.JComboBox();
96.119 - methodParamsLabel = new javax.swing.JLabel();
96.120 - methodParamsCombo = new javax.swing.JComboBox();
96.121 - methodCallArgsLabel = new javax.swing.JLabel();
96.122 - methodCallArgsCombo = new javax.swing.JComboBox();
96.123 - annotationArgsLabel = new javax.swing.JLabel();
96.124 - annotationArgsCombo = new javax.swing.JComboBox();
96.125 - chainedMethodCallsLabel = new javax.swing.JLabel();
96.126 - chainedMethodCallsCombo = new javax.swing.JComboBox();
96.127 - throwsKeywordLabel = new javax.swing.JLabel();
96.128 - throwsKeywordCombo = new javax.swing.JComboBox();
96.129 - throwsListLabel = new javax.swing.JLabel();
96.130 - throwsListCombo = new javax.swing.JComboBox();
96.131 - arrayInitLabel = new javax.swing.JLabel();
96.132 - arrayInitCombo = new javax.swing.JComboBox();
96.133 - forLabel = new javax.swing.JLabel();
96.134 - forCombo = new javax.swing.JComboBox();
96.135 - forStatementLabel = new javax.swing.JLabel();
96.136 - forStatementCombo = new javax.swing.JComboBox();
96.137 - ifStatementLabel = new javax.swing.JLabel();
96.138 - ifStatementCombo = new javax.swing.JComboBox();
96.139 - whileStatementLabel = new javax.swing.JLabel();
96.140 - whileStatementComboBox = new javax.swing.JComboBox();
96.141 - doWhileStatementLabel = new javax.swing.JLabel();
96.142 - doWhileStatementCombo = new javax.swing.JComboBox();
96.143 - assertLabel = new javax.swing.JLabel();
96.144 - assertCombo = new javax.swing.JComboBox();
96.145 - enumConstantsLabel = new javax.swing.JLabel();
96.146 - enumConstantsCombo = new javax.swing.JComboBox();
96.147 - annotationsLabel = new javax.swing.JLabel();
96.148 - annotationsCombo = new javax.swing.JComboBox();
96.149 - binaryOpsLabel = new javax.swing.JLabel();
96.150 - binaryOpsCombo = new javax.swing.JComboBox();
96.151 - ternaryOpsLabel = new javax.swing.JLabel();
96.152 - ternaryOpsCombo = new javax.swing.JComboBox();
96.153 - assignOpsLabel = new javax.swing.JLabel();
96.154 - assignOpsCombo = new javax.swing.JComboBox();
96.155 - spacerPanel1 = new javax.swing.JPanel();
96.156 -
96.157 - setName(org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_Wrapping")); // NOI18N
96.158 - setOpaque(false);
96.159 - setLayout(new java.awt.BorderLayout());
96.160 -
96.161 - scrollPane.setMinimumSize(new java.awt.Dimension(300, 200));
96.162 - scrollPane.setPreferredSize(new java.awt.Dimension(350, 600));
96.163 -
96.164 - panel1.setOpaque(false);
96.165 - panel1.setLayout(new java.awt.GridBagLayout());
96.166 -
96.167 - extendsImplemetsKeywordLabel.setLabelFor(extendsImplementsKeywordCombo);
96.168 - org.openide.awt.Mnemonics.setLocalizedText(extendsImplemetsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsKeyword")); // NOI18N
96.169 - gridBagConstraints = new java.awt.GridBagConstraints();
96.170 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.171 - gridBagConstraints.insets = new java.awt.Insets(8, 8, 4, 0);
96.172 - panel1.add(extendsImplemetsKeywordLabel, gridBagConstraints);
96.173 -
96.174 - extendsImplementsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.175 - gridBagConstraints = new java.awt.GridBagConstraints();
96.176 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.177 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.178 - gridBagConstraints.weightx = 1.0;
96.179 - gridBagConstraints.insets = new java.awt.Insets(8, 6, 4, 8);
96.180 - panel1.add(extendsImplementsKeywordCombo, gridBagConstraints);
96.181 -
96.182 - extendsImplementsListLabel.setLabelFor(extendsImplementsListCombo);
96.183 - org.openide.awt.Mnemonics.setLocalizedText(extendsImplementsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsList")); // NOI18N
96.184 - gridBagConstraints = new java.awt.GridBagConstraints();
96.185 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.186 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.187 - panel1.add(extendsImplementsListLabel, gridBagConstraints);
96.188 -
96.189 - extendsImplementsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.190 - gridBagConstraints = new java.awt.GridBagConstraints();
96.191 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.192 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.193 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.194 - panel1.add(extendsImplementsListCombo, gridBagConstraints);
96.195 -
96.196 - methodParamsLabel.setLabelFor(methodParamsCombo);
96.197 - org.openide.awt.Mnemonics.setLocalizedText(methodParamsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodParameters")); // NOI18N
96.198 - gridBagConstraints = new java.awt.GridBagConstraints();
96.199 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.200 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.201 - panel1.add(methodParamsLabel, gridBagConstraints);
96.202 -
96.203 - methodParamsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.204 - gridBagConstraints = new java.awt.GridBagConstraints();
96.205 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.206 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.207 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.208 - panel1.add(methodParamsCombo, gridBagConstraints);
96.209 -
96.210 - methodCallArgsLabel.setLabelFor(methodCallArgsCombo);
96.211 - org.openide.awt.Mnemonics.setLocalizedText(methodCallArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodCallArgs")); // NOI18N
96.212 - gridBagConstraints = new java.awt.GridBagConstraints();
96.213 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.214 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.215 - panel1.add(methodCallArgsLabel, gridBagConstraints);
96.216 -
96.217 - methodCallArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.218 - gridBagConstraints = new java.awt.GridBagConstraints();
96.219 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.220 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.221 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.222 - panel1.add(methodCallArgsCombo, gridBagConstraints);
96.223 -
96.224 - annotationArgsLabel.setLabelFor(annotationArgsCombo);
96.225 - org.openide.awt.Mnemonics.setLocalizedText(annotationArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotationArgs")); // NOI18N
96.226 - gridBagConstraints = new java.awt.GridBagConstraints();
96.227 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.228 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.229 - panel1.add(annotationArgsLabel, gridBagConstraints);
96.230 -
96.231 - annotationArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.232 - gridBagConstraints = new java.awt.GridBagConstraints();
96.233 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.234 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.235 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.236 - panel1.add(annotationArgsCombo, gridBagConstraints);
96.237 -
96.238 - chainedMethodCallsLabel.setLabelFor(chainedMethodCallsCombo);
96.239 - org.openide.awt.Mnemonics.setLocalizedText(chainedMethodCallsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_chainedMethodCalls")); // NOI18N
96.240 - gridBagConstraints = new java.awt.GridBagConstraints();
96.241 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.242 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.243 - panel1.add(chainedMethodCallsLabel, gridBagConstraints);
96.244 -
96.245 - chainedMethodCallsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.246 - gridBagConstraints = new java.awt.GridBagConstraints();
96.247 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.248 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.249 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.250 - panel1.add(chainedMethodCallsCombo, gridBagConstraints);
96.251 -
96.252 - throwsKeywordLabel.setLabelFor(throwsKeywordCombo);
96.253 - org.openide.awt.Mnemonics.setLocalizedText(throwsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsKeyword")); // NOI18N
96.254 - gridBagConstraints = new java.awt.GridBagConstraints();
96.255 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.256 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.257 - panel1.add(throwsKeywordLabel, gridBagConstraints);
96.258 -
96.259 - throwsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.260 - gridBagConstraints = new java.awt.GridBagConstraints();
96.261 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.262 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.263 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.264 - panel1.add(throwsKeywordCombo, gridBagConstraints);
96.265 -
96.266 - throwsListLabel.setLabelFor(throwsListCombo);
96.267 - org.openide.awt.Mnemonics.setLocalizedText(throwsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsList")); // NOI18N
96.268 - gridBagConstraints = new java.awt.GridBagConstraints();
96.269 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.270 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.271 - panel1.add(throwsListLabel, gridBagConstraints);
96.272 -
96.273 - throwsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.274 - gridBagConstraints = new java.awt.GridBagConstraints();
96.275 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.276 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.277 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.278 - panel1.add(throwsListCombo, gridBagConstraints);
96.279 -
96.280 - arrayInitLabel.setLabelFor(arrayInitCombo);
96.281 - org.openide.awt.Mnemonics.setLocalizedText(arrayInitLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_arrayInit")); // NOI18N
96.282 - gridBagConstraints = new java.awt.GridBagConstraints();
96.283 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.284 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.285 - panel1.add(arrayInitLabel, gridBagConstraints);
96.286 -
96.287 - arrayInitCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.288 - gridBagConstraints = new java.awt.GridBagConstraints();
96.289 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.290 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.291 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.292 - panel1.add(arrayInitCombo, gridBagConstraints);
96.293 -
96.294 - forLabel.setLabelFor(forCombo);
96.295 - org.openide.awt.Mnemonics.setLocalizedText(forLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_for")); // NOI18N
96.296 - gridBagConstraints = new java.awt.GridBagConstraints();
96.297 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.298 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.299 - panel1.add(forLabel, gridBagConstraints);
96.300 -
96.301 - forCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.302 - gridBagConstraints = new java.awt.GridBagConstraints();
96.303 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.304 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.305 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.306 - panel1.add(forCombo, gridBagConstraints);
96.307 -
96.308 - forStatementLabel.setLabelFor(forStatementCombo);
96.309 - org.openide.awt.Mnemonics.setLocalizedText(forStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_forStatement")); // NOI18N
96.310 - gridBagConstraints = new java.awt.GridBagConstraints();
96.311 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.312 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.313 - panel1.add(forStatementLabel, gridBagConstraints);
96.314 -
96.315 - forStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.316 - gridBagConstraints = new java.awt.GridBagConstraints();
96.317 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.318 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.319 - gridBagConstraints.weightx = 1.0;
96.320 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.321 - panel1.add(forStatementCombo, gridBagConstraints);
96.322 -
96.323 - ifStatementLabel.setLabelFor(ifStatementCombo);
96.324 - org.openide.awt.Mnemonics.setLocalizedText(ifStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ifStatement")); // NOI18N
96.325 - gridBagConstraints = new java.awt.GridBagConstraints();
96.326 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.327 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.328 - panel1.add(ifStatementLabel, gridBagConstraints);
96.329 -
96.330 - ifStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.331 - gridBagConstraints = new java.awt.GridBagConstraints();
96.332 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.333 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.334 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.335 - panel1.add(ifStatementCombo, gridBagConstraints);
96.336 -
96.337 - whileStatementLabel.setLabelFor(whileStatementComboBox);
96.338 - org.openide.awt.Mnemonics.setLocalizedText(whileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_whileStatement")); // NOI18N
96.339 - gridBagConstraints = new java.awt.GridBagConstraints();
96.340 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.341 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.342 - panel1.add(whileStatementLabel, gridBagConstraints);
96.343 -
96.344 - whileStatementComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.345 - gridBagConstraints = new java.awt.GridBagConstraints();
96.346 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.347 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.348 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.349 - panel1.add(whileStatementComboBox, gridBagConstraints);
96.350 -
96.351 - doWhileStatementLabel.setLabelFor(doWhileStatementCombo);
96.352 - org.openide.awt.Mnemonics.setLocalizedText(doWhileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_doWhileStatement")); // NOI18N
96.353 - gridBagConstraints = new java.awt.GridBagConstraints();
96.354 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.355 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.356 - panel1.add(doWhileStatementLabel, gridBagConstraints);
96.357 -
96.358 - doWhileStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.359 - gridBagConstraints = new java.awt.GridBagConstraints();
96.360 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.361 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.362 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.363 - panel1.add(doWhileStatementCombo, gridBagConstraints);
96.364 -
96.365 - assertLabel.setLabelFor(assertCombo);
96.366 - org.openide.awt.Mnemonics.setLocalizedText(assertLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assert")); // NOI18N
96.367 - gridBagConstraints = new java.awt.GridBagConstraints();
96.368 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.369 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.370 - panel1.add(assertLabel, gridBagConstraints);
96.371 -
96.372 - assertCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.373 - gridBagConstraints = new java.awt.GridBagConstraints();
96.374 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.375 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.376 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.377 - panel1.add(assertCombo, gridBagConstraints);
96.378 -
96.379 - enumConstantsLabel.setLabelFor(enumConstantsCombo);
96.380 - org.openide.awt.Mnemonics.setLocalizedText(enumConstantsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_enumConstants")); // NOI18N
96.381 - gridBagConstraints = new java.awt.GridBagConstraints();
96.382 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.383 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.384 - panel1.add(enumConstantsLabel, gridBagConstraints);
96.385 -
96.386 - enumConstantsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.387 - gridBagConstraints = new java.awt.GridBagConstraints();
96.388 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.389 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.390 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.391 - panel1.add(enumConstantsCombo, gridBagConstraints);
96.392 -
96.393 - annotationsLabel.setLabelFor(annotationsCombo);
96.394 - org.openide.awt.Mnemonics.setLocalizedText(annotationsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotations")); // NOI18N
96.395 - gridBagConstraints = new java.awt.GridBagConstraints();
96.396 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.397 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.398 - panel1.add(annotationsLabel, gridBagConstraints);
96.399 -
96.400 - annotationsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.401 - gridBagConstraints = new java.awt.GridBagConstraints();
96.402 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.403 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.404 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.405 - panel1.add(annotationsCombo, gridBagConstraints);
96.406 -
96.407 - binaryOpsLabel.setLabelFor(binaryOpsCombo);
96.408 - org.openide.awt.Mnemonics.setLocalizedText(binaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_binaryOps")); // NOI18N
96.409 - gridBagConstraints = new java.awt.GridBagConstraints();
96.410 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.411 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.412 - panel1.add(binaryOpsLabel, gridBagConstraints);
96.413 -
96.414 - binaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.415 - gridBagConstraints = new java.awt.GridBagConstraints();
96.416 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.417 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.418 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.419 - panel1.add(binaryOpsCombo, gridBagConstraints);
96.420 -
96.421 - ternaryOpsLabel.setLabelFor(ternaryOpsCombo);
96.422 - org.openide.awt.Mnemonics.setLocalizedText(ternaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ternaryOps")); // NOI18N
96.423 - gridBagConstraints = new java.awt.GridBagConstraints();
96.424 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.425 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.426 - panel1.add(ternaryOpsLabel, gridBagConstraints);
96.427 -
96.428 - ternaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.429 - gridBagConstraints = new java.awt.GridBagConstraints();
96.430 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.431 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.432 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.433 - panel1.add(ternaryOpsCombo, gridBagConstraints);
96.434 -
96.435 - assignOpsLabel.setLabelFor(assignOpsCombo);
96.436 - org.openide.awt.Mnemonics.setLocalizedText(assignOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assignOps")); // NOI18N
96.437 - gridBagConstraints = new java.awt.GridBagConstraints();
96.438 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
96.439 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
96.440 - panel1.add(assignOpsLabel, gridBagConstraints);
96.441 -
96.442 - assignOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
96.443 - gridBagConstraints = new java.awt.GridBagConstraints();
96.444 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.445 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
96.446 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
96.447 - panel1.add(assignOpsCombo, gridBagConstraints);
96.448 -
96.449 - spacerPanel1.setOpaque(false);
96.450 - gridBagConstraints = new java.awt.GridBagConstraints();
96.451 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
96.452 - gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
96.453 - gridBagConstraints.weighty = 1.0;
96.454 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 8);
96.455 - panel1.add(spacerPanel1, gridBagConstraints);
96.456 -
96.457 - scrollPane.setViewportView(panel1);
96.458 -
96.459 - add(scrollPane, java.awt.BorderLayout.CENTER);
96.460 - }// </editor-fold>//GEN-END:initComponents
96.461 -
96.462 - // Variables declaration - do not modify//GEN-BEGIN:variables
96.463 - private javax.swing.JComboBox annotationArgsCombo;
96.464 - private javax.swing.JLabel annotationArgsLabel;
96.465 - private javax.swing.JComboBox annotationsCombo;
96.466 - private javax.swing.JLabel annotationsLabel;
96.467 - private javax.swing.JComboBox arrayInitCombo;
96.468 - private javax.swing.JLabel arrayInitLabel;
96.469 - private javax.swing.JComboBox assertCombo;
96.470 - private javax.swing.JLabel assertLabel;
96.471 - private javax.swing.JComboBox assignOpsCombo;
96.472 - private javax.swing.JLabel assignOpsLabel;
96.473 - private javax.swing.JComboBox binaryOpsCombo;
96.474 - private javax.swing.JLabel binaryOpsLabel;
96.475 - private javax.swing.JComboBox chainedMethodCallsCombo;
96.476 - private javax.swing.JLabel chainedMethodCallsLabel;
96.477 - private javax.swing.JComboBox doWhileStatementCombo;
96.478 - private javax.swing.JLabel doWhileStatementLabel;
96.479 - private javax.swing.JComboBox enumConstantsCombo;
96.480 - private javax.swing.JLabel enumConstantsLabel;
96.481 - private javax.swing.JComboBox extendsImplementsKeywordCombo;
96.482 - private javax.swing.JComboBox extendsImplementsListCombo;
96.483 - private javax.swing.JLabel extendsImplementsListLabel;
96.484 - private javax.swing.JLabel extendsImplemetsKeywordLabel;
96.485 - private javax.swing.JComboBox forCombo;
96.486 - private javax.swing.JLabel forLabel;
96.487 - private javax.swing.JComboBox forStatementCombo;
96.488 - private javax.swing.JLabel forStatementLabel;
96.489 - private javax.swing.JComboBox ifStatementCombo;
96.490 - private javax.swing.JLabel ifStatementLabel;
96.491 - private javax.swing.JComboBox methodCallArgsCombo;
96.492 - private javax.swing.JLabel methodCallArgsLabel;
96.493 - private javax.swing.JComboBox methodParamsCombo;
96.494 - private javax.swing.JLabel methodParamsLabel;
96.495 - private javax.swing.JPanel panel1;
96.496 - private javax.swing.JScrollPane scrollPane;
96.497 - private javax.swing.JPanel spacerPanel1;
96.498 - private javax.swing.JComboBox ternaryOpsCombo;
96.499 - private javax.swing.JLabel ternaryOpsLabel;
96.500 - private javax.swing.JComboBox throwsKeywordCombo;
96.501 - private javax.swing.JLabel throwsKeywordLabel;
96.502 - private javax.swing.JComboBox throwsListCombo;
96.503 - private javax.swing.JLabel throwsListLabel;
96.504 - private javax.swing.JComboBox whileStatementComboBox;
96.505 - private javax.swing.JLabel whileStatementLabel;
96.506 - // End of variables declaration//GEN-END:variables
96.507 -
96.508 -}
97.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/NumericKeyListener.java Fri Sep 18 16:20:24 2015 -0500
97.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
97.3 @@ -1,74 +0,0 @@
97.4 -/*
97.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
97.6 - *
97.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
97.8 - *
97.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
97.10 - * Other names may be trademarks of their respective owners.
97.11 - *
97.12 - * The contents of this file are subject to the terms of either the GNU
97.13 - * General Public License Version 2 only ("GPL") or the Common
97.14 - * Development and Distribution License("CDDL") (collectively, the
97.15 - * "License"). You may not use this file except in compliance with the
97.16 - * License. You can obtain a copy of the License at
97.17 - * http://www.netbeans.org/cddl-gplv2.html
97.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
97.19 - * specific language governing permissions and limitations under the
97.20 - * License. When distributing the software, include this License Header
97.21 - * Notice in each file and include the License file at
97.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
97.23 - * particular file as subject to the "Classpath" exception as provided
97.24 - * by Oracle in the GPL Version 2 section of the License file that
97.25 - * accompanied this code. If applicable, add the following below the
97.26 - * License Header, with the fields enclosed by brackets [] replaced by
97.27 - * your own identifying information:
97.28 - * "Portions Copyrighted [year] [name of copyright owner]"
97.29 - *
97.30 - * If you wish your version of this file to be governed by only the CDDL
97.31 - * or only the GPL Version 2, indicate your decision by adding
97.32 - * "[Contributor] elects to include this software in this distribution
97.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
97.34 - * single choice of license, a recipient has the option to distribute
97.35 - * your version of this file under either the CDDL, the GPL Version 2 or
97.36 - * to extend the choice of license to its licensees as provided above.
97.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
97.38 - * Version 2 license, then the option applies only if the new code is
97.39 - * made subject to such option by the copyright holder.
97.40 - *
97.41 - * Contributor(s):
97.42 - *
97.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
97.44 - */
97.45 -package org.netbeans.modules.python.editor.options;
97.46 -
97.47 -import java.awt.Component;
97.48 -import java.awt.event.KeyEvent;
97.49 -import java.awt.event.KeyListener;
97.50 -
97.51 -/**
97.52 - *
97.53 - * @author tester
97.54 - */
97.55 -public class NumericKeyListener implements KeyListener {
97.56 - public NumericKeyListener() {
97.57 - }
97.58 -
97.59 - @Override
97.60 - public void keyPressed(KeyEvent evt) {
97.61 - }
97.62 -
97.63 - @Override
97.64 - public void keyReleased(KeyEvent evt) {
97.65 - }
97.66 -
97.67 - @Override
97.68 - public void keyTyped(KeyEvent evt) {
97.69 - if (!Character.isDigit(evt.getKeyChar()) && !Character.isISOControl(evt.getKeyChar())) {
97.70 - evt.consume();
97.71 - Component c = evt.getComponent();
97.72 - if (c != null) {
97.73 - c.getToolkit().beep();
97.74 - }
97.75 - }
97.76 - }
97.77 -}
98.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonElementCtx.java Fri Sep 18 16:20:24 2015 -0500
98.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonElementCtx.java Mon Sep 21 13:01:16 2015 +0200
98.3 @@ -32,15 +32,15 @@
98.4
98.5 import java.util.Iterator;
98.6
98.7 -import org.netbeans.modules.python.editor.elements.AstElement;
98.8 -import org.netbeans.modules.python.editor.elements.Element;
98.9 +import org.netbeans.modules.python.source.elements.AstElement;
98.10 +import org.netbeans.modules.python.source.elements.Element;
98.11 import org.netbeans.editor.BaseDocument;
98.12 import org.netbeans.modules.csl.api.ElementKind;
98.13 import org.netbeans.modules.csl.spi.GsfUtilities;
98.14 -import org.netbeans.modules.python.editor.AstPath;
98.15 -import org.netbeans.modules.python.editor.PythonAstUtils;
98.16 -import org.netbeans.modules.python.editor.PythonParserResult;
98.17 -import org.netbeans.modules.python.editor.elements.IndexedElement;
98.18 +import org.netbeans.modules.python.source.AstPath;
98.19 +import org.netbeans.modules.python.source.PythonAstUtils;
98.20 +import org.netbeans.modules.python.source.PythonParserResult;
98.21 +import org.netbeans.modules.python.source.elements.IndexedElement;
98.22 import org.openide.filesystems.FileObject;
98.23 import org.python.antlr.PythonTree;
98.24 import org.python.antlr.ast.Assign;
99.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefUtils.java Fri Sep 18 16:20:24 2015 -0500
99.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefUtils.java Mon Sep 21 13:01:16 2015 +0200
99.3 @@ -72,10 +72,10 @@
99.4 import org.netbeans.modules.csl.api.ElementKind;
99.5 import org.netbeans.modules.parsing.api.Source;
99.6 import org.netbeans.modules.python.api.PythonMIMEResolver;
99.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
99.8 -import org.netbeans.modules.python.editor.PythonParserResult;
99.9 -import org.netbeans.modules.python.editor.PythonUtils;
99.10 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
99.11 +import org.netbeans.modules.python.source.PythonAstUtils;
99.12 +import org.netbeans.modules.python.source.PythonParserResult;
99.13 +import org.netbeans.modules.python.source.PythonUtils;
99.14 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
99.15 import org.openide.cookies.EditorCookie;
99.16 import org.openide.filesystems.FileObject;
99.17 import org.openide.util.Lookup;
100.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefactoringsFactory.java Fri Sep 18 16:20:24 2015 -0500
100.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefactoringsFactory.java Mon Sep 21 13:01:16 2015 +0200
100.3 @@ -43,7 +43,7 @@
100.4 */
100.5 package org.netbeans.modules.python.editor.refactoring;
100.6
100.7 -import org.netbeans.modules.python.editor.PythonUtils;
100.8 +import org.netbeans.modules.python.source.PythonUtils;
100.9 import org.netbeans.modules.refactoring.api.AbstractRefactoring;
100.10 import org.netbeans.modules.refactoring.api.RenameRefactoring;
100.11 import org.netbeans.modules.refactoring.api.WhereUsedQuery;
101.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/WhereUsedElement.java Fri Sep 18 16:20:24 2015 -0500
101.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/WhereUsedElement.java Mon Sep 21 13:01:16 2015 +0200
101.3 @@ -54,9 +54,9 @@
101.4 import org.netbeans.modules.csl.api.OffsetRange;
101.5 import org.netbeans.modules.csl.api.UiUtils;
101.6 import org.netbeans.modules.csl.spi.GsfUtilities;
101.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
101.8 -import org.netbeans.modules.python.editor.PythonParserResult;
101.9 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
101.10 +import org.netbeans.modules.python.source.PythonAstUtils;
101.11 +import org.netbeans.modules.python.source.PythonParserResult;
101.12 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
101.13 import org.netbeans.modules.python.editor.refactoring.ui.ElementGripFactory;
101.14 import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
101.15 import org.openide.filesystems.FileObject;
102.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/ui/RefactoringActionsProvider.java Fri Sep 18 16:20:24 2015 -0500
102.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/ui/RefactoringActionsProvider.java Mon Sep 21 13:01:16 2015 +0200
102.3 @@ -64,14 +64,14 @@
102.4 import org.netbeans.modules.refactoring.spi.ui.UI;
102.5 import org.netbeans.modules.refactoring.spi.ui.ActionsImplementationProvider;
102.6 import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
102.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
102.8 -import org.netbeans.modules.python.editor.PythonIndex;
102.9 -import org.netbeans.modules.python.editor.PythonParserResult;
102.10 -import org.netbeans.modules.python.editor.PythonStructureScanner;
102.11 -import org.netbeans.modules.python.editor.PythonStructureScanner.AnalysisResult;
102.12 -import org.netbeans.modules.python.editor.PythonUtils;
102.13 -import org.netbeans.modules.python.editor.elements.AstElement;
102.14 -import org.netbeans.modules.python.editor.elements.Element;
102.15 +import org.netbeans.modules.python.source.PythonAstUtils;
102.16 +import org.netbeans.modules.python.source.PythonIndex;
102.17 +import org.netbeans.modules.python.source.PythonParserResult;
102.18 +import org.netbeans.modules.python.source.PythonStructureScanner;
102.19 +import org.netbeans.modules.python.source.PythonStructureScanner.AnalysisResult;
102.20 +import org.netbeans.modules.python.source.PythonUtils;
102.21 +import org.netbeans.modules.python.source.elements.AstElement;
102.22 +import org.netbeans.modules.python.source.elements.Element;
102.23 import org.openide.ErrorManager;
102.24 import org.openide.cookies.EditorCookie;
102.25 import org.openide.filesystems.FileObject;
103.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ArgListCompiler.java Fri Sep 18 16:20:24 2015 -0500
103.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
103.3 @@ -1,121 +0,0 @@
103.4 -// Copyright (c) Corporation for National Research Initiatives
103.5 -package org.netbeans.modules.python.editor.scopes;
103.6 -
103.7 -import java.util.ArrayList;
103.8 -
103.9 -import java.util.List;
103.10 -import org.python.antlr.PythonTree;
103.11 -import org.python.antlr.Visitor;
103.12 -import org.python.antlr.ast.Assign;
103.13 -import org.python.antlr.ast.Name;
103.14 -import org.python.antlr.ast.Suite;
103.15 -import org.python.antlr.ast.Tuple;
103.16 -import org.python.antlr.ast.arguments;
103.17 -import org.python.antlr.ast.expr_contextType;
103.18 -import org.python.antlr.base.expr;
103.19 -import org.python.antlr.base.stmt;
103.20 -
103.21 -/** Based on org.python.compiler.ArgListCompiler */
103.22 -public class ArgListCompiler extends Visitor {
103.23 - public boolean arglist, keywordlist;
103.24 - public List<expr> defaults;
103.25 - public List<String> names;
103.26 - public ArrayList<PythonTree> nodes;
103.27 - public List<String> fpnames;
103.28 - public List<stmt> init_code;
103.29 - private SymbolTable symbolTable;
103.30 -
103.31 - public ArgListCompiler(SymbolTable symbolTable) {
103.32 - this.symbolTable = symbolTable;
103.33 - arglist = keywordlist = false;
103.34 - defaults = null;
103.35 - names = new ArrayList<>();
103.36 - nodes = new ArrayList<>();
103.37 - fpnames = new ArrayList<>();
103.38 - init_code = new ArrayList<>();
103.39 - }
103.40 -
103.41 - public void reset() {
103.42 - arglist = keywordlist = false;
103.43 - defaults = null;
103.44 - names.clear();
103.45 - nodes.clear();
103.46 - init_code.clear();
103.47 - }
103.48 -
103.49 - public void appendInitCode(Suite node) {
103.50 - node.getInternalBody().addAll(0, init_code);
103.51 - }
103.52 -
103.53 - public List<expr> getDefaults() {
103.54 - return defaults;
103.55 - }
103.56 -
103.57 - public void visitArgs(arguments args) throws Exception {
103.58 - for (int i = 0; i < args.getInternalArgs().size(); i++) {
103.59 - expr node = args.getInternalArgs().get(i);
103.60 - String name = (String)visit(node);
103.61 - names.add(name);
103.62 - nodes.add(node);
103.63 - if (node instanceof Tuple) {
103.64 - List<expr> targets = new ArrayList<>();
103.65 - targets.add(node);
103.66 - Assign ass = new Assign(node,
103.67 - targets,
103.68 - new Name(node, name, expr_contextType.Load));
103.69 - init_code.add(ass);
103.70 - }
103.71 - }
103.72 - if (args.getInternalVararg() != null) {
103.73 - arglist = true;
103.74 - names.add(args.getInternalVararg());
103.75 - //nodes.add(null); // no corresponding node?
103.76 - nodes.add(args); // just use the corresponding args node instead
103.77 - }
103.78 - if (args.getInternalKwarg() != null) {
103.79 - keywordlist = true;
103.80 - names.add(args.getInternalKwarg());
103.81 - //nodes.add(null); // no corresponding node?
103.82 - nodes.add(args); // just use the corresponding args node instead
103.83 - }
103.84 -
103.85 - defaults = args.getInternalDefaults();
103.86 - for (int i = 0; i < defaults.size(); i++) {
103.87 - if (defaults.get(i) == null) {
103.88 - symbolTable.error("non-default argument follows default argument", true,
103.89 - args.getInternalArgs().get(args.getInternalArgs().size() - defaults.size() + i));
103.90 - }
103.91 - }
103.92 - }
103.93 -
103.94 - @Override
103.95 - public Object visitName(Name node) throws Exception {
103.96 - //FIXME: do we need Store and Param, or just Param?
103.97 - if (node.getInternalCtx() != expr_contextType.Store && node.getInternalCtx() != expr_contextType.Param) {
103.98 - return null;
103.99 - }
103.100 -
103.101 - if (fpnames.contains(node.getInternalId())) {
103.102 - symbolTable.error("duplicate argument name found: " +
103.103 - node.getInternalId(), true, node);
103.104 - }
103.105 - fpnames.add(node.getInternalId());
103.106 - return node.getInternalId();
103.107 - }
103.108 -
103.109 - @Override
103.110 - public Object visitTuple(Tuple node) throws Exception {
103.111 - StringBuffer name = new StringBuffer("(");
103.112 - List<expr> elts = node.getInternalElts();
103.113 - if (elts != null) {
103.114 - int n = elts.size();
103.115 - for (int i = 0; i < n - 1; i++) {
103.116 - name.append(visit(elts.get(i)));
103.117 - name.append(", ");
103.118 - }
103.119 - name.append(visit(elts.get(n - 1)));
103.120 - }
103.121 - name.append(")");
103.122 - return name.toString();
103.123 - }
103.124 -}
104.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ScopeConstants.java Fri Sep 18 16:20:24 2015 -0500
104.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
104.3 @@ -1,28 +0,0 @@
104.4 -package org.netbeans.modules.python.editor.scopes;
104.5 -
104.6 -/** Based on org.python.compiler.ScopeConstants in Jython */
104.7 -public interface ScopeConstants {
104.8 - public final static int BOUND = 1 << 0;
104.9 - public final static int NGLOBAL = 1 << 1; // func scope expl global
104.10 - public final static int PARAM = 1 << 2;
104.11 - public final static int FROM_PARAM = 1 << 3;
104.12 - public final static int CELL = 1 << 4;
104.13 - public final static int FREE = 1 << 5;
104.14 - public final static int CLASS_GLOBAL = 1 << 6; // class scope expl global
104.15 - public final static int READ = 1 << 7;
104.16 - public final static int CALLED = 1 << 8;
104.17 - public final static int DEF = 1 << 9;
104.18 - public final static int IMPORTED = 1 << 10;
104.19 - public final static int CLASS = 1 << 11;
104.20 - public final static int FUNCTION = 1 << 12;
104.21 - public final static int MEMBER = 1 << 13;
104.22 - public final static int GENERATOR = 1 << 13; // it's a generator expression
104.23 - public final static int PRIVATE = 1 << 14;
104.24 - public final static int ALIAS = 1 << 15;
104.25 - public final static int PROTECTED = 1 << 16;
104.26 - public final static int BOUND_IN_CONSTRUCTOR = 1 << 17;
104.27 - public final static int GLOBAL = NGLOBAL | CLASS_GLOBAL; // all global
104.28 - public final static int TOPSCOPE = 0;
104.29 - public final static int FUNCSCOPE = 1;
104.30 - public final static int CLASSSCOPE = 2;
104.31 -}
105.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ScopeInfo.java Fri Sep 18 16:20:24 2015 -0500
105.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
105.3 @@ -1,575 +0,0 @@
105.4 -// (C) Copyright 2001 Samuele Pedroni
105.5 -package org.netbeans.modules.python.editor.scopes;
105.6 -
105.7 -import java.util.ArrayList;
105.8 -import java.util.Collections;
105.9 -import java.util.HashMap;
105.10 -import java.util.LinkedHashMap;
105.11 -import java.util.Map;
105.12 -import java.util.List;
105.13 -
105.14 -import org.netbeans.modules.python.editor.AstPath;
105.15 -import org.netbeans.modules.python.editor.PythonAstUtils;
105.16 -import org.python.antlr.ParseException;
105.17 -import org.python.antlr.PythonTree;
105.18 -import org.python.antlr.ast.Assign;
105.19 -import org.python.antlr.ast.Attribute;
105.20 -import org.python.antlr.ast.ClassDef;
105.21 -import org.python.antlr.ast.Name;
105.22 -import org.python.antlr.ast.Return;
105.23 -import org.python.antlr.ast.Tuple;
105.24 -import org.python.antlr.base.expr;
105.25 -import static org.netbeans.modules.python.editor.scopes.ScopeConstants.*;
105.26 -
105.27 -/**
105.28 - * Based on org.python.compiler.ScopeInfo in Jython
105.29 - *
105.30 - * See {@link ScopesCompiler} for details on my modifications
105.31 - */
105.32 -@SuppressWarnings("unchecked")
105.33 -public class ScopeInfo extends Object {
105.34 - public PythonTree scope_node;
105.35 - public String scope_name;
105.36 - public int level;
105.37 - public int func_level;
105.38 - public boolean hidden;
105.39 -
105.40 - public String dump() {
105.41 - StringBuilder sb = new StringBuilder();
105.42 -
105.43 - for (int i = 0; i < level; i++) {
105.44 - sb.append(" ");
105.45 - }
105.46 - sb.append("=============================================\n");
105.47 - for (int i = 0; i < level; i++) {
105.48 - sb.append(" ");
105.49 - }
105.50 - sb.append(((kind != CLASSSCOPE) ? scope_name : "class " +
105.51 - scope_name) + ": " + scope_node + " : " + PythonAstUtils.getRange(scope_node) + "\n");
105.52 - //for(int i=0; i<level; i++) sb.append(" ");
105.53 - //sb.append("UP=" + up);
105.54 - //sb.append(" NESTED=" + nested);
105.55 - //sb.append("\n");
105.56 -
105.57 -
105.58 - // Sort to make test output stable
105.59 - List<String> keys = new ArrayList<>(tbl.keySet());
105.60 - Collections.sort(keys);
105.61 - for (String name : keys) {
105.62 - SymInfo info = tbl.get(name);
105.63 - for (int i = 0; i < level; i++) {
105.64 - sb.append(" ");
105.65 - }
105.66 - sb.append(name);
105.67 - sb.append(" ");
105.68 - sb.append(info.dumpFlags(this));
105.69 - sb.append("\n");
105.70 - }
105.71 -
105.72 - if (inner_free.size() > 0 || cellvars.size() > 0 || jy_paramcells.size() > 0 ||
105.73 - jy_npurecell != 0 /*|| cell != 0 || distance != 0 || up != null*/) {
105.74 - for (int i = 0; i < level; i++) {
105.75 - sb.append(" ");
105.76 - }
105.77 - sb.append("---------------------------------------------\n");
105.78 - }
105.79 -
105.80 - if (inner_free.size() > 0) {
105.81 - List<String> sorted = new ArrayList<>();
105.82 - for (String s : inner_free.keySet()) {
105.83 - sorted.add(s + "=" + inner_free.get(s));
105.84 - }
105.85 - Collections.sort(sorted);
105.86 -
105.87 - for (int i = 0; i < level; i++) {
105.88 - sb.append(" ");
105.89 - }
105.90 - sb.append("inner_free: {"); // NOI18N
105.91 - boolean first = true;
105.92 - for (String s : sorted) {
105.93 - if (first) {
105.94 - first = false;
105.95 - } else {
105.96 - sb.append(", "); // NOI18N
105.97 - }
105.98 - sb.append(s);
105.99 - }
105.100 - sb.append("}\n"); // NOI18N
105.101 - }
105.102 - if (cellvars.size() > 0) {
105.103 - Collections.sort(cellvars);
105.104 - for (int i = 0; i < level; i++) {
105.105 - sb.append(" ");
105.106 - }
105.107 - sb.append("cellvars: " + cellvars.toString() + "\n"); // TODO - sort
105.108 - }
105.109 - if (jy_paramcells.size() > 0) {
105.110 - Collections.sort(jy_paramcells);
105.111 - for (int i = 0; i < level; i++) {
105.112 - sb.append(" ");
105.113 - }
105.114 - sb.append("jy_paramcells: " + jy_paramcells.toString() + "\n"); // TODO - sort
105.115 - }
105.116 - if (jy_npurecell != 0) {
105.117 - for (int i = 0; i < level; i++) {
105.118 - sb.append(" ");
105.119 - }
105.120 - sb.append("jy_npurecell: " + jy_npurecell + "\n"); // TODO - sort
105.121 - }
105.122 - //if (cell != 0) {
105.123 - // for(int i=0; i<level; i++) sb.append(" ");
105.124 - // sb.append("cell: " + cell + "\n"); // TODO - sort
105.125 - //}
105.126 - //if (distance != 0) {
105.127 - // for(int i=0; i<level; i++) sb.append(" ");
105.128 - // sb.append("distance: " + distance + "\n"); // TODO - sort
105.129 - //}
105.130 - //if (up != null) {
105.131 - // for(int i=0; i<level; i++) sb.append(" ");
105.132 - // sb.append("up: " + up.scope_node);
105.133 - //}
105.134 -
105.135 - if (attributes.size() > 0) {
105.136 - for (int i = 0; i < level; i++) {
105.137 - sb.append(" ");
105.138 - }
105.139 - sb.append("------ Attributes ---------------------------------------\n"); // NOI18N
105.140 - // Sort
105.141 - List<String> attributeNames = new ArrayList<>(attributes.keySet());
105.142 - Collections.sort(attributeNames);
105.143 - for (String attributeName : attributeNames) {
105.144 - for (int i = 0; i < level; i++) {
105.145 - sb.append(" ");
105.146 - }
105.147 - sb.append(attributeName);
105.148 - sb.append(" : "); // NOI18N
105.149 - sb.append(attributes.get(attributeName));
105.150 - sb.append("\n"); // NOI18N
105.151 - }
105.152 - }
105.153 -
105.154 - return sb.toString();
105.155 - }
105.156 -
105.157 - public ScopeInfo(String name, PythonTree node, int level, int kind,
105.158 - int func_level, ArgListCompiler ac) {
105.159 - scope_name = name;
105.160 - scope_node = node;
105.161 - this.level = level;
105.162 - this.kind = kind;
105.163 - this.func_level = func_level;
105.164 - this.ac = ac;
105.165 - }
105.166 - public int kind;
105.167 - public boolean unqual_exec;
105.168 - public boolean exec;
105.169 - public boolean from_import_star;
105.170 - public boolean contains_ns_free_vars;
105.171 - public boolean generator;
105.172 - private boolean hasReturnWithValue;
105.173 - public int yield_count;
105.174 - public int max_with_count;
105.175 - public ArgListCompiler ac;
105.176 - public Map<String, SymInfo> tbl = new LinkedHashMap<>();
105.177 -
105.178 - // define a separate dictionary for dynamic bounded variables
105.179 - public Map<String, SymInfo> attributes = new HashMap<>();
105.180 - public List<String> names = new ArrayList<>();
105.181 -
105.182 - private void addAttributeEntry(String name, PythonTree node, int flags) {
105.183 - SymInfo info = attributes.get(name);
105.184 - if (info == null) {
105.185 - SymInfo entry = new SymInfo(flags);
105.186 - if (SymInfo.isPrivateName(name)) {
105.187 - entry.flags |= PRIVATE;
105.188 - } else if (SymInfo.isProtectedName(name)) {
105.189 - entry.flags |= PROTECTED;
105.190 - }
105.191 - entry.node = node;
105.192 - attributes.put(name, entry);
105.193 - }
105.194 - }
105.195 -
105.196 - private void addToClassScope(String name, PythonTree node, boolean inConstructor) {
105.197 - int flags = CLASSSCOPE | BOUND | MEMBER;
105.198 - if (inConstructor) {
105.199 - flags |= BOUND_IN_CONSTRUCTOR;
105.200 - }
105.201 - addAttributeEntry(name, node, flags);
105.202 - }
105.203 -
105.204 - public ScopeInfo getClassScope() {
105.205 - ScopeInfo cur = this;
105.206 - while ((cur != null) &&
105.207 - (!(cur.scope_node instanceof ClassDef))) {
105.208 - cur = cur.nested;
105.209 - }
105.210 - return cur;
105.211 - }
105.212 -
105.213 - private boolean belongsToExprList(List<expr> types, expr cur) {
105.214 - return types != null && types.contains(cur);
105.215 - }
105.216 -
105.217 - boolean isAttributeAssigment(AstPath path, Attribute attr) {
105.218 - PythonTree leaf = path.leaf();
105.219 - Assign assign = null;
105.220 - expr target = attr; // default to single
105.221 - if (leaf instanceof Assign) {
105.222 - assign = (Assign)leaf;
105.223 - } else if (leaf instanceof Tuple) {
105.224 - // check for tuple assignment
105.225 - Tuple tuple = (Tuple)leaf;
105.226 - PythonTree tupleParent = path.leafParent();
105.227 - if (belongsToExprList(tuple.getInternalElts(), attr)) {
105.228 - if (tupleParent instanceof Assign) {
105.229 - assign = (Assign)tupleParent;
105.230 - target = tuple; // tuple assignment target
105.231 - }
105.232 - }
105.233 - }
105.234 - // check if we got assignment
105.235 - if (assign == null) {
105.236 - return false;
105.237 - }
105.238 - if (belongsToExprList(assign.getInternalTargets(), target)) {
105.239 - return true;
105.240 - }
105.241 - return false;
105.242 - }
105.243 -
105.244 - public void addAttribute(AstPath path, String name, PythonTree node) {
105.245 - // deeply check assignment context for attribute.
105.246 - Attribute curAttr = (Attribute)node;
105.247 -
105.248 - if (curAttr.getInternalValue() instanceof Attribute) {
105.249 - // recursice attributes( x.y.z.w ) to be handled later
105.250 - } else if (curAttr.getInternalValue() instanceof Name) {
105.251 -
105.252 - Name parentName = (Name)curAttr.getInternalValue();
105.253 -
105.254 - ScopeInfo classScope = getClassScope();
105.255 - boolean inConstructor = false;
105.256 - String parName = parentName.getInternalId();
105.257 -
105.258 - // for simplicity handle only at classScope in current source
105.259 - if (classScope != null) {
105.260 - // check for self or inherited parent name prefix
105.261 - if ((parName.equals("self")) ||
105.262 - (PythonAstUtils.getParentClassFromNode(path, classScope.scope_node, parName) != null)) {
105.263 - if (!(parName.equals("self"))) {
105.264 - // check classname not overridden by local scope variable
105.265 - if (tbl.get(parName) != null) {
105.266 - return;
105.267 - }
105.268 - }
105.269 - if (scope_name.equals("__init__") || scope_name.equals("__new__")) {
105.270 - inConstructor = true; // set in constructor
105.271 - }
105.272 - //
105.273 - // put in class scope
105.274 - if (isAttributeAssigment(path, curAttr)) {
105.275 - classScope.addToClassScope(name, node, inConstructor);
105.276 - } else {
105.277 - // store at current scope if parName is not overriding
105.278 - // classname at current scope
105.279 - int flags = CLASSSCOPE | READ;
105.280 - addAttributeEntry(name, node, flags);
105.281 - }
105.282 - }
105.283 - }
105.284 - }
105.285 - }
105.286 -
105.287 - public int addGlobal(String name, PythonTree node) {
105.288 - // global kind = func vs. class
105.289 - int global = kind == CLASSSCOPE ? CLASS_GLOBAL : NGLOBAL;
105.290 - SymInfo info = tbl.get(name);
105.291 - if (info == null) {
105.292 - SymInfo entry = new SymInfo(global | BOUND);
105.293 - if (SymInfo.isPrivateName(name)) {
105.294 - entry.flags |= PRIVATE;
105.295 - } else if (SymInfo.isProtectedName(name)) {
105.296 - entry.flags |= PROTECTED;
105.297 - }
105.298 - entry.node = node;
105.299 - tbl.put(name, entry);
105.300 - return -1;
105.301 - }
105.302 - int prev = info.flags;
105.303 - info.flags |= global | BOUND;
105.304 - return prev;
105.305 - }
105.306 - public int local = 0;
105.307 -
105.308 - public void addParam(String name, PythonTree node) {
105.309 - SymInfo entry = new SymInfo(PARAM | BOUND, local++);
105.310 - entry.node = node;
105.311 - tbl.put(name, entry);
105.312 - names.add(name);
105.313 - }
105.314 -
105.315 - // <netbeans>
105.316 - public boolean isUnused(String name) {
105.317 - SymInfo info = tbl.get(name);
105.318 - if (info != null) {
105.319 - return info.isUnused(this);
105.320 - }
105.321 - return false;
105.322 - }
105.323 -
105.324 - public boolean isParameter(String name) {
105.325 - SymInfo info = tbl.get(name);
105.326 - if (info != null) {
105.327 - return info.isParameter();
105.328 - }
105.329 - return false;
105.330 - }
105.331 - // </netbeans>
105.332 -
105.333 - public void markFromParam() {
105.334 - for (SymInfo info : tbl.values()) {
105.335 - info.flags |= FROM_PARAM;
105.336 - }
105.337 - }
105.338 -
105.339 - public SymInfo addBound(String name, PythonTree node) {
105.340 - SymInfo info = tbl.get(name);
105.341 - if (info == null) {
105.342 - info = new SymInfo(BOUND);
105.343 - if (SymInfo.isPrivateName(name)) {
105.344 - info.flags |= PRIVATE;
105.345 - } else if (SymInfo.isProtectedName(name)) {
105.346 - info.flags |= PROTECTED;
105.347 - }
105.348 - tbl.put(name, info);
105.349 - info.node = node;
105.350 - return info;
105.351 - }
105.352 - info.flags |= BOUND;
105.353 -
105.354 - return info;
105.355 - }
105.356 -
105.357 - public SymInfo addUsed(String name, PythonTree node) {
105.358 - SymInfo info = tbl.get(name);
105.359 - if (info == null) {
105.360 - // <netbeans>
105.361 - info = new SymInfo(0);
105.362 - tbl.put(name, info);
105.363 - info.node = node;
105.364 - }
105.365 - info.flags |= READ;
105.366 -
105.367 - return info;
105.368 - // </netbeans>
105.369 - }
105.370 -
105.371 -
105.372 - // <netbeans>
105.373 - void markCall(String name) {
105.374 - SymInfo entry = tbl.get(name);
105.375 - if (entry != null) {
105.376 - entry.flags |= CALLED;
105.377 - }
105.378 - }
105.379 - // </netbeans>
105.380 - private final static String PRESENT = new String("PRESENT");
105.381 - public HashMap<String, String> inner_free = new HashMap<>();
105.382 - public List<String> cellvars = new ArrayList<>();
105.383 - public List<String> jy_paramcells = new ArrayList<>();
105.384 - public int jy_npurecell;
105.385 - public int cell, distance;
105.386 - public ScopeInfo up;
105.387 - public ScopeInfo nested;
105.388 -
105.389 - //Resolve the names used in the given scope, and mark any freevars used in the up scope
105.390 - public void cook(ScopeInfo up, int distance, SymbolTable ctxt) throws Exception {
105.391 - if (up == null) {
105.392 - return; // top level => nop
105.393 - }
105.394 - this.up = up;
105.395 - this.distance = distance;
105.396 - boolean func = kind == FUNCSCOPE;
105.397 - List<String> purecells = new ArrayList<>();
105.398 - cell = 0;
105.399 - boolean some_inner_free = inner_free.size() > 0;
105.400 -
105.401 - for (String name : inner_free.keySet()) {
105.402 -
105.403 - SymInfo info = tbl.get(name);
105.404 - if (info == null) {
105.405 - tbl.put(name, new SymInfo(FREE));
105.406 - continue;
105.407 - }
105.408 - int flags = info.flags;
105.409 - if (func) {
105.410 - // not func global and bound ?
105.411 - if ((flags & NGLOBAL) == 0 && (flags & BOUND) != 0) {
105.412 - info.flags |= CELL;
105.413 - if ((info.flags & PARAM) != 0) {
105.414 - jy_paramcells.add(name);
105.415 - }
105.416 - cellvars.add(name);
105.417 - info.env_index = cell++;
105.418 - if ((flags & PARAM) == 0) {
105.419 - purecells.add(name);
105.420 - }
105.421 - continue;
105.422 - }
105.423 - } else {
105.424 - info.flags |= FREE;
105.425 - }
105.426 - }
105.427 - boolean some_free = false;
105.428 -
105.429 - boolean nested = up.kind != TOPSCOPE;
105.430 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
105.431 - String name = entry.getKey();
105.432 - SymInfo info = entry.getValue();
105.433 - int flags = info.flags;
105.434 - if (nested && (flags & FREE) != 0) {
105.435 - up.inner_free.put(name, PRESENT);
105.436 - }
105.437 - if ((flags & (GLOBAL | PARAM | CELL)) == 0) {
105.438 - if ((flags & BOUND) != 0) { // ?? only func
105.439 - // System.err.println("local: "+name);
105.440 - names.add(name);
105.441 - info.locals_index = local++;
105.442 - continue;
105.443 - }
105.444 - info.flags |= FREE;
105.445 - some_free = true;
105.446 - if (nested) {
105.447 - up.inner_free.put(name, PRESENT);
105.448 - }
105.449 - }
105.450 -
105.451 - // <netbeans>
105.452 - if ((info.flags & FREE) != 0) {
105.453 - // Mark definition symbol as read as well
105.454 - ScopeInfo curr = up;
105.455 - while (curr != null) {
105.456 - SymInfo s = curr.tbl.get(name);
105.457 - if (s != null && ((s.flags & BOUND) != 0)) {
105.458 - s.flags |= READ;
105.459 - s.flags |= (info.flags & (CALLED));
105.460 - break;
105.461 - }
105.462 - curr = curr.up;
105.463 - while (curr != null && curr.kind == CLASSSCOPE) {
105.464 - curr = curr.up;
105.465 - }
105.466 - }
105.467 - }
105.468 -
105.469 - // </netbeans>
105.470 - }
105.471 - if ((jy_npurecell = purecells.size()) > 0) {
105.472 - int sz = purecells.size();
105.473 - for (int i = 0; i < sz; i++) {
105.474 - names.add(purecells.get(i));
105.475 - }
105.476 - }
105.477 -
105.478 - if (some_free && nested) {
105.479 - up.contains_ns_free_vars = true;
105.480 - }
105.481 - // XXX - this doesn't catch all cases - may depend subtly
105.482 - // on how visiting NOW works with antlr compared to javacc
105.483 - if ((unqual_exec || from_import_star)) {
105.484 - if (some_inner_free) {
105.485 - dynastuff_trouble(true, ctxt);
105.486 - } else if (func_level > 1 && some_free) {
105.487 - dynastuff_trouble(false, ctxt);
105.488 - }
105.489 - }
105.490 -
105.491 - }
105.492 -
105.493 - private void dynastuff_trouble(boolean inner_free,
105.494 - SymbolTable ctxt) throws Exception {
105.495 - String illegal;
105.496 - if (unqual_exec && from_import_star) {
105.497 - illegal = "function '" + scope_name +
105.498 - "' uses import * and bare exec, which are illegal";
105.499 - } else if (unqual_exec) {
105.500 - illegal = "unqualified exec is not allowed in function '" +
105.501 - scope_name + "'";
105.502 - } else {
105.503 - illegal = "import * is not allowed in function '" + scope_name + "'";
105.504 - }
105.505 - String why;
105.506 - if (inner_free) {
105.507 - why = " because it contains a function with free variables";
105.508 - } else {
105.509 - why = " because it contains free variables";
105.510 - }
105.511 - ctxt.error(illegal + why, true, scope_node);
105.512 - }
105.513 - public List<String> freevars = new ArrayList<>();
105.514 -
105.515 - /**
105.516 - * setup the closure on this scope using the scope passed into cook as up as
105.517 - * the containing scope
105.518 - */
105.519 - public void setup_closure() {
105.520 - setup_closure(up);
105.521 - }
105.522 -
105.523 - /**
105.524 - * setup the closure on this scope using the passed in scope. This is used
105.525 - * by jythonc to setup its closures.
105.526 - */
105.527 - public void setup_closure(ScopeInfo up) {
105.528 - int free = cell; // env = cell...,free...
105.529 - Map<String, SymInfo> up_tbl = up.tbl;
105.530 - boolean nested = up.kind != TOPSCOPE;
105.531 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
105.532 - String name = entry.getKey();
105.533 - SymInfo info = entry.getValue();
105.534 - int flags = info.flags;
105.535 - if ((flags & FREE) != 0) {
105.536 - SymInfo up_info = up_tbl.get(name);
105.537 - // ?? differs from CPython -- what is the intended behaviour?
105.538 - if (up_info != null) {
105.539 - int up_flags = up_info.flags;
105.540 - if ((up_flags & (CELL | FREE)) != 0) {
105.541 - info.env_index = free++;
105.542 - freevars.add(name);
105.543 - continue;
105.544 - }
105.545 - // ! func global affect nested scopes
105.546 - if (nested && (up_flags & NGLOBAL) != 0) {
105.547 - info.flags = NGLOBAL | BOUND;
105.548 - continue;
105.549 - }
105.550 - }
105.551 - info.flags &= ~FREE;
105.552 - }
105.553 - }
105.554 -
105.555 - }
105.556 -
105.557 - @Override
105.558 - public String toString() {
105.559 - return "ScopeInfo[" + scope_name + " " + kind + "]@" +
105.560 - System.identityHashCode(this);
105.561 - }
105.562 -
105.563 - public void defineAsGenerator(expr node) {
105.564 - generator = true;
105.565 - if (hasReturnWithValue) {
105.566 - throw new ParseException("'return' with argument " +
105.567 - "inside generator", node);
105.568 - }
105.569 - }
105.570 -
105.571 - public void noteReturnValue(Return node) {
105.572 - if (generator) {
105.573 - throw new ParseException("'return' with argument " +
105.574 - "inside generator", node);
105.575 - }
105.576 - hasReturnWithValue = true;
105.577 - }
105.578 -}
106.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ScopesCompiler.java Fri Sep 18 16:20:24 2015 -0500
106.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
106.3 @@ -1,641 +0,0 @@
106.4 -// (C) Copyright 2001 Samuele Pedroni
106.5 -package org.netbeans.modules.python.editor.scopes;
106.6 -
106.7 -import java.util.ArrayList;
106.8 -import java.util.List;
106.9 -import java.util.Map;
106.10 -import java.util.Set;
106.11 -import java.util.Stack;
106.12 -import org.netbeans.modules.python.editor.AstPath;
106.13 -import org.openide.util.Exceptions;
106.14 -import org.python.antlr.PythonTree;
106.15 -import org.python.antlr.Visitor;
106.16 -import org.python.antlr.ast.Assign;
106.17 -import org.python.antlr.ast.Attribute;
106.18 -import org.python.antlr.ast.Call;
106.19 -import org.python.antlr.ast.ClassDef;
106.20 -import org.python.antlr.ast.Delete;
106.21 -import org.python.antlr.ast.Exec;
106.22 -import org.python.antlr.ast.Expression;
106.23 -import org.python.antlr.ast.FunctionDef;
106.24 -import org.python.antlr.ast.GeneratorExp;
106.25 -import org.python.antlr.ast.Global;
106.26 -import org.python.antlr.ast.Import;
106.27 -import org.python.antlr.ast.ImportFrom;
106.28 -import org.python.antlr.ast.Interactive;
106.29 -import org.python.antlr.ast.Lambda;
106.30 -import org.python.antlr.ast.ListComp;
106.31 -import org.python.antlr.ast.Name;
106.32 -import org.python.antlr.ast.Return;
106.33 -import org.python.antlr.ast.Str;
106.34 -import org.python.antlr.ast.With;
106.35 -import org.python.antlr.ast.Yield;
106.36 -import org.python.antlr.ast.alias;
106.37 -import org.python.antlr.ast.arguments;
106.38 -import org.python.antlr.base.expr;
106.39 -import org.python.antlr.ast.expr_contextType;
106.40 -import org.python.antlr.base.stmt;
106.41 -
106.42 -/**
106.43 - * Based on org.python.compiler.ScopesCompiler in Jython
106.44 - *
106.45 - * Modifications I've made:
106.46 - * - Methods for finding all the free variables
106.47 - * - Methods for identifying unused bound variables
106.48 - * - Track whether symbols are referenced as calls or not
106.49 - * (so I can determine whether to look in the index for
106.50 - * functions or data etc. when trying to resolve imports)
106.51 - * - Track variable reads/writes
106.52 - * - Track imports etc.
106.53 - * - Add nodes to each SymInfo
106.54 - * - Replace old style Java (Hashtable, Vector, implements ScopeConstants) with
106.55 - * modern Java (HashMap, ArrayList, import static)
106.56 - *
106.57 - */
106.58 -@SuppressWarnings("unchecked")
106.59 -public class ScopesCompiler extends Visitor implements ScopeConstants {
106.60 - private SymbolTable symbolTable;
106.61 - private Stack scopes;
106.62 - private ScopeInfo cur = null;
106.63 - private Map<PythonTree, ScopeInfo> nodeScopes;
106.64 - private int level = 0;
106.65 - private int func_level = 0;
106.66 - private List<Import> imports;
106.67 - private List<PythonTree> mainImports;
106.68 - private List<ImportFrom> importsFrom;
106.69 - private Set<PythonTree> topLevelImports;
106.70 - private PythonTree root;
106.71 - private PythonTree parent;
106.72 - private AstPath path = new AstPath();
106.73 - /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
106.74 - private List<Str> publicSymbols;
106.75 - /** Set to true if we encountered manipulation on __all__ that I don't understand */
106.76 - private boolean invalidPublicSymbols;
106.77 -
106.78 - public ScopesCompiler(SymbolTable symbolTable, Map<PythonTree, ScopeInfo> nodeScopes, PythonTree root,
106.79 - List<Import> imports, List<ImportFrom> importsFrom, List<PythonTree> mainImports, Set<PythonTree> topLevelImports) {
106.80 - this.symbolTable = symbolTable;
106.81 - this.nodeScopes = nodeScopes;
106.82 - scopes = new Stack();
106.83 - this.root = root;
106.84 -
106.85 - this.imports = imports;
106.86 - this.importsFrom = importsFrom;
106.87 - this.mainImports = mainImports;
106.88 - this.topLevelImports = topLevelImports;
106.89 - }
106.90 -
106.91 - @Override
106.92 - public void traverse(PythonTree node) throws Exception {
106.93 - // Jython's parser often doesn't set the parent references correctly
106.94 - // so try to fix that here
106.95 - node.setParent(parent);
106.96 -
106.97 - PythonTree oldParent = parent;
106.98 - parent = node;
106.99 -
106.100 - path.descend(node);
106.101 - super.traverse(node);
106.102 - parent = oldParent;
106.103 - path.ascend();
106.104 - }
106.105 -
106.106 - public void beginScope(String name, int kind, PythonTree node,
106.107 - ArgListCompiler ac) {
106.108 - if (cur != null) {
106.109 - scopes.push(cur);
106.110 - }
106.111 - if (kind == FUNCSCOPE) {
106.112 - func_level++;
106.113 - }
106.114 - cur = new ScopeInfo(name, node, level++, kind, func_level, ac);
106.115 - nodeScopes.put(node, cur);
106.116 - }
106.117 -
106.118 - public void endScope() throws Exception {
106.119 - if (cur.kind == FUNCSCOPE) {
106.120 - func_level--;
106.121 - }
106.122 - level--;
106.123 - ScopeInfo up = null;
106.124 - if (!scopes.empty()) {
106.125 - up = (ScopeInfo)scopes.pop();
106.126 - }
106.127 - //Go into the stack to find a non class containing scope to use making the closure
106.128 - //See PEP 227
106.129 - int dist = 1;
106.130 - ScopeInfo referenceable = up;
106.131 - for (int i = scopes.size() - 1; i >= 0 && referenceable.kind == CLASSSCOPE; i--, dist++) {
106.132 - referenceable = ((ScopeInfo)scopes.get(i));
106.133 - }
106.134 - cur.cook(referenceable, dist, symbolTable);
106.135 -// cur.dump(); // debug
106.136 - cur = up;
106.137 - }
106.138 -
106.139 - public void parse() {
106.140 - try {
106.141 - visit(root);
106.142 - } catch (Throwable t) {
106.143 - Exceptions.printStackTrace(t);
106.144 - //throw org.python.core.ParserFacade.fixParseError(null, t,
106.145 - // code_compiler.getFilename());
106.146 - }
106.147 - }
106.148 -
106.149 - @Override
106.150 - public Object visitInteractive(Interactive node) throws Exception {
106.151 - beginScope("<single-top>", TOPSCOPE, node, null);
106.152 - PythonTree oldParent = parent;
106.153 - parent = node;
106.154 - suite(node.getInternalBody());
106.155 - parent = oldParent;
106.156 - endScope();
106.157 - return null;
106.158 - }
106.159 -
106.160 - @Override
106.161 - public Object visitModule(org.python.antlr.ast.Module node)
106.162 - throws Exception {
106.163 - List<stmt> body = node.getInternalBody();
106.164 - if (body != null && body.size() > 0) {
106.165 - boolean foundFirst = false;
106.166 - for (stmt stmt : body) {
106.167 - if (stmt != null) {
106.168 - if (stmt instanceof Import || stmt instanceof ImportFrom) {
106.169 - if (!foundFirst) {
106.170 - foundFirst = true;
106.171 - }
106.172 - mainImports.add(stmt);
106.173 - } else if (foundFirst) {
106.174 - break;
106.175 - }
106.176 - }
106.177 - }
106.178 - }
106.179 -
106.180 - beginScope("<file-top>", TOPSCOPE, node, null);
106.181 -
106.182 - PythonTree oldParent = parent;
106.183 - parent = node;
106.184 - suite(node.getInternalBody());
106.185 - parent = oldParent;
106.186 -
106.187 - endScope();
106.188 - return null;
106.189 - }
106.190 -
106.191 - @Override
106.192 - public Object visitExpression(Expression node) throws Exception {
106.193 - beginScope("<eval-top>", TOPSCOPE, node, null);
106.194 - visit(new Return(node, node.getInternalBody()));
106.195 - endScope();
106.196 - return null;
106.197 - }
106.198 -
106.199 - private void def(String name, int extraFlags, PythonTree node) {
106.200 - SymInfo info = cur.addBound(name, node);
106.201 - // <netbeans>
106.202 - info.flags |= (DEF | extraFlags);
106.203 - info.node = node;
106.204 - // </netbeans>
106.205 - }
106.206 -
106.207 - @Override
106.208 - public Object visitAssign(Assign node) throws Exception {
106.209 - List<expr> targets = node.getInternalTargets();
106.210 - if (targets != null && targets.size() == 1 && targets.get(0) instanceof Name) {
106.211 - Name lhs = (Name)targets.get(0);
106.212 - if ("__all__".equals(lhs.getInternalId())) { // NOI18N
106.213 - expr nodeValue = node.getInternalValue();
106.214 - if (!invalidPublicSymbols && nodeValue instanceof org.python.antlr.ast.List) {
106.215 - org.python.antlr.ast.List allList = (org.python.antlr.ast.List)nodeValue;
106.216 - if (allList != null) {
106.217 - for (expr expr : allList.getInternalElts()) {
106.218 - if (expr instanceof Str) {
106.219 - Str str = (Str)expr;
106.220 - if (publicSymbols == null) {
106.221 - publicSymbols = new ArrayList<>();
106.222 - }
106.223 - publicSymbols.add(str);
106.224 - } else {
106.225 - invalidPublicSymbols = true;
106.226 - }
106.227 - }
106.228 - }
106.229 - } else {
106.230 - invalidPublicSymbols = true;
106.231 - }
106.232 - }
106.233 - }
106.234 -
106.235 - if (targets.size() > 0) {
106.236 - List<Name> names = new ArrayList<>(targets.size());
106.237 - boolean valid = true;
106.238 - for (expr et : targets) {
106.239 - if (et instanceof Name) {
106.240 - Name name = (Name)et;
106.241 - names.add(name);
106.242 - } else {
106.243 - valid = false;
106.244 - }
106.245 - }
106.246 - if (valid) {
106.247 - expr nodeValue = node.getInternalValue();
106.248 - if (nodeValue instanceof Name) {
106.249 - Name value = (Name)nodeValue;
106.250 -
106.251 - SymInfo rhsSym = cur.tbl.get(value.getInternalId());
106.252 - if (rhsSym != null && rhsSym.isDef()) {
106.253 - for (Name name : names) {
106.254 - visitName(name);
106.255 - SymInfo sym = cur.tbl.get(name.getInternalId());
106.256 - if (sym != null) {
106.257 - sym.flags |= ALIAS;
106.258 - sym.flags |= (rhsSym.flags & (CLASS | FUNCTION));
106.259 - sym.node = rhsSym.node;
106.260 - }
106.261 - }
106.262 - }
106.263 - }
106.264 - }
106.265 - }
106.266 -
106.267 - return super.visitAssign(node);
106.268 - }
106.269 -
106.270 - @Override
106.271 - public Object visitFunctionDef(FunctionDef node) throws Exception {
106.272 - def(node.getInternalName(), FUNCTION, node);
106.273 - ArgListCompiler ac = new ArgListCompiler(symbolTable);
106.274 - ac.visitArgs(node.getInternalArgs());
106.275 -
106.276 - List<expr> defaults = ac.getDefaults();
106.277 - for (int i = 0; i < defaults.size(); i++) {
106.278 - visit(defaults.get(i));
106.279 - }
106.280 -
106.281 - List<expr> decs = node.getInternalDecorator_list();
106.282 - for (int i = decs.size() - 1; i >= 0; i--) {
106.283 - visit(decs.get(i));
106.284 - }
106.285 -
106.286 - ScopeInfo parentScope = cur;
106.287 - beginScope(node.getInternalName(), FUNCSCOPE, node, ac);
106.288 - cur.nested = parentScope;
106.289 -
106.290 - int n = ac.names.size();
106.291 - for (int i = 0; i < n; i++) {
106.292 - cur.addParam(ac.names.get(i), ac.nodes.get(i));
106.293 - }
106.294 - for (int i = 0; i < ac.init_code.size(); i++) {
106.295 - visit(ac.init_code.get(i));
106.296 - }
106.297 - cur.markFromParam();
106.298 -
106.299 - PythonTree oldParent = parent;
106.300 - parent = node;
106.301 - suite(node.getInternalBody());
106.302 - parent = oldParent;
106.303 -
106.304 - endScope();
106.305 - return null;
106.306 - }
106.307 -
106.308 - @Override
106.309 - public Object visitLambda(Lambda node) throws Exception {
106.310 - ArgListCompiler ac = new ArgListCompiler(symbolTable);
106.311 - ac.visitArgs(node.getInternalArgs());
106.312 -
106.313 - List<expr> defaults = ac.getDefaults();
106.314 - for (expr expr : defaults) {
106.315 - visit(expr);
106.316 - }
106.317 -
106.318 - beginScope("<lambda>", FUNCSCOPE, node, ac);
106.319 - assert ac.names.size() == ac.nodes.size();
106.320 - for (int i = 0; i < ac.names.size(); i++) {
106.321 - cur.addParam(ac.names.get(i), ac.nodes.get(i));
106.322 - }
106.323 - for (Object o : ac.init_code) {
106.324 - visit((stmt)o);
106.325 - }
106.326 - cur.markFromParam();
106.327 - visit(node.getInternalBody());
106.328 - endScope();
106.329 - return null;
106.330 - }
106.331 -
106.332 - public void suite(List<stmt> stmts) throws Exception {
106.333 - if (stmts != null) {
106.334 - for (int i = 0; i < stmts.size(); i++) {
106.335 - stmt s = stmts.get(i);
106.336 - path.descend(s);
106.337 - visit(s);
106.338 - path.ascend();
106.339 - }
106.340 - }
106.341 - }
106.342 -
106.343 - @Override
106.344 - public Object visitImport(Import node) throws Exception {
106.345 - if (parent == root) {
106.346 - topLevelImports.add(node);
106.347 - }
106.348 - imports.add(node);
106.349 -
106.350 - List<alias> names = node.getInternalNames();
106.351 - if (names != null) {
106.352 - for (alias alias : names) {
106.353 - String asname = alias.getInternalAsname();
106.354 - if (asname != null) {
106.355 - SymInfo entry = cur.addBound(asname, node);
106.356 - entry.flags |= IMPORTED;
106.357 - } else {
106.358 - String name = alias.getInternalName();
106.359 - if (name.indexOf('.') > 0) {
106.360 - name = name.substring(0, name.indexOf('.'));
106.361 - }
106.362 - SymInfo entry = cur.addBound(name, node);
106.363 - entry.flags |= IMPORTED;
106.364 - }
106.365 - }
106.366 - }
106.367 - return null;
106.368 - }
106.369 -
106.370 - @Override
106.371 - public Object visitImportFrom(ImportFrom node) throws Exception {
106.372 - if (parent == root) {
106.373 - topLevelImports.add(node);
106.374 - }
106.375 - importsFrom.add(node);
106.376 -
106.377 - //Future.checkFromFuture(node); // future stmt support
106.378 - List<alias> names = node.getInternalNames();
106.379 - if (names == null || names.size() == 0) {
106.380 - cur.from_import_star = true;
106.381 - return null;
106.382 - }
106.383 - for (alias alias : names) {
106.384 - String asname = alias.getInternalAsname();
106.385 - if (asname != null) {
106.386 - SymInfo entry = cur.addBound(asname, node);
106.387 - entry.flags |= IMPORTED;
106.388 - } else {
106.389 - SymInfo entry = cur.addBound(alias.getInternalName(), node);
106.390 - entry.flags |= IMPORTED;
106.391 - }
106.392 - }
106.393 - return null;
106.394 - }
106.395 -
106.396 - @Override
106.397 - public Object visitGlobal(Global node) throws Exception {
106.398 - List<String> names = node.getInternalNames();
106.399 - for (String name : names) {
106.400 - int prev = cur.addGlobal(name, node);
106.401 - if (prev >= 0) {
106.402 - if ((prev & FROM_PARAM) != 0) {
106.403 - symbolTable.error("name '" + name + "' is local and global", true, node);
106.404 - }
106.405 - if ((prev & GLOBAL) != 0) {
106.406 - continue;
106.407 - }
106.408 - String what;
106.409 - if ((prev & BOUND) != 0) {
106.410 - what = "assignment";
106.411 - } else {
106.412 - what = "use";
106.413 - }
106.414 - symbolTable.error("name '" + name + "' declared global after " + what, false, node);
106.415 - }
106.416 - }
106.417 - return null;
106.418 - }
106.419 -
106.420 - @Override
106.421 - public Object visitExec(Exec node) throws Exception {
106.422 - cur.exec = true;
106.423 - if (node.getInternalGlobals() == null && node.getInternalLocals() == null) {
106.424 - cur.unqual_exec = true;
106.425 - }
106.426 - traverse(node);
106.427 - return null;
106.428 - }
106.429 -
106.430 - @Override
106.431 - public Object visitClassDef(ClassDef node) throws Exception {
106.432 - String name = node.getInternalName();
106.433 - def(name, CLASS, node);
106.434 - List<expr> bases = node.getInternalBases();
106.435 - if (bases != null) {
106.436 - for (expr expr : bases) {
106.437 - visit(expr);
106.438 - }
106.439 - }
106.440 - ScopeInfo parentScope = cur;
106.441 - beginScope(name, CLASSSCOPE, node, null);
106.442 - cur.nested = parentScope;
106.443 - PythonTree oldParent = parent;
106.444 - parent = node;
106.445 - suite(node.getInternalBody());
106.446 - parent = oldParent;
106.447 - endScope();
106.448 - return null;
106.449 - }
106.450 -
106.451 - @Override
106.452 - public Object visitName(Name node) throws Exception {
106.453 - // Jython's parser doesn't always initialize the parent references correctly;
106.454 - // try to correct that here.
106.455 - node.setParent(parent);
106.456 -
106.457 - String name = node.getInternalId();
106.458 - if (node.getInternalCtx() != expr_contextType.Load) {
106.459 - if (name.equals("__debug__")) {
106.460 - symbolTable.error("can not assign to __debug__", true, node);
106.461 - }
106.462 - cur.addBound(name, node);
106.463 - } else {
106.464 - cur.addUsed(name, node);
106.465 - }
106.466 - return null;
106.467 - }
106.468 -
106.469 - // <netbeans>
106.470 - @Override
106.471 - public Object visitCall(Call node) throws Exception {
106.472 - Object ret = super.visitCall(node);
106.473 -
106.474 - expr func = node.getInternalFunc();
106.475 - if (func instanceof Name) {
106.476 - Name name = (Name)func;
106.477 - cur.markCall(name.getInternalId());
106.478 - } else if (func instanceof Attribute) {
106.479 - Attribute attr = (Attribute)func;
106.480 - if (cur.attributes != null) {
106.481 - SymInfo funcSymbol = cur.attributes.get(attr.getInternalAttr());
106.482 - if (funcSymbol != null) {
106.483 - funcSymbol.flags |= FUNCTION | CALLED; // mark as func/method call
106.484 - }
106.485 - }
106.486 -
106.487 - }
106.488 -
106.489 - return ret;
106.490 - }
106.491 -
106.492 - @Override
106.493 - public Object visitDelete(Delete node) throws Exception {
106.494 - for (expr et : node.getInternalTargets()) {
106.495 - if (et instanceof Name) {
106.496 - String name = ((Name)et).getInternalId();
106.497 - cur.addUsed(name, node);
106.498 - }
106.499 - }
106.500 -
106.501 - return super.visitDelete(node);
106.502 - }
106.503 -
106.504 - @Override
106.505 - public Object visitAttribute(Attribute node) throws Exception {
106.506 - if (parent instanceof Call && node.getInternalValue() instanceof Name &&
106.507 - ("__all__".equals(((Name)node.getInternalValue()).getInternalId()))) {
106.508 - // If you for example call
106.509 - // __all__.extend("foo")
106.510 - // or
106.511 - // __all__.append("bar")
106.512 - // then I don't want to try to analyze __all__
106.513 - String nodeAttr = node.getInternalAttr();
106.514 - if ("extend".equals(nodeAttr) || "append".equals(nodeAttr)) { // NOI18N
106.515 - Call call = (Call)parent;
106.516 - List<expr> callArgs = call.getInternalArgs();
106.517 - if (callArgs != null) {
106.518 - for (expr expr : callArgs) {
106.519 - if (expr instanceof Str) {
106.520 - if (publicSymbols == null) {
106.521 - publicSymbols = new ArrayList<>();
106.522 - }
106.523 - publicSymbols.add((Str)expr);
106.524 - } else if (expr instanceof org.python.antlr.ast.List) {
106.525 - org.python.antlr.ast.List list = (org.python.antlr.ast.List)expr;
106.526 - if (list != null) {
106.527 - List<expr> elts = list.getInternalElts();
106.528 - if (elts != null) {
106.529 - for (expr ex : elts) {
106.530 - if (ex instanceof Str) {
106.531 - Str str = (Str)ex;
106.532 - if (publicSymbols == null) {
106.533 - publicSymbols = new ArrayList<>();
106.534 - }
106.535 - publicSymbols.add(str);
106.536 - } else {
106.537 - invalidPublicSymbols = true;
106.538 - }
106.539 - }
106.540 - }
106.541 - }
106.542 - } else {
106.543 - invalidPublicSymbols = true;
106.544 - break;
106.545 - }
106.546 - }
106.547 - }
106.548 - } else {
106.549 - invalidPublicSymbols = true;
106.550 - }
106.551 - } else {
106.552 - String nodeAttr = node.getInternalAttr();
106.553 - if (nodeAttr != null) {
106.554 - cur.addAttribute(path, nodeAttr, node);
106.555 - }
106.556 - }
106.557 - return super.visitAttribute(node);
106.558 - }
106.559 - // </netbeans>
106.560 -
106.561 - @Override
106.562 - public Object visitListComp(ListComp node) throws Exception {
106.563 - String tmp = "_[" + node.getLine() + "_" + node.getCharPositionInLine() + "]";
106.564 - cur.addBound(tmp, node);
106.565 - traverse(node);
106.566 - return null;
106.567 - }
106.568 -
106.569 - @Override
106.570 - public Object visitYield(Yield node) throws Exception {
106.571 - cur.defineAsGenerator(node);
106.572 - cur.yield_count++;
106.573 - traverse(node);
106.574 - return null;
106.575 - }
106.576 -
106.577 - @Override
106.578 - public Object visitReturn(Return node) throws Exception {
106.579 - if (node.getInternalValue() != null) {
106.580 - cur.noteReturnValue(node);
106.581 - }
106.582 - traverse(node);
106.583 - return null;
106.584 - }
106.585 -
106.586 - @Override
106.587 - public Object visitGeneratorExp(GeneratorExp node) throws Exception {
106.588 - // The first iterator is evaluated in the outer scope
106.589 - if (node.getInternalGenerators() != null && node.getInternalGenerators().size() > 0) {
106.590 - visit(node.getInternalGenerators().get(0).getInternalIter());
106.591 - }
106.592 - String bound_exp = "_(x)";
106.593 - String tmp = "_(" + node.getLine() + "_" + node.getCharPositionInLine() + ")";
106.594 - def(tmp, GENERATOR, node);
106.595 - ArgListCompiler ac = new ArgListCompiler(symbolTable);
106.596 - List<expr> args = new ArrayList<>();
106.597 - Name argsName = new Name(node.getToken(), bound_exp, expr_contextType.Param);
106.598 - args.add(argsName);
106.599 - ac.visitArgs(new arguments(node, args, null, null, new ArrayList<expr>()));
106.600 - beginScope(tmp, FUNCSCOPE, node, ac);
106.601 - cur.addParam(bound_exp, argsName);
106.602 - cur.markFromParam();
106.603 -
106.604 - cur.defineAsGenerator(node);
106.605 - cur.yield_count++;
106.606 - // The reset of the iterators are evaluated in the inner scope
106.607 - if (node.getInternalElt() != null) {
106.608 - visit(node.getInternalElt());
106.609 - }
106.610 - if (node.getInternalGenerators() != null) {
106.611 - for (int i = 0; i < node.getInternalGenerators().size(); i++) {
106.612 - if (node.getInternalGenerators().get(i) != null) {
106.613 - if (i == 0) {
106.614 - visit(node.getInternalGenerators().get(i).getInternalTarget());
106.615 - if (node.getInternalGenerators().get(i).getInternalIfs() != null) {
106.616 - for (expr cond : node.getInternalGenerators().get(i).getInternalIfs()) {
106.617 - if (cond != null) {
106.618 - visit(cond);
106.619 - }
106.620 - }
106.621 - }
106.622 - } else {
106.623 - visit(node.getInternalGenerators().get(i));
106.624 - }
106.625 - }
106.626 - }
106.627 - }
106.628 -
106.629 - endScope();
106.630 - return null;
106.631 - }
106.632 -
106.633 - @Override
106.634 - public Object visitWith(With node) throws Exception {
106.635 - cur.max_with_count++;
106.636 - traverse(node);
106.637 -
106.638 - return null;
106.639 - }
106.640 -
106.641 - public List<Str> getPublicSymbols() {
106.642 - return invalidPublicSymbols ? null : publicSymbols;
106.643 - }
106.644 -}
107.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/SymInfo.java Fri Sep 18 16:20:24 2015 -0500
107.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
107.3 @@ -1,209 +0,0 @@
107.4 -package org.netbeans.modules.python.editor.scopes;
107.5 -
107.6 -import org.python.antlr.PythonTree;
107.7 -import static org.netbeans.modules.python.editor.scopes.ScopeConstants.*;
107.8 -
107.9 -public class SymInfo extends Object {
107.10 - public SymInfo(int flags) {
107.11 - this.flags = flags;
107.12 - }
107.13 -
107.14 - public SymInfo(int flags, int locals_index) {
107.15 - this.flags = flags;
107.16 - this.locals_index = locals_index;
107.17 - }
107.18 - public int flags;
107.19 - public int locals_index;
107.20 - public int env_index;
107.21 - public PythonTree node;
107.22 -
107.23 - @Override
107.24 - public String toString() {
107.25 - return "SymInfo[" + flags + " " + locals_index + " " +
107.26 - env_index + "]" + dumpFlags(null);
107.27 - }
107.28 -
107.29 - public String dumpFlags(ScopeInfo info) {
107.30 - StringBuilder sb = new StringBuilder();
107.31 - if ((flags & BOUND) != 0) {
107.32 - sb.append("[bound]");
107.33 - }
107.34 - // func scope global (affect nested scopes)
107.35 - // vs. class scope global
107.36 - if ((flags & NGLOBAL) != 0) {
107.37 - sb.append("[func-global]");
107.38 - } else if ((flags & CLASS_GLOBAL) != 0) {
107.39 - sb.append("[class-global]");
107.40 - }
107.41 - if ((flags & PARAM) != 0) {
107.42 - sb.append("[param]");
107.43 - } else if ((flags & FROM_PARAM) != 0) {
107.44 - sb.append("[from-param]");
107.45 - }
107.46 - if ((flags & CELL) != 0) {
107.47 - sb.append("[cell]");
107.48 - }
107.49 - if ((flags & FREE) != 0) {
107.50 - sb.append("[free]");
107.51 - }
107.52 - if (isImported()) {
107.53 - sb.append("[imported]");
107.54 - }
107.55 - if (isPrivate()) {
107.56 - sb.append("[private]");
107.57 - }
107.58 - if (isClass()) {
107.59 - sb.append("[class]");
107.60 - }
107.61 - if (isFunction()) {
107.62 - sb.append("[function]");
107.63 - }
107.64 - if (isData()) {
107.65 - sb.append("[data]");
107.66 - }
107.67 - if (isMember()) {
107.68 - sb.append("[member]");
107.69 - }
107.70 - if (isDef()) {
107.71 - sb.append("[def]");
107.72 - }
107.73 - if (isRead()) {
107.74 - sb.append("[read]");
107.75 - }
107.76 - if (isAlias()) {
107.77 - sb.append("[alias]");
107.78 - }
107.79 - if (isGeneratorExp()) {
107.80 - sb.append("[generator]");
107.81 - }
107.82 - if (isCalled()) {
107.83 - sb.append("[called]");
107.84 - }
107.85 - if (isProtected()) {
107.86 - sb.append("[protected]");
107.87 - }
107.88 - if (isBoundInConstructor()) {
107.89 - sb.append("[bound-in-constructor]");
107.90 - }
107.91 - if (isUnused(info)) {
107.92 - sb.append("[unused]");
107.93 - }
107.94 - if (isUnresolved()) {
107.95 - sb.append("[UNRESOLVED]");
107.96 - }
107.97 - sb.append("[node=");
107.98 - if (node != null) {
107.99 - sb.append(node.getClass().getSimpleName());
107.100 - } else {
107.101 - sb.append("null");
107.102 - }
107.103 - sb.append("]");
107.104 -
107.105 - return sb.toString();
107.106 - }
107.107 -
107.108 - public boolean isUnused(ScopeInfo info) {
107.109 - // Cannot correctly detect usage of variables in CLASSSCOPE
107.110 - return (info == null || info.kind == FUNCSCOPE || info.kind == TOPSCOPE) &&
107.111 - (flags & (READ | BOUND | DEF)) == BOUND;
107.112 - }
107.113 -
107.114 - public boolean isParameter() {
107.115 - return (flags & (PARAM | FROM_PARAM)) != 0;
107.116 - }
107.117 -
107.118 - public boolean isUnresolved() {
107.119 - return (flags & (BOUND | FREE)) == 0;
107.120 - }
107.121 -
107.122 - public boolean isImported() {
107.123 - return (flags & IMPORTED) != 0;
107.124 - }
107.125 -
107.126 - public boolean isData() {
107.127 - return (flags & (BOUND | DEF | CLASS | FUNCTION)) == (BOUND);
107.128 - }
107.129 -
107.130 - public boolean isClass() {
107.131 - return (flags & CLASS) != 0;
107.132 - }
107.133 -
107.134 - public boolean isDef() {
107.135 - return (flags & DEF) != 0;
107.136 - }
107.137 -
107.138 - public boolean isFunction() {
107.139 - return (flags & FUNCTION) != 0;
107.140 - }
107.141 -
107.142 - public boolean isBound() {
107.143 - return (flags & BOUND) != 0;
107.144 - }
107.145 -
107.146 - public boolean isMember() {
107.147 - return (flags & MEMBER) != 0;
107.148 - }
107.149 -
107.150 - public boolean isCalled() {
107.151 - return (flags & CALLED) != 0;
107.152 - }
107.153 -
107.154 - public boolean isRead() {
107.155 - return (flags & READ) != 0;
107.156 - }
107.157 -
107.158 - public boolean isGeneratorExp() {
107.159 - return (flags & GENERATOR) != 0;
107.160 - }
107.161 -
107.162 - public boolean isFree() {
107.163 - return (flags & FREE) != 0;
107.164 - }
107.165 -
107.166 - public boolean isPrivate() {
107.167 - return (flags & PRIVATE) != 0;
107.168 - }
107.169 -
107.170 - public boolean isProtected() {
107.171 - return (flags & PROTECTED) != 0;
107.172 - }
107.173 -
107.174 - public boolean isBoundInConstructor() {
107.175 - return (flags & BOUND_IN_CONSTRUCTOR) != 0;
107.176 - }
107.177 -
107.178 - public boolean isAlias() {
107.179 - return (flags & ALIAS) != 0;
107.180 - }
107.181 -
107.182 - public boolean isVariable(boolean mustBeBound) {
107.183 - int mask = mustBeBound ? BOUND : 0;
107.184 - return (flags & (BOUND | CALLED | DEF | IMPORTED | CLASS | FUNCTION | MEMBER | GENERATOR)) == mask;
107.185 - }
107.186 -
107.187 - public static boolean isPrivateName(String name) {
107.188 - // Private variables: start with __ but doesn't end with __
107.189 - // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
107.190 - if (name.startsWith("__") && !name.endsWith("__")) { // NOI18N
107.191 - return true;
107.192 - } else if (name != null && name.startsWith("_") && !name.endsWith("_")) { // NOI18N
107.193 - // From PEP8: Single_leading_underscore: weak "internal use" indicator
107.194 - // (e.g. "from M import *" does not import objects whose name
107.195 - // starts with an underscore).
107.196 - return true;
107.197 - }
107.198 -
107.199 - return false;
107.200 - }
107.201 -
107.202 - public static boolean isProtectedName(String name) {
107.203 - // Protected variable starts with a single _
107.204 - // this is a convention only
107.205 - if (!name.startsWith("__")) { // NOI18N
107.206 - if (name.startsWith("_")) { // NOI18N
107.207 - return true;
107.208 - }
107.209 - }
107.210 - return false;
107.211 - }
107.212 -}
108.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/SymbolTable.java Fri Sep 18 16:20:24 2015 -0500
108.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
108.3 @@ -1,1249 +0,0 @@
108.4 -/*
108.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
108.6 - *
108.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
108.8 - *
108.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
108.10 - * Other names may be trademarks of their respective owners.
108.11 - *
108.12 - * The contents of this file are subject to the terms of either the GNU
108.13 - * General Public License Version 2 only ("GPL") or the Common
108.14 - * Development and Distribution License("CDDL") (collectively, the
108.15 - * "License"). You may not use this file except in compliance with the
108.16 - * License. You can obtain a copy of the License at
108.17 - * http://www.netbeans.org/cddl-gplv2.html
108.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
108.19 - * specific language governing permissions and limitations under the
108.20 - * License. When distributing the software, include this License Header
108.21 - * Notice in each file and include the License file at
108.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
108.23 - * particular file as subject to the "Classpath" exception as provided
108.24 - * by Oracle in the GPL Version 2 section of the License file that
108.25 - * accompanied this code. If applicable, add the following below the
108.26 - * License Header, with the fields enclosed by brackets [] replaced by
108.27 - * your own identifying information:
108.28 - * "Portions Copyrighted [year] [name of copyright owner]"
108.29 - *
108.30 - * If you wish your version of this file to be governed by only the CDDL
108.31 - * or only the GPL Version 2, indicate your decision by adding
108.32 - * "[Contributor] elects to include this software in this distribution
108.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
108.34 - * single choice of license, a recipient has the option to distribute
108.35 - * your version of this file under either the CDDL, the GPL Version 2 or
108.36 - * to extend the choice of license to its licensees as provided above.
108.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
108.38 - * Version 2 license, then the option applies only if the new code is
108.39 - * made subject to such option by the copyright holder.
108.40 - *
108.41 - * Contributor(s):
108.42 - *
108.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
108.44 - */
108.45 -package org.netbeans.modules.python.editor.scopes;
108.46 -
108.47 -import java.util.ArrayList;
108.48 -import java.util.Collections;
108.49 -import java.util.HashMap;
108.50 -import java.util.HashSet;
108.51 -import java.util.List;
108.52 -import java.util.Map;
108.53 -import java.util.Set;
108.54 -import org.netbeans.modules.csl.api.ElementKind;
108.55 -import org.netbeans.modules.csl.api.OffsetRange;
108.56 -import org.netbeans.modules.csl.api.Severity;
108.57 -import org.netbeans.modules.csl.api.Error;
108.58 -import org.netbeans.modules.csl.spi.DefaultError;
108.59 -import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
108.60 -import org.netbeans.modules.python.editor.PythonAstUtils;
108.61 -import org.netbeans.modules.python.editor.PythonIndex;
108.62 -import org.netbeans.modules.python.editor.PythonIndexer;
108.63 -import org.netbeans.modules.python.editor.PythonParserResult;
108.64 -import org.netbeans.modules.python.editor.PythonUtils;
108.65 -import org.netbeans.modules.python.editor.elements.AstElement;
108.66 -import org.netbeans.modules.python.editor.elements.Element;
108.67 -import org.netbeans.modules.python.editor.elements.IndexedElement;
108.68 -import org.netbeans.modules.python.editor.imports.ImportEntry;
108.69 -import org.netbeans.modules.python.editor.imports.ImportManager;
108.70 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
108.71 -import org.openide.filesystems.FileObject;
108.72 -import org.openide.filesystems.FileStateInvalidException;
108.73 -import org.openide.filesystems.FileUtil;
108.74 -import org.openide.util.Exceptions;
108.75 -import org.python.antlr.PythonTree;
108.76 -import org.python.antlr.Visitor;
108.77 -import org.python.antlr.ast.Attribute;
108.78 -import org.python.antlr.ast.ClassDef;
108.79 -import org.python.antlr.ast.Expression;
108.80 -import org.python.antlr.ast.FunctionDef;
108.81 -import org.python.antlr.ast.GeneratorExp;
108.82 -import org.python.antlr.ast.Import;
108.83 -import org.python.antlr.ast.ImportFrom;
108.84 -import org.python.antlr.ast.Interactive;
108.85 -import org.python.antlr.ast.Lambda;
108.86 -import org.python.antlr.ast.Name;
108.87 -import org.python.antlr.ast.Str;
108.88 -import org.python.antlr.ast.alias;
108.89 -import org.python.antlr.base.expr;
108.90 -import static org.netbeans.modules.python.editor.scopes.ScopeConstants.*;
108.91 -
108.92 -/**
108.93 - * A symbol table tracks a bunch of scopes and can answer questions about defined
108.94 - * symbols.
108.95 - *
108.96 - * Based on Jython's ScopeManager.
108.97 - *
108.98 - * @author Tor Norbye
108.99 - */
108.100 -public class SymbolTable {
108.101 - private final static int YES = 1;
108.102 - private final static int NO = 0;
108.103 - private final static int CIRCULAR = -1;
108.104 - private Map<PythonTree, ScopeInfo> scopes = new HashMap<>();
108.105 - private PythonTree root;
108.106 - private FileObject fileObject;
108.107 - private List<Import> imports = new ArrayList<>();
108.108 - private List<ImportFrom> importsFrom = new ArrayList<>();
108.109 - private List<PythonTree> mainImports = new ArrayList<>();
108.110 - private Set<PythonTree> topLevelImports = new HashSet<>();
108.111 - private List<Error> errors;
108.112 - /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
108.113 - private List<Str> publicSymbols;
108.114 - private final static HashMap<String, String> classAttributes = new HashMap<String, String>() {
108.115 - {
108.116 - put("__class__", "__class__");
108.117 - put("__bases__", "__bases__");
108.118 - put("__dict__", "__dict__");
108.119 - put("__doc__", "__doc__");
108.120 - put("__name__", "__bases");
108.121 - }
108.122 - };
108.123 - private HashMap<String, ClassDef> classes = new HashMap<>();
108.124 - // TODO - use WeakHashMap?
108.125 - static Map<String, Set<IndexedElement>> importedElements = new HashMap<>();
108.126 -
108.127 - private HashMap<String, ClassDef> buildLocalClasses() {
108.128 - HashMap<String, ClassDef> localClasses = new HashMap<>();
108.129 - for (PythonTree cur : scopes.keySet()) {
108.130 - if (cur instanceof ClassDef) {
108.131 - ClassDef curClass = (ClassDef)cur;
108.132 - localClasses.put(curClass.getInternalName(), curClass);
108.133 - }
108.134 - }
108.135 - return localClasses;
108.136 - }
108.137 -
108.138 - public SymbolTable(PythonTree root, FileObject fileObject) {
108.139 - this.root = root;
108.140 - this.fileObject = fileObject;
108.141 -
108.142 - if (root != null) {
108.143 - try {
108.144 - ScopesCompiler compiler = new ScopesCompiler(this, scopes, root, imports, importsFrom, mainImports, topLevelImports);
108.145 - compiler.parse();
108.146 - publicSymbols = compiler.getPublicSymbols();
108.147 - classes = buildLocalClasses();
108.148 - if (publicSymbols != null) {
108.149 - // Mark all other symbols private!
108.150 - Set<String> names = new HashSet<>(publicSymbols.size() + 1);
108.151 - names.add("__all__"); // __all__ itself is exported!
108.152 - for (Str str : publicSymbols) {
108.153 - String name = PythonAstUtils.getStrContent(str);
108.154 - if (name != null) {
108.155 - names.add(name);
108.156 - }
108.157 - }
108.158 -
108.159 - ScopeInfo topScope = scopes.get(root);
108.160 - if (topScope != null) {
108.161 - for (Map.Entry<String, SymInfo> entry : topScope.tbl.entrySet()) {
108.162 - String name = entry.getKey();
108.163 - if (!names.contains(name)) {
108.164 - SymInfo sym = entry.getValue();
108.165 - sym.flags |= PRIVATE;
108.166 - if (sym.isDef() && sym.node != null) {
108.167 - ScopeInfo scope = scopes.get(sym.node);
108.168 - scope.hidden = true;
108.169 - }
108.170 - }
108.171 - }
108.172 - }
108.173 -
108.174 - for (Map.Entry<PythonTree, ScopeInfo> entry : scopes.entrySet()) {
108.175 - ScopeInfo scope = entry.getValue();
108.176 - boolean isHidden = false;
108.177 - ScopeInfo curr = scope;
108.178 - while (curr != null) {
108.179 - if (curr.hidden) {
108.180 - isHidden = true;
108.181 - break;
108.182 - }
108.183 - if (curr.nested != null) {
108.184 - curr = curr.nested;
108.185 - } else {
108.186 - curr = curr.up;
108.187 - }
108.188 -
108.189 - }
108.190 - if (isHidden) {
108.191 - scope.hidden = true;
108.192 - }
108.193 - }
108.194 -
108.195 - // Mark all symbols private, unless the scope is a direct descendant
108.196 - // of a public symbol
108.197 - for (ScopeInfo scope : scopes.values()) {
108.198 - if (scope.hidden) {
108.199 - for (SymInfo sym : scope.tbl.values()) {
108.200 - sym.flags |= PRIVATE;
108.201 - }
108.202 - }
108.203 - }
108.204 - }
108.205 - } catch (Exception ex) {
108.206 - Exceptions.printStackTrace(ex);
108.207 - }
108.208 - }
108.209 - }
108.210 -
108.211 - public boolean isPrivate(PythonTree node, String name) {
108.212 - ScopeInfo scope = scopes.get(node);
108.213 - if (scope == null) {
108.214 - scope = scopes.get(root);
108.215 - }
108.216 - if (scope != null) {
108.217 - if (scope.up != null) {
108.218 - if (scope.hidden) {
108.219 - return true;
108.220 - }
108.221 - // Look in parent's scope table
108.222 - if (scope.nested != null) {
108.223 - scope = scope.nested;
108.224 - } else {
108.225 - scope = scope.up;
108.226 - }
108.227 - if (scope != null) {
108.228 - SymInfo sym = scope.tbl.get(name);
108.229 - if (sym != null) {
108.230 - return sym.isPrivate();
108.231 - }
108.232 - }
108.233 - } else {
108.234 - SymInfo sym = scope.tbl.get(name);
108.235 - if (sym != null) {
108.236 - return sym.isPrivate();
108.237 - }
108.238 - }
108.239 - }
108.240 -
108.241 - return false;
108.242 - }
108.243 -
108.244 - public SymInfo findDeclaration(PythonTree scope, String name, boolean allowFree) {
108.245 - ScopeInfo scopeInfo = getScopeInfo(scope);
108.246 - if (scopeInfo != null) {
108.247 - SymInfo sym = scopeInfo.tbl.get(name);
108.248 - SymInfo orig = sym;
108.249 - while (sym != null && sym.isFree()) {
108.250 - scopeInfo = scopeInfo.up;
108.251 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
108.252 - scopeInfo = scopeInfo.up;
108.253 - }
108.254 - sym = scopeInfo.tbl.get(name);
108.255 - }
108.256 -
108.257 - if (allowFree && sym == null && orig != null) {
108.258 - // Free variable -- might have to resolve it
108.259 - return orig;
108.260 - }
108.261 -
108.262 - // Look for attributes too
108.263 - if (sym == null) {
108.264 - sym = scopeInfo.attributes.get(name);
108.265 - orig = sym;
108.266 - while (sym != null && sym.isFree()) {
108.267 - scopeInfo = scopeInfo.up;
108.268 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
108.269 - scopeInfo = scopeInfo.up;
108.270 - }
108.271 - sym = scopeInfo.tbl.get(name);
108.272 - }
108.273 -
108.274 - if (allowFree && sym == null && orig != null) {
108.275 - // Free variable -- might have to resolve it
108.276 - return orig;
108.277 - }
108.278 - }
108.279 -
108.280 - return sym;
108.281 - }
108.282 -
108.283 - return null;
108.284 - }
108.285 -
108.286 - public ScopeInfo getScopeInfo(PythonTree node) {
108.287 - return scopes.get(node);
108.288 - }
108.289 -
108.290 - public List<Error> getErrors() {
108.291 - return errors != null ? errors : Collections.<Error>emptyList();
108.292 - }
108.293 -
108.294 - public SymInfo findBySignature(ElementKind kind, String signature) {
108.295 - PythonTree scope = root;
108.296 - String name = signature;
108.297 - int dot = signature.lastIndexOf('.');
108.298 - if (dot != -1) {
108.299 - String clz = signature.substring(0, dot);
108.300 - name = signature.substring(dot + 1);
108.301 - SymInfo sym = findDeclaration(root, clz, true);
108.302 - if (sym != null && sym.node != null) {
108.303 - scope = sym.node;
108.304 - }
108.305 - }
108.306 - SymInfo sym = findDeclaration(scope, name, true);
108.307 -
108.308 - return sym;
108.309 - }
108.310 -
108.311 - private List<String> getModulesToStarImport() {
108.312 - List<String> modules = new ArrayList<>();
108.313 -
108.314 - for (ImportFrom from : importsFrom) {
108.315 - List<alias> names = from.getInternalNames();
108.316 - if (names != null) {
108.317 - for (alias at : names) {
108.318 - if ("*".equals(at.getInternalName())) { // NOI18N
108.319 - modules.add(from.getInternalModule());
108.320 - }
108.321 - }
108.322 - }
108.323 - }
108.324 -
108.325 - modules.addAll(PythonIndex.BUILTIN_MODULES);
108.326 -
108.327 - return modules;
108.328 - }
108.329 -
108.330 - private void addSymbolsFromModule(PythonParserResult info, String module, String prefix, QuerySupport.Kind kind, Set<? super IndexedElement> result) {
108.331 - if (PythonIndex.isBuiltinModule(module)) {
108.332 - Set<IndexedElement> all = getAllSymbolsFromModule(info, module);
108.333 - for (IndexedElement e : all) {
108.334 - if (kind == QuerySupport.Kind.PREFIX) {
108.335 - if (e.getName().startsWith(prefix)) {
108.336 - result.add(e);
108.337 - }
108.338 - } else if (kind == QuerySupport.Kind.EXACT) {
108.339 - if (prefix.equals(e.getName())) {
108.340 - result.add(e);
108.341 - }
108.342 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
108.343 - if (e.getName().regionMatches(true, 0, prefix, 0, prefix.length())) {
108.344 - result.add(e);
108.345 - }
108.346 - }
108.347 - }
108.348 - } else {
108.349 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
108.350 - Set<IndexedElement> elements = index.getImportedElements(prefix, kind, Collections.singleton(module), null);
108.351 - for (IndexedElement e : elements) {
108.352 - result.add(e);
108.353 - }
108.354 - }
108.355 - }
108.356 -
108.357 - private Set<IndexedElement> getAllSymbolsFromModule(PythonParserResult info, String module) {
108.358 - Set<IndexedElement> elements = importedElements.get(module);
108.359 - if (elements == null) {
108.360 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
108.361 - Set<String> systemHolder = new HashSet<>(3);
108.362 - elements = index.getImportedElements("", QuerySupport.Kind.PREFIX, Collections.singleton(module), systemHolder);
108.363 - // Cache system modules - don't cache local modules
108.364 - if (!systemHolder.isEmpty()) {
108.365 - importedElements.put(module, elements);
108.366 - }
108.367 - }
108.368 -
108.369 - return elements;
108.370 - }
108.371 -
108.372 - public Set<Element> getDefinedElements(PythonParserResult info, PythonTree scope, String prefix, QuerySupport.Kind kind) {
108.373 - Set<Element> elements = new HashSet<>(300);
108.374 - ScopeInfo scopeInfo = scopes.get(scope);
108.375 - String module = PythonUtils.getModuleName(fileObject);
108.376 - String url = fileObject.toURL().toExternalForm();
108.377 -
108.378 - // Get builtin symbols
108.379 - for (String mod : getModulesToStarImport()) {
108.380 - addSymbolsFromModule(info, mod, prefix, kind, elements);
108.381 - }
108.382 -
108.383 - // I can't just search the scope table for all variables in scope because this
108.384 - // will only include the local -bound- variables and the -used- free variables.
108.385 - // I need to find potential free variables as well. This means I should walk up
108.386 - // the scope chain and compute all eligible names. By keep track of the ones I've
108.387 - // already added I avoid adding references to variables I have re-bound in closer
108.388 - // scopes.
108.389 -
108.390 - Set<String> added = new HashSet<>();
108.391 -
108.392 - while (scopeInfo != null) {
108.393 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
108.394 - String name = entry.getKey();
108.395 - if (added.contains(name)) {
108.396 - // Something in narrower scope already processed this one
108.397 - continue;
108.398 - }
108.399 - if (kind == QuerySupport.Kind.EXACT) {
108.400 - if (!(name.equals(prefix))) {
108.401 - continue;
108.402 - }
108.403 - } else if (kind == QuerySupport.Kind.PREFIX) {
108.404 - if (!name.startsWith(prefix)) {
108.405 - continue;
108.406 - }
108.407 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
108.408 - if (!name.regionMatches(true, 0, prefix, 0, prefix.length())) {
108.409 - continue;
108.410 - }
108.411 - }
108.412 - SymInfo sym = entry.getValue();
108.413 -
108.414 - ScopeInfo curr = scopeInfo;
108.415 - while (sym != null && sym.isFree()) {
108.416 - curr = curr.up;
108.417 - while (curr != null && curr.kind == CLASSSCOPE) {
108.418 - curr = curr.up;
108.419 - }
108.420 - if (curr == null) {
108.421 - sym = null;
108.422 - break;
108.423 - }
108.424 - sym = scopeInfo.tbl.get(name);
108.425 - }
108.426 - if (sym == null) {
108.427 - continue;
108.428 - }
108.429 - if (sym.isUnresolved()) {
108.430 - // Don't add completion items for stuff we're not sure about
108.431 - continue;
108.432 - }
108.433 -
108.434 - PythonTree node = sym.node;
108.435 - if (node == null) {
108.436 - continue;
108.437 - }
108.438 -
108.439 -
108.440 - if (sym.isImported()) {
108.441 - Element element = new AstElement(this, node, name, Character.isUpperCase(name.charAt(0)) ? ElementKind.CLASS : ElementKind.MODULE);
108.442 - elements.add(element);
108.443 - } else if (sym.isDef()) {
108.444 - String signature;
108.445 - if (sym.isClass() && node instanceof ClassDef) {
108.446 - signature = PythonIndexer.computeClassSig((ClassDef)node, sym);
108.447 - } else if (sym.isFunction() && node instanceof FunctionDef) {
108.448 - assert sym.isFunction() && node instanceof FunctionDef : name + ";" + sym + " in " + module;
108.449 - signature = PythonIndexer.computeFunctionSig(name, (FunctionDef)node, sym);
108.450 - } else {
108.451 - // Probably a generator expression
108.452 - continue;
108.453 - }
108.454 - //Element element = AstElement.create(null, node);
108.455 - IndexedElement element = IndexedElement.create(signature, module, url, null);
108.456 - element.setSmart(true);
108.457 - elements.add(element);
108.458 - } else {
108.459 - // TODO - class attributes?
108.460 - Element element = new AstElement(this, node, name, ElementKind.VARIABLE);
108.461 - elements.add(element);
108.462 - }
108.463 -
108.464 - added.add(name);
108.465 - }
108.466 -
108.467 - scopeInfo = scopeInfo.up;
108.468 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
108.469 - scopeInfo = scopeInfo.up;
108.470 - }
108.471 - }
108.472 -
108.473 - return elements;
108.474 - }
108.475 -
108.476 - // Return all node references to the given name
108.477 - // This will include imports, calls, definitions, etc.
108.478 - public List<PythonTree> getOccurrences(PythonTree scope, String name, boolean abortOnFree) {
108.479 - ScopeInfo scopeInfo = scopes.get(scope);
108.480 - if (scopeInfo != null) {
108.481 - SymInfo sym = scopeInfo.tbl.get(name);
108.482 - while (sym != null && sym.isFree()) {
108.483 - if (abortOnFree) {
108.484 - return null;
108.485 - }
108.486 - scopeInfo = scopeInfo.up;
108.487 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
108.488 - scopeInfo = scopeInfo.up;
108.489 - }
108.490 - sym = scopeInfo.tbl.get(name);
108.491 - }
108.492 -
108.493 - if (sym != null) {
108.494 - NameNodeFinder finder = new NameNodeFinder(name, scopeInfo.scope_node);
108.495 - finder.run();
108.496 - return finder.getNodes();
108.497 - }
108.498 - }
108.499 -
108.500 - return Collections.emptyList();
108.501 - }
108.502 -
108.503 - /** Return a list of the variables visible from a given scope */
108.504 - public Set<String> getVarNames(PythonTree scope, boolean mustBeBound) {
108.505 - ScopeInfo scopeInfo = scopes.get(scope);
108.506 - Set<String> names = new HashSet<>();
108.507 - while (scopeInfo != null) {
108.508 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
108.509 - String name = entry.getKey();
108.510 - SymInfo sym = entry.getValue();
108.511 - if (sym.isVariable(mustBeBound)) {
108.512 - names.add(name);
108.513 - }
108.514 - }
108.515 - scopeInfo = scopeInfo.up;
108.516 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
108.517 - scopeInfo = scopeInfo.up;
108.518 - }
108.519 - }
108.520 -
108.521 - return names;
108.522 - }
108.523 -
108.524 - public List<ImportEntry> getUnusedImports() {
108.525 - List<ImportEntry> unused = new ArrayList<>();
108.526 - ScopeInfo scopeInfo = scopes.get(root);
108.527 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
108.528 - SymInfo sym = entry.getValue();
108.529 - if (sym.isImported() && !sym.isRead()) {
108.530 - String name = entry.getKey();
108.531 - if (name.equals("*")) { // NOI18N
108.532 - // Not detecting usages of wildcard imports yet...
108.533 - continue;
108.534 - }
108.535 - PythonTree node = sym.node;
108.536 - if (node instanceof Import) {
108.537 - Import imp = (Import)node;
108.538 - int ordinal = 0;
108.539 - String module = null;
108.540 - String asName = null;
108.541 - List<alias> names = imp.getInternalNames();
108.542 - if (names != null) {
108.543 - for (alias at : names) {
108.544 - if (name.equals(at.getInternalAsname())) {
108.545 - module = at.getInternalName();
108.546 - asName = at.getInternalAsname();
108.547 - break;
108.548 - } else if (name.equals(at.getInternalName())) {
108.549 - module = at.getInternalName();
108.550 - break;
108.551 - }
108.552 - }
108.553 - if (module == null) {
108.554 - // For imports with dotted names, like wsgiref.handlers,
108.555 - // the symbol table entry is just "wsgiref", yet I have to match
108.556 - // the symbols, so try again more carefully
108.557 - for (alias at : names) {
108.558 - if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
108.559 - at.getInternalAsname().charAt(name.length()) == '.') {
108.560 - module = at.getInternalName();
108.561 - asName = at.getInternalAsname();
108.562 - break;
108.563 - } else if (at.getInternalName().startsWith(name) &&
108.564 - at.getInternalName().charAt(name.length()) == '.') {
108.565 - module = at.getInternalName();
108.566 - break;
108.567 - }
108.568 - }
108.569 - }
108.570 - }
108.571 - unused.add(new ImportEntry(module, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
108.572 - } else if (node instanceof ImportFrom) {
108.573 - ImportFrom imp = (ImportFrom)node;
108.574 - if (ImportManager.isFutureImport(imp)) {
108.575 - continue;
108.576 - }
108.577 - String module = imp.getInternalModule();
108.578 - String origName = null;
108.579 - String asName = null;
108.580 - int ordinal = 0;
108.581 - List<alias> names = imp.getInternalNames();
108.582 - if (names != null) {
108.583 - for (alias at : names) {
108.584 - if (name.equals(at.getInternalAsname())) {
108.585 - origName = at.getInternalName();
108.586 - asName = at.getInternalAsname();
108.587 - break;
108.588 - } else if (name.equals(at.getInternalName())) {
108.589 - origName = at.getInternalName();
108.590 - break;
108.591 - }
108.592 - }
108.593 - if (origName == null) {
108.594 - // For imports with dotted names, like wsgiref.handlers,
108.595 - // the symbol table entry is just "wsgiref", yet I have to match
108.596 - // the symbols, so try again more carefully
108.597 - for (alias at : names) {
108.598 - if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
108.599 - at.getInternalAsname().charAt(name.length()) == '.') {
108.600 - origName = at.getInternalName();
108.601 - asName = at.getInternalAsname();
108.602 - break;
108.603 - } else if (at.getInternalName().startsWith(name) &&
108.604 - at.getInternalName().charAt(name.length()) == '.') {
108.605 - origName = at.getInternalName();
108.606 - break;
108.607 - }
108.608 - }
108.609 - }
108.610 - }
108.611 - unused.add(new ImportEntry(module, origName, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
108.612 - }
108.613 - }
108.614 - }
108.615 -
108.616 - return unused;
108.617 - }
108.618 -
108.619 - private class NameNodeFinder extends Visitor {
108.620 - private List<PythonTree> nodes = new ArrayList<>();
108.621 - private PythonTree startScope;
108.622 - private String name;
108.623 -
108.624 - public NameNodeFinder(String name, PythonTree startScope) {
108.625 - this.name = name;
108.626 - this.startScope = startScope;
108.627 - }
108.628 -
108.629 - public void run() {
108.630 - try {
108.631 - visit(startScope);
108.632 - } catch (Exception ex) {
108.633 - Exceptions.printStackTrace(ex);
108.634 - }
108.635 - }
108.636 -
108.637 - @Override
108.638 - public Object visitImport(Import imp) throws Exception {
108.639 - List<alias> names = imp.getInternalNames();
108.640 - if (names != null && names.size() > 0) {
108.641 - boolean found = false;
108.642 - for (alias at : names) {
108.643 - String asName = at.getInternalAsname();
108.644 - if (asName != null) {
108.645 - if (name.equals(asName)) {
108.646 - found = true;
108.647 - break;
108.648 - }
108.649 - } else if (name.equals(at.getInternalName())) {
108.650 - found = true;
108.651 - break;
108.652 - }
108.653 - }
108.654 - if (found) {
108.655 - nodes.add(imp);
108.656 - }
108.657 - }
108.658 - return super.visitImport(imp);
108.659 - }
108.660 -
108.661 - @Override
108.662 - public Object visitImportFrom(ImportFrom imp) throws Exception {
108.663 - List<alias> names = imp.getInternalNames();
108.664 - if (names != null && names.size() > 0) {
108.665 - boolean found = false;
108.666 - for (alias at : names) {
108.667 - String asName = at.getInternalAsname();
108.668 - if (asName != null) {
108.669 - if (name.equals(asName)) {
108.670 - found = true;
108.671 - break;
108.672 - }
108.673 - } else if (name.equals(at.getInternalName())) {
108.674 - found = true;
108.675 - break;
108.676 - }
108.677 - }
108.678 - if (found) {
108.679 - nodes.add(imp);
108.680 - }
108.681 - }
108.682 -
108.683 - return super.visitImportFrom(imp);
108.684 - }
108.685 -
108.686 - @Override
108.687 - public Object visitName(Name node) throws Exception {
108.688 - if (node.getInternalId().equals(name)) {
108.689 - nodes.add(node);
108.690 - }
108.691 - return super.visitName(node);
108.692 - }
108.693 -
108.694 - @Override
108.695 - public Object visitFunctionDef(FunctionDef node) throws Exception {
108.696 - if (name.equals(node.getInternalName())) {
108.697 - nodes.add(node);
108.698 - }
108.699 -
108.700 - if (isIncludedScope(node)) {
108.701 - return super.visitFunctionDef(node);
108.702 - } else {
108.703 - return null;
108.704 - }
108.705 - }
108.706 -
108.707 - @Override
108.708 - public Object visitClassDef(ClassDef node) throws Exception {
108.709 - if (name.equals(node.getInternalName())) {
108.710 - nodes.add(node);
108.711 - }
108.712 -
108.713 - if (isIncludedScope(node)) {
108.714 - return super.visitClassDef(node);
108.715 - } else {
108.716 - return null;
108.717 - }
108.718 - }
108.719 -
108.720 - @Override
108.721 - public Object visitExpression(Expression node) throws Exception {
108.722 - if (isIncludedScope(node)) {
108.723 - return super.visitExpression(node);
108.724 - } else {
108.725 - return null;
108.726 - }
108.727 - }
108.728 -
108.729 - @Override
108.730 - public Object visitInteractive(Interactive node) throws Exception {
108.731 - if (isIncludedScope(node)) {
108.732 - return super.visitInteractive(node);
108.733 - } else {
108.734 - return null;
108.735 - }
108.736 - }
108.737 -
108.738 - @Override
108.739 - public Object visitLambda(Lambda node) throws Exception {
108.740 - if (isIncludedScope(node)) {
108.741 - return super.visitLambda(node);
108.742 - } else {
108.743 - return null;
108.744 - }
108.745 - }
108.746 -
108.747 - @Override
108.748 - public Object visitGeneratorExp(GeneratorExp node) throws Exception {
108.749 - if (isIncludedScope(node)) {
108.750 - return super.visitGeneratorExp(node);
108.751 - } else {
108.752 - return null;
108.753 - }
108.754 - }
108.755 -
108.756 - private boolean isIncludedScope(PythonTree node) {
108.757 - if (node == startScope) {
108.758 - return true;
108.759 - }
108.760 -
108.761 - ScopeInfo info = scopes.get(node);
108.762 - if (info == null) {
108.763 - return false;
108.764 - }
108.765 -
108.766 - SymInfo sym = info.tbl.get(name);
108.767 - // Skip scopes that redefine the variable
108.768 - if (sym != null && sym.isBound()) {
108.769 - return false;
108.770 - }
108.771 -
108.772 - return true;
108.773 - }
108.774 -
108.775 - public List<PythonTree> getNodes() {
108.776 - return nodes;
108.777 - }
108.778 - }
108.779 -
108.780 - public Map<String, SymInfo> getUnresolvedNames(PythonParserResult info) {
108.781 - Map<String, SymInfo> unresolved = new HashMap<>();
108.782 - Set<String> builtin = getBuiltin(info);
108.783 -
108.784 - for (ScopeInfo scopeInfo : scopes.values()) {
108.785 - Map<String, SymInfo> tbl = scopeInfo.tbl;
108.786 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
108.787 - SymInfo symInfo = entry.getValue();
108.788 - boolean isUnresolved = symInfo.isUnresolved();
108.789 - if (!isUnresolved && symInfo.isFree()) {
108.790 - // Peek up scope stack
108.791 - String name = entry.getKey();
108.792 - SymInfo sym = symInfo;
108.793 - ScopeInfo scope = scopeInfo;
108.794 - while (sym != null && sym.isFree()) {
108.795 - scope = scope.up;
108.796 - while (scope != null && scope.kind == CLASSSCOPE) {
108.797 - scope = scope.up;
108.798 - }
108.799 - sym = scope.tbl.get(name);
108.800 - }
108.801 - if (sym == null) {
108.802 - isUnresolved = true;
108.803 - } else {
108.804 - isUnresolved = sym.isUnresolved();
108.805 - }
108.806 - }
108.807 - if (isUnresolved) {
108.808 - String key = entry.getKey();
108.809 - if (!builtin.contains(key)) {
108.810 - unresolved.put(key, symInfo);
108.811 - }
108.812 - }
108.813 - }
108.814 - }
108.815 -
108.816 - return unresolved;
108.817 - }
108.818 -
108.819 - public List<Attribute> getNotInInitAttributes(PythonParserResult info) {
108.820 - List<Attribute> notInInitAttribs = new ArrayList<>();
108.821 - for (ScopeInfo scopeInfo : scopes.values()) {
108.822 - if (scopeInfo.scope_node instanceof ClassDef) {
108.823 - if (scopeInfo.attributes != null) {
108.824 - for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
108.825 - SymInfo symInfo = entry.getValue();
108.826 - if (!symInfo.isBoundInConstructor()) {
108.827 - notInInitAttribs.add((Attribute)symInfo.node);
108.828 - }
108.829 - }
108.830 - }
108.831 - }
108.832 - }
108.833 - return notInInitAttribs;
108.834 - }
108.835 -
108.836 - private ScopeInfo getClassScope(String className) {
108.837 - for (ScopeInfo scopeInfo : scopes.values()) {
108.838 - if (scopeInfo.scope_node instanceof ClassDef) {
108.839 - ClassDef curClass = (ClassDef)scopeInfo.scope_node;
108.840 - if (curClass.getInternalName().equals(className)) {
108.841 - return scopeInfo;
108.842 - }
108.843 - }
108.844 - }
108.845 - return null;
108.846 - }
108.847 -
108.848 - private int belongsToParents(ClassDef cls, String name, HashMap<String, String> cycling) {
108.849 - List<expr> bases = cls.getInternalBases();
108.850 - if (bases == null || bases.size() == 0) {
108.851 - return NO; // no parents
108.852 - }
108.853 - for (expr base : bases) {
108.854 - String className = null;
108.855 - if (base instanceof Name) {
108.856 - className = ((Name)base).getInternalId();
108.857 - } else {
108.858 - // should be Attribute here( module.className form )
108.859 - // which imply imported from external scope
108.860 - // So we give up on scope returning optimistaically True
108.861 - return YES;
108.862 - }
108.863 - assert (className != null);
108.864 - if (cycling.get(className) != null) {
108.865 - cycling.clear();
108.866 - // put parent child conficting back in cycling
108.867 - cycling.put(className, cls.getInternalName());
108.868 - return CIRCULAR;
108.869 - }
108.870 - cycling.put(className, className);
108.871 - ScopeInfo localClassScope = getClassScope(className);
108.872 - if (localClassScope == null) {
108.873 - // return true (success) when at least one parent is outside module scope
108.874 - // just to notify caller to be optimistic and assume that
108.875 - // name is resolved by imported classes inheritance
108.876 - // scanning imported classed from here is discouraged for
108.877 - // performances reasons
108.878 - return YES;
108.879 - } else {
108.880 - if ((name != null) &&
108.881 - (localClassScope.attributes.get(name) != null)) {
108.882 - return YES;
108.883 - }
108.884 - // try recurse parentage to resolve attribute
108.885 - ClassDef parentClass = (ClassDef)localClassScope.scope_node;
108.886 - int recResult = belongsToParents(parentClass, name, cycling);
108.887 - if (recResult != NO) // stop on FOUND(YES) or CIRCULAR error
108.888 - {
108.889 - return recResult;
108.890 - }
108.891 - }
108.892 - }
108.893 - return NO;
108.894 - }
108.895 -
108.896 - private boolean isImported(String moduleName) {
108.897 - for (Import imported : imports) {
108.898 - List<alias> names = imported.getInternalNames();
108.899 - if (names != null) {
108.900 - for (alias cur : names) {
108.901 - String name = cur.getInternalName();
108.902 - String asName = cur.getInternalAsname();
108.903 - if (((name != null) && (name.equals(moduleName))) ||
108.904 - ((asName != null) && (asName.equals(moduleName)))) {
108.905 - return true;
108.906 - }
108.907 - }
108.908 - }
108.909 - }
108.910 - return false;
108.911 - }
108.912 -
108.913 - private boolean isImportedFrom(String className) {
108.914 - for (ImportFrom importedFrom : importsFrom) {
108.915 - List<alias> names = importedFrom.getInternalNames();
108.916 - if (names != null) {
108.917 - for (alias cur : names) {
108.918 - String name = cur.getInternalName();
108.919 - String asName = cur.getInternalAsname();
108.920 - if (((name != null) && (name.equals(className))) ||
108.921 - ((asName != null) && (asName.equals(className)))) {
108.922 - return true;
108.923 - }
108.924 - }
108.925 - }
108.926 - }
108.927 - return false;
108.928 - }
108.929 -
108.930 - public List<PythonTree> getUnresolvedParents(PythonParserResult info) {
108.931 - // deal with unresolved parents in inherit trees
108.932 - List<PythonTree> unresolvedParents = new ArrayList<>();
108.933 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
108.934 -
108.935 - for (String cur : classes.keySet()) {
108.936 - ClassDef cls = classes.get(cur);
108.937 - List<expr> bases = cls.getInternalBases();
108.938 - if (bases == null || bases.size() > 0) {
108.939 - // has parents
108.940 - for (expr base : bases) {
108.941 - if (base instanceof Name) {
108.942 - String className = ((Name)base).getInternalId();
108.943 - Set<String> builtin = getBuiltin(info);
108.944 - if ((!classes.containsKey(className)) &&
108.945 - (!builtin.contains(className))) {
108.946 - // check in from imports
108.947 - if (!isImportedFrom(className)) {
108.948 - unresolvedParents.add(base);
108.949 - }
108.950 - }
108.951 - } else {
108.952 - // should be Attribute here( module.className form )
108.953 - // which imply imported from external scope
108.954 - Attribute attr = (Attribute)base;
108.955 - String clsName = attr.getInternalAttr();
108.956 - if (attr.getInternalValue() instanceof Name) {
108.957 - String moduleName = ((Name)(attr.getInternalValue())).getInternalId();
108.958 - // check that import is resolved first
108.959 - if (!isImported(moduleName)) {
108.960 - unresolvedParents.add(base);
108.961 - } else {
108.962 - Set<IndexedElement> found = index.getImportedElements(clsName, QuerySupport.Kind.EXACT, Collections.<String>singleton(moduleName), null);
108.963 - if (found.size() == 0) {
108.964 - unresolvedParents.add(base);
108.965 - }
108.966 - }
108.967 - } else {
108.968 - unresolvedParents.add(base);
108.969 - }
108.970 - }
108.971 - }
108.972 - }
108.973 - }
108.974 - return unresolvedParents;
108.975 - }
108.976 -
108.977 - public HashMap<ClassDef, String> getClassesCyclingRedundancies(PythonParserResult info) {
108.978 - HashMap<ClassDef, String> cyclingRedundancies = new HashMap<>();
108.979 - for (String cur : classes.keySet()) {
108.980 - HashMap<String, String> returned = new HashMap<>();
108.981 - ClassDef curClass = classes.get(cur);
108.982 - if (!cyclingRedundancies.containsKey(curClass)) {
108.983 - if (belongsToParents(curClass, null, returned) == CIRCULAR) {
108.984 - // store hashMap returned
108.985 - Map.Entry<String, String> cycling = returned.entrySet().iterator().next();
108.986 - cyclingRedundancies.put(curClass, cycling.getKey());
108.987 - }
108.988 - }
108.989 - }
108.990 - return cyclingRedundancies;
108.991 - }
108.992 -
108.993 - public List<PythonTree> getUnresolvedAttributes(PythonParserResult info) {
108.994 - List<PythonTree> unresolvedNodes = new ArrayList<>();
108.995 - for (ScopeInfo scopeInfo : scopes.values()) {
108.996 - Set<String> unresolved = new HashSet<>();
108.997 - Map<String, SymInfo> tbl = scopeInfo.tbl;
108.998 - // unresolved attributes in local classes
108.999 - Map<String, SymInfo> attribs = scopeInfo.attributes;
108.1000 - for (Map.Entry<String, SymInfo> curAttr : attribs.entrySet()) {
108.1001 - SymInfo symInfo = curAttr.getValue();
108.1002 - if (symInfo.isRead()) {
108.1003 - // check for builtin attribs first
108.1004 - if (classAttributes.get(curAttr.getKey()) == null) {
108.1005 - // not a builtin attribute
108.1006 - ScopeInfo parentScope = scopeInfo.getClassScope();
108.1007 - if (parentScope != null) {
108.1008 - // limit scope to Classes for self and inherited
108.1009 - Map<String, SymInfo> parentattribs = parentScope.attributes;
108.1010 - SymInfo classAttr = parentattribs.get(curAttr.getKey());
108.1011 - tbl = parentScope.tbl;
108.1012 - if (classAttr == null) {
108.1013 - // may be also a reference to a method
108.1014 - classAttr = tbl.get(curAttr.getKey());
108.1015 - }
108.1016 - if (classAttr == null) {
108.1017 - // do not bother with method since they are
108.1018 - // managed by completion
108.1019 - ClassDef curClass = (ClassDef)parentScope.scope_node;
108.1020 - if (belongsToParents(curClass, curAttr.getKey(), new HashMap()) == NO) {
108.1021 - if (!symInfo.isCalled()) {
108.1022 - // no corresponding attributes
108.1023 - //PythonTree tree = symInfo.node ;
108.1024 - Attribute attr = (Attribute)symInfo.node;
108.1025 - // Name name = new Name(tree.getToken(),attr.getInternalAttr(),attr.ctx) ;
108.1026 - unresolvedNodes.add(attr);
108.1027 - }
108.1028 - }
108.1029 - }
108.1030 - }
108.1031 - }
108.1032 - }
108.1033 - }
108.1034 - if (unresolved.size() > 0) {
108.1035 - NameFinder finder = new NameFinder(unresolved);
108.1036 - List<Name> nodes = finder.run(scopeInfo.scope_node);
108.1037 - unresolvedNodes.addAll(nodes);
108.1038 - }
108.1039 -
108.1040 - }
108.1041 -
108.1042 - if (unresolvedNodes.size() > 1) {
108.1043 - Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
108.1044 - //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
108.1045 - }
108.1046 -
108.1047 - return unresolvedNodes;
108.1048 - }
108.1049 -
108.1050 - public List<PythonTree> getUnresolved(PythonParserResult info) {
108.1051 - List<PythonTree> unresolvedNodes = new ArrayList<>();
108.1052 - Set<String> builtin = getBuiltin(info);
108.1053 -
108.1054 - for (ScopeInfo scopeInfo : scopes.values()) {
108.1055 - Set<String> unresolved = new HashSet<>();
108.1056 - Map<String, SymInfo> tbl = scopeInfo.tbl;
108.1057 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
108.1058 - SymInfo symInfo = entry.getValue();
108.1059 - boolean isUnresolved = symInfo.isUnresolved();
108.1060 - if (!isUnresolved && symInfo.isFree()) {
108.1061 - // Peek up scope stack
108.1062 - String name = entry.getKey();
108.1063 - SymInfo sym = symInfo;
108.1064 - ScopeInfo scope = scopeInfo;
108.1065 - while (sym != null && sym.isFree()) {
108.1066 - scope = scope.up;
108.1067 - while (scope != null && scope.kind == CLASSSCOPE) {
108.1068 - scope = scope.up;
108.1069 - }
108.1070 - sym = scope.tbl.get(name);
108.1071 - }
108.1072 - if (sym == null) {
108.1073 - isUnresolved = true;
108.1074 - } else {
108.1075 - isUnresolved = sym.isUnresolved();
108.1076 - }
108.1077 - }
108.1078 - if (isUnresolved) {
108.1079 - String key = entry.getKey();
108.1080 - if (!builtin.contains(key)) {
108.1081 - unresolved.add(key);
108.1082 - }
108.1083 - }
108.1084 - }
108.1085 -
108.1086 -
108.1087 - if (unresolved.size() > 0) {
108.1088 - // Check imports and see if it's resolved by existing imports
108.1089 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
108.1090 - // TODO - cache system libraries!
108.1091 - // TODO - make method which doesn't create elements for these guys!
108.1092 -// Set<IndexedElement> elements = index.getImportedElements("", NameKind.PREFIX, PythonIndex.ALL_SCOPE, imports, importsFrom);
108.1093 -// for (IndexedElement e : elements) {
108.1094 -// unresolved.remove(e.getName());
108.1095 -// }
108.1096 - Set<String> wildcarded = index.getImportedFromWildcards(importsFrom);
108.1097 - unresolved.removeAll(wildcarded);
108.1098 -
108.1099 - if (unresolved.size() > 0) {
108.1100 - NameFinder finder = new NameFinder(unresolved);
108.1101 - List<Name> nodes = finder.run(scopeInfo.scope_node);
108.1102 - unresolvedNodes.addAll(nodes);
108.1103 - }
108.1104 - }
108.1105 - }
108.1106 -
108.1107 - if (unresolvedNodes.size() > 1) {
108.1108 - Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
108.1109 - //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
108.1110 - }
108.1111 -
108.1112 - return unresolvedNodes;
108.1113 - }
108.1114 -
108.1115 - public List<PythonTree> getUnused(boolean skipSelf, boolean skipParams) { // not used for unused imports, see separate method
108.1116 - List<PythonTree> unusedNodes = new ArrayList<>();
108.1117 -
108.1118 - for (ScopeInfo scopeInfo : scopes.values()) {
108.1119 - if (scopeInfo.kind != FUNCSCOPE && scopeInfo.kind != TOPSCOPE && scopeInfo.kind != CLASSSCOPE) {
108.1120 - continue;
108.1121 - }
108.1122 - Set<String> unused = new HashSet<>();
108.1123 - Map<String, SymInfo> tbl = scopeInfo.tbl;
108.1124 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
108.1125 - SymInfo symInfo = entry.getValue();
108.1126 - if (symInfo.isUnused(scopeInfo) && (!skipParams || !symInfo.isParameter())) {
108.1127 - String key = entry.getKey();
108.1128 - if (skipSelf && "self".equals(key)) { // NOI18N
108.1129 - continue;
108.1130 - }
108.1131 - unused.add(key);
108.1132 - }
108.1133 - }
108.1134 -
108.1135 - if (unused.size() > 0) {
108.1136 - NameFinder finder = new NameFinder(unused);
108.1137 - List<Name> nodes = finder.run(scopeInfo.scope_node);
108.1138 - unusedNodes.addAll(nodes);
108.1139 - }
108.1140 - }
108.1141 -
108.1142 - if (unusedNodes.size() > 1) {
108.1143 - Collections.sort(unusedNodes, PythonUtils.NAME_NODE_COMPARATOR);
108.1144 - //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
108.1145 - }
108.1146 -
108.1147 - return unusedNodes;
108.1148 - }
108.1149 -
108.1150 - private static class NameFinder extends Visitor {
108.1151 - private Set<String> names;
108.1152 - private List<Name> nodes = new ArrayList<>();
108.1153 - private PythonTree acceptDef;
108.1154 -
108.1155 - private NameFinder(Set<String> names) {
108.1156 - this.names = names;
108.1157 - }
108.1158 -
108.1159 - @Override
108.1160 - public Object visitClassDef(ClassDef node) throws Exception {
108.1161 - // Don't look in nested scopes
108.1162 - if (node != acceptDef) {
108.1163 - return null;
108.1164 - }
108.1165 - return super.visitClassDef(node);
108.1166 - }
108.1167 -
108.1168 - @Override
108.1169 - public Object visitFunctionDef(FunctionDef node) throws Exception {
108.1170 - // Don't look in nested scopes
108.1171 - if (node != acceptDef) {
108.1172 - return null;
108.1173 - }
108.1174 - return super.visitFunctionDef(node);
108.1175 - }
108.1176 -
108.1177 - @Override
108.1178 - public Object visitName(Name node) throws Exception {
108.1179 - String name = node.getInternalId();
108.1180 - if (names.contains(name)) {
108.1181 - nodes.add(node);
108.1182 - }
108.1183 -
108.1184 - return super.visitName(node);
108.1185 - }
108.1186 -
108.1187 - public List<Name> run(PythonTree node) {
108.1188 - this.acceptDef = node;
108.1189 - try {
108.1190 - visit(node);
108.1191 - } catch (Exception ex) {
108.1192 - Exceptions.printStackTrace(ex);
108.1193 - }
108.1194 -
108.1195 - return nodes;
108.1196 - }
108.1197 - }
108.1198 - private static Set<String> builtinSymbols;
108.1199 -
108.1200 - private Set<String> getBuiltin(PythonParserResult info) {
108.1201 - if (builtinSymbols == null) {
108.1202 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
108.1203 - builtinSymbols = index.getBuiltinSymbols();
108.1204 - }
108.1205 -
108.1206 - return builtinSymbols;
108.1207 - }
108.1208 -
108.1209 - public void error(String msg, boolean err, PythonTree node) throws Exception {
108.1210 - assert node != null;
108.1211 - // TODO - record and register with the hints manager?
108.1212 - OffsetRange range = PythonAstUtils.getRange(node);
108.1213 -
108.1214 - if (errors == null) {
108.1215 - errors = new ArrayList<>();
108.1216 - }
108.1217 - Error error = new DefaultError(null, msg, null, fileObject, range.getStart(), range.getEnd(), err ? Severity.ERROR : Severity.WARNING);
108.1218 - errors.add(error);
108.1219 - }
108.1220 -
108.1221 - public String getFilename() {
108.1222 - return FileUtil.getFileDisplayName(fileObject);
108.1223 - }
108.1224 -
108.1225 - public Map<PythonTree, ScopeInfo> getScopes() {
108.1226 - return scopes;
108.1227 - }
108.1228 -
108.1229 - public List<Import> getImports() {
108.1230 - return imports;
108.1231 - }
108.1232 -
108.1233 - public List<ImportFrom> getImportsFrom() {
108.1234 - return importsFrom;
108.1235 - }
108.1236 -
108.1237 - public boolean isTopLevel(PythonTree node) {
108.1238 - return topLevelImports.contains(node);
108.1239 - }
108.1240 -
108.1241 - public List<PythonTree> getMainImports() {
108.1242 - return mainImports;
108.1243 - }
108.1244 -
108.1245 - public Set<PythonTree> getTopLevelImports() {
108.1246 - return topLevelImports;
108.1247 - }
108.1248 -
108.1249 - public List<Str> getPublicSymbols() {
108.1250 - return publicSymbols;
108.1251 - }
108.1252 -}
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
109.2 +++ b/python.hints/build.xml Mon Sep 21 13:01:16 2015 +0200
109.3 @@ -0,0 +1,5 @@
109.4 +<?xml version="1.0" encoding="UTF-8"?>
109.5 +<project basedir="." default="netbeans" name="contrib/python.hints">
109.6 + <description>Builds, tests, and runs the project org.netbeans.modules.python.hints</description>
109.7 + <import file="../../nbbuild/templates/projectized.xml"/>
109.8 +</project>
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
110.2 +++ b/python.hints/manifest.mf Mon Sep 21 13:01:16 2015 +0200
110.3 @@ -0,0 +1,7 @@
110.4 +Manifest-Version: 1.0
110.5 +AutoUpdate-Show-In-Client: true
110.6 +OpenIDE-Module: org.netbeans.modules.python.hints
110.7 +OpenIDE-Module-Layer: org/netbeans/modules/python/hints/layer.xml
110.8 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/python/hints/Bundle.properties
110.9 +OpenIDE-Module-Specification-Version: 1.0
110.10 +
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
111.2 +++ b/python.hints/nbproject/project.properties Mon Sep 21 13:01:16 2015 +0200
111.3 @@ -0,0 +1,2 @@
111.4 +javac.source=1.7
111.5 +javac.compilerargs=-Xlint -Xlint:-serial
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
112.2 +++ b/python.hints/nbproject/project.xml Mon Sep 21 13:01:16 2015 +0200
112.3 @@ -0,0 +1,157 @@
112.4 +<?xml version="1.0" encoding="UTF-8"?>
112.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
112.6 + <type>org.netbeans.modules.apisupport.project</type>
112.7 + <configuration>
112.8 + <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
112.9 + <code-name-base>org.netbeans.modules.python.hints</code-name-base>
112.10 + <module-dependencies>
112.11 + <dependency>
112.12 + <code-name-base>org.jython</code-name-base>
112.13 + <build-prerequisite/>
112.14 + <compile-dependency/>
112.15 + <run-dependency>
112.16 + <release-version>2</release-version>
112.17 + <specification-version>2.12</specification-version>
112.18 + </run-dependency>
112.19 + </dependency>
112.20 + <dependency>
112.21 + <code-name-base>org.netbeans.modules.csl.api</code-name-base>
112.22 + <build-prerequisite/>
112.23 + <compile-dependency/>
112.24 + <run-dependency>
112.25 + <release-version>2</release-version>
112.26 + <specification-version>2.51</specification-version>
112.27 + </run-dependency>
112.28 + </dependency>
112.29 + <dependency>
112.30 + <code-name-base>org.netbeans.modules.editor.codetemplates</code-name-base>
112.31 + <build-prerequisite/>
112.32 + <compile-dependency/>
112.33 + <run-dependency>
112.34 + <release-version>1</release-version>
112.35 + <specification-version>1.41</specification-version>
112.36 + </run-dependency>
112.37 + </dependency>
112.38 + <dependency>
112.39 + <code-name-base>org.netbeans.modules.editor.document</code-name-base>
112.40 + <build-prerequisite/>
112.41 + <compile-dependency/>
112.42 + <run-dependency>
112.43 + <specification-version>1.5</specification-version>
112.44 + </run-dependency>
112.45 + </dependency>
112.46 + <dependency>
112.47 + <code-name-base>org.netbeans.modules.editor.indent</code-name-base>
112.48 + <build-prerequisite/>
112.49 + <compile-dependency/>
112.50 + <run-dependency>
112.51 + <release-version>2</release-version>
112.52 + <specification-version>1.42</specification-version>
112.53 + </run-dependency>
112.54 + </dependency>
112.55 + <dependency>
112.56 + <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
112.57 + <build-prerequisite/>
112.58 + <compile-dependency/>
112.59 + <run-dependency>
112.60 + <release-version>3</release-version>
112.61 + <specification-version>4.3</specification-version>
112.62 + </run-dependency>
112.63 + </dependency>
112.64 + <dependency>
112.65 + <code-name-base>org.netbeans.modules.lexer</code-name-base>
112.66 + <build-prerequisite/>
112.67 + <compile-dependency/>
112.68 + <run-dependency>
112.69 + <release-version>2</release-version>
112.70 + <specification-version>1.62</specification-version>
112.71 + </run-dependency>
112.72 + </dependency>
112.73 + <dependency>
112.74 + <code-name-base>org.netbeans.modules.options.api</code-name-base>
112.75 + <build-prerequisite/>
112.76 + <compile-dependency/>
112.77 + <run-dependency>
112.78 + <release-version>1</release-version>
112.79 + <specification-version>1.44</specification-version>
112.80 + </run-dependency>
112.81 + </dependency>
112.82 + <dependency>
112.83 + <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
112.84 + <build-prerequisite/>
112.85 + <compile-dependency/>
112.86 + <run-dependency>
112.87 + <release-version>1</release-version>
112.88 + <specification-version>9.5</specification-version>
112.89 + </run-dependency>
112.90 + </dependency>
112.91 + <dependency>
112.92 + <code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
112.93 + <build-prerequisite/>
112.94 + <compile-dependency/>
112.95 + <run-dependency>
112.96 + <specification-version>9.7</specification-version>
112.97 + </run-dependency>
112.98 + </dependency>
112.99 + <dependency>
112.100 + <code-name-base>org.netbeans.modules.projectapi</code-name-base>
112.101 + <build-prerequisite/>
112.102 + <compile-dependency/>
112.103 + <run-dependency>
112.104 + <release-version>1</release-version>
112.105 + <specification-version>1.65</specification-version>
112.106 + </run-dependency>
112.107 + </dependency>
112.108 + <dependency>
112.109 + <code-name-base>org.netbeans.modules.python.core</code-name-base>
112.110 + <build-prerequisite/>
112.111 + <compile-dependency/>
112.112 + <run-dependency>
112.113 + <specification-version>1.4</specification-version>
112.114 + </run-dependency>
112.115 + </dependency>
112.116 + <dependency>
112.117 + <code-name-base>org.netbeans.modules.python.editor</code-name-base>
112.118 + <build-prerequisite/>
112.119 + <compile-dependency/>
112.120 + <run-dependency>
112.121 + <specification-version>1.8.2</specification-version>
112.122 + </run-dependency>
112.123 + </dependency>
112.124 + <dependency>
112.125 + <code-name-base>org.netbeans.modules.python.source</code-name-base>
112.126 + <build-prerequisite/>
112.127 + <compile-dependency/>
112.128 + <run-dependency>
112.129 + <specification-version>1.1</specification-version>
112.130 + </run-dependency>
112.131 + </dependency>
112.132 + <dependency>
112.133 + <code-name-base>org.openide.filesystems</code-name-base>
112.134 + <build-prerequisite/>
112.135 + <compile-dependency/>
112.136 + <run-dependency>
112.137 + <specification-version>9.8</specification-version>
112.138 + </run-dependency>
112.139 + </dependency>
112.140 + <dependency>
112.141 + <code-name-base>org.openide.util</code-name-base>
112.142 + <build-prerequisite/>
112.143 + <compile-dependency/>
112.144 + <run-dependency>
112.145 + <specification-version>9.5</specification-version>
112.146 + </run-dependency>
112.147 + </dependency>
112.148 + <dependency>
112.149 + <code-name-base>org.openide.util.lookup</code-name-base>
112.150 + <build-prerequisite/>
112.151 + <compile-dependency/>
112.152 + <run-dependency>
112.153 + <specification-version>8.32</specification-version>
112.154 + </run-dependency>
112.155 + </dependency>
112.156 + </module-dependencies>
112.157 + <public-packages/>
112.158 + </data>
112.159 + </configuration>
112.160 +</project>
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
113.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AccessToProtected.java Mon Sep 21 13:01:16 2015 +0200
113.3 @@ -0,0 +1,150 @@
113.4 +/*
113.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
113.6 + *
113.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
113.8 + *
113.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
113.10 + * Other names may be trademarks of their respective owners.
113.11 + *
113.12 + * The contents of this file are subject to the terms of either the GNU
113.13 + * General Public License Version 2 only ("GPL") or the Common
113.14 + * Development and Distribution License("CDDL") (collectively, the
113.15 + * "License"). You may not use this file except in compliance with the
113.16 + * License. You can obtain a copy of the License at
113.17 + * http://www.netbeans.org/cddl-gplv2.html
113.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
113.19 + * specific language governing permissions and limitations under the
113.20 + * License. When distributing the software, include this License Header
113.21 + * Notice in each file and include the License file at
113.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
113.23 + * particular file as subject to the "Classpath" exception as provided
113.24 + * by Oracle in the GPL Version 2 section of the License file that
113.25 + * accompanied this code. If applicable, add the following below the
113.26 + * License Header, with the fields enclosed by brackets [] replaced by
113.27 + * your own identifying information:
113.28 + * "Portions Copyrighted [year] [name of copyright owner]"
113.29 + *
113.30 + * If you wish your version of this file to be governed by only the CDDL
113.31 + * or only the GPL Version 2, indicate your decision by adding
113.32 + * "[Contributor] elects to include this software in this distribution
113.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
113.34 + * single choice of license, a recipient has the option to distribute
113.35 + * your version of this file under either the CDDL, the GPL Version 2 or
113.36 + * to extend the choice of license to its licensees as provided above.
113.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
113.38 + * Version 2 license, then the option applies only if the new code is
113.39 + * made subject to such option by the copyright holder.
113.40 + *
113.41 + * Contributor(s):
113.42 + *
113.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
113.44 + */
113.45 +package org.netbeans.modules.python.hints;
113.46 +
113.47 +import java.util.Collections;
113.48 +import java.util.List;
113.49 +import java.util.Set;
113.50 +import java.util.prefs.Preferences;
113.51 +import javax.swing.JComponent;
113.52 +import org.netbeans.modules.csl.api.Hint;
113.53 +import org.netbeans.modules.csl.api.HintFix;
113.54 +import org.netbeans.modules.csl.api.HintSeverity;
113.55 +import org.netbeans.modules.csl.api.OffsetRange;
113.56 +import org.netbeans.modules.csl.api.RuleContext;
113.57 +import org.netbeans.modules.python.source.PythonAstUtils;
113.58 +import org.netbeans.modules.python.source.PythonParserResult;
113.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
113.60 +import org.netbeans.modules.python.source.NameStyle;
113.61 +import org.openide.util.NbBundle;
113.62 +import org.python.antlr.ast.Attribute;
113.63 +import org.python.antlr.ast.Name;
113.64 +import org.python.antlr.base.expr;
113.65 +
113.66 +/**
113.67 + * Check direct acces to parent protected variables or methods
113.68 + * @author jean-yves Mengant
113.69 + */
113.70 +public class AccessToProtected extends PythonAstRule {
113.71 + private final static String ACCESS_PROTECTED_ID = "AccessProtected"; // NOI18N
113.72 + private final static String ACCESS_PROTECTED_VARIABLE = "AccessProtectedVariable"; // NOI18N
113.73 + private final static String ACCESS_PROTECTED_DESC = "AccessProtectedDesc"; // NOI18N
113.74 +
113.75 + @Override
113.76 + public Set<Class> getKinds() {
113.77 + return Collections.<Class>singleton(Attribute.class);
113.78 + }
113.79 +
113.80 + @Override
113.81 + public void run(PythonRuleContext context, List<Hint> result) {
113.82 + PythonParserResult info = (PythonParserResult) context.parserResult;
113.83 + Attribute cur = (Attribute)context.node;
113.84 + String curAttr = cur.getInternalAttr();
113.85 + if (curAttr == null) {
113.86 + return;
113.87 + }
113.88 +
113.89 + if (NameStyle.isProtectedName(curAttr)) {
113.90 + expr curValue = cur.getInternalValue();
113.91 + if (curValue instanceof Name) {
113.92 + Name nam = (Name)curValue;
113.93 + String id = nam.getInternalId();
113.94 + if (id.equals("self")) { // NOI18N
113.95 + return; // normal access from class instance
113.96 + }
113.97 + if (PythonAstUtils.getParentClassFromNode(context.path, null, id) != null) {
113.98 + return; // parent access
113.99 + }
113.100 + // we should warn here : Access to protected Attributes from non child
113.101 + // classes
113.102 + OffsetRange range = PythonAstUtils.getRange(cur);
113.103 + range = PythonLexerUtils.getLexerOffsets(info, range);
113.104 + if (range != OffsetRange.NONE) {
113.105 + List<HintFix> fixList = Collections.emptyList();
113.106 + String message = NbBundle.getMessage(NameRule.class, ACCESS_PROTECTED_VARIABLE, curAttr);
113.107 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
113.108 + result.add(desc);
113.109 + }
113.110 + }
113.111 + }
113.112 + }
113.113 +
113.114 + @Override
113.115 + public String getId() {
113.116 + return ACCESS_PROTECTED_ID;
113.117 + }
113.118 +
113.119 + @Override
113.120 + public String getDescription() {
113.121 + return NbBundle.getMessage(RelativeImports.class, ACCESS_PROTECTED_DESC);
113.122 + }
113.123 +
113.124 + @Override
113.125 + public boolean getDefaultEnabled() {
113.126 + return false;
113.127 + }
113.128 +
113.129 + @Override
113.130 + public JComponent getCustomizer(Preferences node) {
113.131 + return null;
113.132 + }
113.133 +
113.134 + @Override
113.135 + public boolean appliesTo(RuleContext context) {
113.136 + return true;
113.137 + }
113.138 +
113.139 + @Override
113.140 + public String getDisplayName() {
113.141 + return NbBundle.getMessage(AccessToProtected.class, ACCESS_PROTECTED_ID);
113.142 + }
113.143 +
113.144 + @Override
113.145 + public boolean showInTasklist() {
113.146 + return true;
113.147 + }
113.148 +
113.149 + @Override
113.150 + public HintSeverity getDefaultSeverity() {
113.151 + return HintSeverity.WARNING;
113.152 + }
113.153 +}
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
114.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AllAssignExists.java Mon Sep 21 13:01:16 2015 +0200
114.3 @@ -0,0 +1,148 @@
114.4 +/*
114.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
114.6 + *
114.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
114.8 + *
114.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
114.10 + * Other names may be trademarks of their respective owners.
114.11 + *
114.12 + * The contents of this file are subject to the terms of either the GNU
114.13 + * General Public License Version 2 only ("GPL") or the Common
114.14 + * Development and Distribution License("CDDL") (collectively, the
114.15 + * "License"). You may not use this file except in compliance with the
114.16 + * License. You can obtain a copy of the License at
114.17 + * http://www.netbeans.org/cddl-gplv2.html
114.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
114.19 + * specific language governing permissions and limitations under the
114.20 + * License. When distributing the software, include this License Header
114.21 + * Notice in each file and include the License file at
114.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
114.23 + * particular file as subject to the "Classpath" exception as provided
114.24 + * by Oracle in the GPL Version 2 section of the License file that
114.25 + * accompanied this code. If applicable, add the following below the
114.26 + * License Header, with the fields enclosed by brackets [] replaced by
114.27 + * your own identifying information:
114.28 + * "Portions Copyrighted [year] [name of copyright owner]"
114.29 + *
114.30 + * If you wish your version of this file to be governed by only the CDDL
114.31 + * or only the GPL Version 2, indicate your decision by adding
114.32 + * "[Contributor] elects to include this software in this distribution
114.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
114.34 + * single choice of license, a recipient has the option to distribute
114.35 + * your version of this file under either the CDDL, the GPL Version 2 or
114.36 + * to extend the choice of license to its licensees as provided above.
114.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
114.38 + * Version 2 license, then the option applies only if the new code is
114.39 + * made subject to such option by the copyright holder.
114.40 + *
114.41 + * Contributor(s):
114.42 + *
114.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
114.44 + */
114.45 +package org.netbeans.modules.python.hints;
114.46 +
114.47 +import java.util.Collections;
114.48 +import java.util.List;
114.49 +import java.util.Set;
114.50 +import java.util.prefs.Preferences;
114.51 +import javax.swing.JComponent;
114.52 +import org.netbeans.modules.csl.api.Hint;
114.53 +import org.netbeans.modules.csl.api.HintFix;
114.54 +import org.netbeans.modules.csl.api.HintSeverity;
114.55 +import org.netbeans.modules.csl.api.OffsetRange;
114.56 +import org.netbeans.modules.csl.api.RuleContext;
114.57 +import org.netbeans.modules.python.source.PythonAstUtils;
114.58 +import org.netbeans.modules.python.source.PythonParserResult;
114.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
114.60 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
114.61 +import org.netbeans.modules.python.source.scopes.SymbolTable;
114.62 +import org.netbeans.modules.python.source.scopes.SymInfo;
114.63 +import org.openide.util.NbBundle;
114.64 +import org.python.antlr.ast.Module;
114.65 +import org.python.antlr.ast.Str;
114.66 +
114.67 +/**
114.68 + *
114.69 + * @author Tor Norbye
114.70 + */
114.71 +public class AllAssignExists extends PythonAstRule {
114.72 + @Override
114.73 + public Set<Class> getKinds() {
114.74 + return Collections.<Class>singleton(Module.class);
114.75 + }
114.76 +
114.77 + @Override
114.78 + public void run(PythonRuleContext context, List<Hint> result) {
114.79 + PythonParserResult ppr = (PythonParserResult)context.parserResult;
114.80 + SymbolTable symbolTable = ppr.getSymbolTable();
114.81 + List<Str> publicSymbols = symbolTable.getPublicSymbols();
114.82 + if (publicSymbols != null) {
114.83 + // Check that we actually have all the symbols called for
114.84 + // by the all-list
114.85 +
114.86 + ScopeInfo topScope = symbolTable.getScopeInfo(context.node);
114.87 + assert topScope != null;
114.88 +
114.89 + // Mark all other symbols private!
114.90 + for (Str str : publicSymbols) {
114.91 + //String name = PythonAstUtils.getExprName(expr);
114.92 + String name = PythonAstUtils.getStrContent(str);
114.93 + if (name != null) {
114.94 + SymInfo sym = topScope.tbl.get(name);
114.95 + if (sym == null) {
114.96 + // Uh oh -- missing!
114.97 + PythonParserResult info = (PythonParserResult) context.parserResult;
114.98 + OffsetRange range = PythonAstUtils.getNameRange(info, str);
114.99 + range = PythonLexerUtils.getLexerOffsets(info, range);
114.100 + if (range != OffsetRange.NONE) {
114.101 + List<HintFix> fixList = Collections.emptyList();
114.102 + String message = NbBundle.getMessage(AllAssignExists.class, "AllAssignExistsMsg", name);
114.103 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 205);
114.104 + result.add(desc);
114.105 + }
114.106 + }
114.107 + }
114.108 + }
114.109 + }
114.110 + }
114.111 +
114.112 + @Override
114.113 + public String getId() {
114.114 + return "AllAssignExists"; // NOI18N
114.115 + }
114.116 +
114.117 + @Override
114.118 + public String getDescription() {
114.119 + return NbBundle.getMessage(AllAssignExists.class, "AllAssignExistsDesc");
114.120 + }
114.121 +
114.122 + @Override
114.123 + public boolean getDefaultEnabled() {
114.124 + return true;
114.125 + }
114.126 +
114.127 + @Override
114.128 + public JComponent getCustomizer(Preferences node) {
114.129 + return null;
114.130 + }
114.131 +
114.132 + @Override
114.133 + public boolean appliesTo(RuleContext context) {
114.134 + return true;
114.135 + }
114.136 +
114.137 + @Override
114.138 + public String getDisplayName() {
114.139 + return NbBundle.getMessage(AllAssignExists.class, "AllAssignExists");
114.140 + }
114.141 +
114.142 + @Override
114.143 + public boolean showInTasklist() {
114.144 + return true;
114.145 + }
114.146 +
114.147 + @Override
114.148 + public HintSeverity getDefaultSeverity() {
114.149 + return HintSeverity.ERROR;
114.150 + }
114.151 +}
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
115.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AssignToVariable.java Mon Sep 21 13:01:16 2015 +0200
115.3 @@ -0,0 +1,245 @@
115.4 +/*
115.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
115.6 + *
115.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
115.8 + *
115.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
115.10 + * Other names may be trademarks of their respective owners.
115.11 + *
115.12 + * The contents of this file are subject to the terms of either the GNU
115.13 + * General Public License Version 2 only ("GPL") or the Common
115.14 + * Development and Distribution License("CDDL") (collectively, the
115.15 + * "License"). You may not use this file except in compliance with the
115.16 + * License. You can obtain a copy of the License at
115.17 + * http://www.netbeans.org/cddl-gplv2.html
115.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
115.19 + * specific language governing permissions and limitations under the
115.20 + * License. When distributing the software, include this License Header
115.21 + * Notice in each file and include the License file at
115.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
115.23 + * particular file as subject to the "Classpath" exception as provided
115.24 + * by Oracle in the GPL Version 2 section of the License file that
115.25 + * accompanied this code. If applicable, add the following below the
115.26 + * License Header, with the fields enclosed by brackets [] replaced by
115.27 + * your own identifying information:
115.28 + * "Portions Copyrighted [year] [name of copyright owner]"
115.29 + *
115.30 + * If you wish your version of this file to be governed by only the CDDL
115.31 + * or only the GPL Version 2, indicate your decision by adding
115.32 + * "[Contributor] elects to include this software in this distribution
115.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
115.34 + * single choice of license, a recipient has the option to distribute
115.35 + * your version of this file under either the CDDL, the GPL Version 2 or
115.36 + * to extend the choice of license to its licensees as provided above.
115.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
115.38 + * Version 2 license, then the option applies only if the new code is
115.39 + * made subject to such option by the copyright holder.
115.40 + *
115.41 + * Contributor(s):
115.42 + *
115.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
115.44 + */
115.45 +package org.netbeans.modules.python.hints;
115.46 +
115.47 +import java.util.ArrayList;
115.48 +import java.util.Collections;
115.49 +import java.util.List;
115.50 +import java.util.Set;
115.51 +import java.util.prefs.Preferences;
115.52 +import javax.swing.JComponent;
115.53 +import javax.swing.text.BadLocationException;
115.54 +import javax.swing.text.JTextComponent;
115.55 +import javax.swing.text.Position;
115.56 +import org.netbeans.modules.python.source.PythonAstUtils;
115.57 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
115.58 +import org.netbeans.editor.BaseDocument;
115.59 +import org.netbeans.editor.Utilities;
115.60 +import org.netbeans.modules.csl.api.EditList;
115.61 +import org.netbeans.modules.csl.api.Hint;
115.62 +import org.netbeans.modules.csl.api.HintFix;
115.63 +import org.netbeans.modules.csl.api.HintSeverity;
115.64 +import org.netbeans.modules.csl.api.OffsetRange;
115.65 +import org.netbeans.modules.csl.api.PreviewableFix;
115.66 +import org.netbeans.modules.csl.api.RuleContext;
115.67 +import org.netbeans.modules.csl.spi.GsfUtilities;
115.68 +import org.netbeans.modules.python.source.PythonParserResult;
115.69 +import org.openide.util.Exceptions;
115.70 +import org.openide.util.NbBundle;
115.71 +import org.python.antlr.PythonTree;
115.72 +import org.python.antlr.ast.Call;
115.73 +import org.python.antlr.ast.Expr;
115.74 +import org.python.antlr.ast.FunctionDef;
115.75 +import org.python.antlr.ast.Str;
115.76 +import org.python.antlr.base.expr;
115.77 +import org.python.antlr.base.stmt;
115.78 +
115.79 +/**
115.80 + * Assign an expression to a variable
115.81 + *
115.82 + * @author Tor Norbye
115.83 + */
115.84 +public class AssignToVariable extends PythonAstRule {
115.85 + @Override
115.86 + public Set<Class> getKinds() {
115.87 + return Collections.singleton((Class)Expr.class);
115.88 + }
115.89 +
115.90 + @Override
115.91 + public void run(PythonRuleContext context, List<Hint> result) {
115.92 + PythonTree node = context.node;
115.93 + Expr expr = (Expr)node;
115.94 + expr exprValue = expr.getInternalValue();
115.95 + if (exprValue instanceof Str) {
115.96 + // Skip triple-quoted strings (typically doc strings)
115.97 + Str str = (Str)exprValue;
115.98 + String s = str.getText();
115.99 + if (s.startsWith("'''") || s.startsWith("\"\"\"")) { // NOI18N
115.100 + return;
115.101 + }
115.102 + PythonTree grandParent = context.path.leafGrandParent();
115.103 + if (grandParent instanceof FunctionDef) {
115.104 + FunctionDef def = (FunctionDef)grandParent;
115.105 + List<stmt> body = def.getInternalBody();
115.106 + if (body != null && body.size() > 0 && body.get(0) == expr) {
115.107 + // First string in a function -- it's a docstring
115.108 + return;
115.109 + }
115.110 + }
115.111 + }
115.112 + if (exprValue instanceof Call) {
115.113 + // Skip calls - they may have side effects
115.114 + // ...unless it looks like a "getter" style Python method
115.115 + Call call = (Call)exprValue;
115.116 + if (!PythonAstUtils.isGetter(call, false)) {
115.117 + return;
115.118 + }
115.119 + }
115.120 + PythonParserResult info = (PythonParserResult) context.parserResult;
115.121 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
115.122 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
115.123 + BaseDocument doc = context.doc;
115.124 + try {
115.125 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
115.126 + (context.caretOffset == -1 ||
115.127 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
115.128 + List<HintFix> fixList = new ArrayList<>();
115.129 + fixList.add(new AssignToVariableFix(context, node));
115.130 + String displayName = getDisplayName();
115.131 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
115.132 + result.add(desc);
115.133 + }
115.134 + } catch (BadLocationException ex) {
115.135 + Exceptions.printStackTrace(ex);
115.136 + }
115.137 + }
115.138 +
115.139 + @Override
115.140 + public String getId() {
115.141 + return "AssignToVariable"; // NOI18N
115.142 + }
115.143 +
115.144 + @Override
115.145 + public String getDisplayName() {
115.146 + return NbBundle.getMessage(AssignToVariable.class, "AssignToVariable");
115.147 + }
115.148 +
115.149 + @Override
115.150 + public String getDescription() {
115.151 + return NbBundle.getMessage(AssignToVariable.class, "AssignToVariableDesc");
115.152 + }
115.153 +
115.154 + @Override
115.155 + public boolean getDefaultEnabled() {
115.156 + return true;
115.157 + }
115.158 +
115.159 + @Override
115.160 + public JComponent getCustomizer(Preferences node) {
115.161 + return null;
115.162 + }
115.163 +
115.164 + @Override
115.165 + public boolean appliesTo(RuleContext context) {
115.166 + return true;
115.167 + }
115.168 +
115.169 + @Override
115.170 + public boolean showInTasklist() {
115.171 + return false;
115.172 + }
115.173 +
115.174 + @Override
115.175 + public HintSeverity getDefaultSeverity() {
115.176 + return HintSeverity.CURRENT_LINE_WARNING;
115.177 + }
115.178 +
115.179 + private static class AssignToVariableFix implements PreviewableFix {
115.180 + private final PythonRuleContext context;
115.181 + private final PythonTree node;
115.182 + private int varOffset;
115.183 + private String varName;
115.184 +
115.185 + private AssignToVariableFix(PythonRuleContext context, PythonTree node) {
115.186 + this.context = context;
115.187 + this.node = node;
115.188 + }
115.189 +
115.190 + @Override
115.191 + public String getDescription() {
115.192 + return NbBundle.getMessage(AssignToVariable.class, "AssignToVariableFix");
115.193 + }
115.194 +
115.195 + @Override
115.196 + public boolean canPreview() {
115.197 + return true;
115.198 + }
115.199 +
115.200 + @Override
115.201 + public EditList getEditList() throws Exception {
115.202 + BaseDocument doc = context.doc;
115.203 + EditList edits = new EditList(doc);
115.204 +
115.205 + OffsetRange astRange = PythonAstUtils.getRange(node);
115.206 + if (astRange != OffsetRange.NONE) {
115.207 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
115.208 + if (lexRange != OffsetRange.NONE) {
115.209 + int offset = lexRange.getStart();
115.210 + StringBuilder sb = new StringBuilder();
115.211 + varName = NbBundle.getMessage(AssignToVariable.class, "VarName");
115.212 + sb.append(varName);
115.213 + sb.append(" = "); // NOI18N
115.214 + varOffset = offset;
115.215 + edits.replace(offset, 0, sb.toString(), false, 0);
115.216 + }
115.217 + }
115.218 +
115.219 + return edits;
115.220 + }
115.221 +
115.222 + @Override
115.223 + public void implement() throws Exception {
115.224 + EditList edits = getEditList();
115.225 +
115.226 + Position pos = edits.createPosition(varOffset);
115.227 + edits.apply();
115.228 + if (pos != null && pos.getOffset() != -1) {
115.229 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
115.230 + if (target != null) {
115.231 + int start = pos.getOffset();
115.232 + int end = start + varName.length();
115.233 + target.select(start, end);
115.234 + }
115.235 + }
115.236 + }
115.237 +
115.238 + @Override
115.239 + public boolean isSafe() {
115.240 + return true;
115.241 + }
115.242 +
115.243 + @Override
115.244 + public boolean isInteractive() {
115.245 + return false;
115.246 + }
115.247 + }
115.248 +}
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
116.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AttributeDefinedOutsideInit.java Mon Sep 21 13:01:16 2015 +0200
116.3 @@ -0,0 +1,140 @@
116.4 +/*
116.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
116.6 + *
116.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
116.8 + *
116.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
116.10 + * Other names may be trademarks of their respective owners.
116.11 + *
116.12 + * The contents of this file are subject to the terms of either the GNU
116.13 + * General Public License Version 2 only ("GPL") or the Common
116.14 + * Development and Distribution License("CDDL") (collectively, the
116.15 + * "License"). You may not use this file except in compliance with the
116.16 + * License. You can obtain a copy of the License at
116.17 + * http://www.netbeans.org/cddl-gplv2.html
116.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
116.19 + * specific language governing permissions and limitations under the
116.20 + * License. When distributing the software, include this License Header
116.21 + * Notice in each file and include the License file at
116.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
116.23 + * particular file as subject to the "Classpath" exception as provided
116.24 + * by Oracle in the GPL Version 2 section of the License file that
116.25 + * accompanied this code. If applicable, add the following below the
116.26 + * License Header, with the fields enclosed by brackets [] replaced by
116.27 + * your own identifying information:
116.28 + * "Portions Copyrighted [year] [name of copyright owner]"
116.29 + *
116.30 + * If you wish your version of this file to be governed by only the CDDL
116.31 + * or only the GPL Version 2, indicate your decision by adding
116.32 + * "[Contributor] elects to include this software in this distribution
116.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
116.34 + * single choice of license, a recipient has the option to distribute
116.35 + * your version of this file under either the CDDL, the GPL Version 2 or
116.36 + * to extend the choice of license to its licensees as provided above.
116.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
116.38 + * Version 2 license, then the option applies only if the new code is
116.39 + * made subject to such option by the copyright holder.
116.40 + *
116.41 + * Contributor(s):
116.42 + *
116.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
116.44 + */
116.45 +package org.netbeans.modules.python.hints;
116.46 +
116.47 +import java.util.Collections;
116.48 +import java.util.List;
116.49 +import java.util.Set;
116.50 +import java.util.prefs.Preferences;
116.51 +import javax.swing.JComponent;
116.52 +import org.netbeans.modules.csl.api.Hint;
116.53 +import org.netbeans.modules.csl.api.HintFix;
116.54 +import org.netbeans.modules.csl.api.HintSeverity;
116.55 +import org.netbeans.modules.csl.api.OffsetRange;
116.56 +import org.netbeans.modules.csl.api.RuleContext;
116.57 +import org.netbeans.modules.python.source.PythonAstUtils;
116.58 +import org.netbeans.modules.python.source.PythonParserResult;
116.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
116.60 +import org.netbeans.modules.python.source.scopes.SymbolTable;
116.61 +import org.openide.util.NbBundle;
116.62 +import org.python.antlr.ast.Attribute;
116.63 +import org.python.antlr.ast.Module;
116.64 +
116.65 +/**
116.66 + *
116.67 + * @author Jean-Yves Mengant
116.68 + */
116.69 +public class AttributeDefinedOutsideInit extends PythonAstRule {
116.70 + private final static String ATTRIBUTE_DEFINED_OUTSIDE_INIT = "AttributeDefinedOutsideInit";
116.71 + private final static String ATTRIBUTE_DEFINED_OUTSITE_INIT_VAR = "AttributeDefinedOutsideInitVariable";
116.72 + private final static String ATTRIBUTE_DEFINED_OUTSIDE_INIT_DESC = "AttributeDefinedOutsideInitDesc";
116.73 +
116.74 + @Override
116.75 + public Set<Class> getKinds() {
116.76 + return Collections.<Class>singleton(Module.class);
116.77 + }
116.78 +
116.79 + @Override
116.80 + public void run(PythonRuleContext context, List<Hint> result) {
116.81 + PythonParserResult info = (PythonParserResult) context.parserResult;
116.82 + PythonParserResult pr = PythonAstUtils.getParseResult(info);
116.83 + SymbolTable symbolTable = pr.getSymbolTable();
116.84 +
116.85 +
116.86 + List<Attribute> notInIntBound = symbolTable.getNotInInitAttributes(info);
116.87 + if (notInIntBound.size() > 0) {
116.88 + for (Attribute cur : notInIntBound) {
116.89 + OffsetRange range = PythonAstUtils.getRange(cur);
116.90 + range = PythonLexerUtils.getLexerOffsets(info, range);
116.91 + if (range != OffsetRange.NONE) {
116.92 + List<HintFix> fixList = Collections.emptyList();
116.93 + String message = NbBundle.getMessage(NameRule.class,
116.94 + ATTRIBUTE_DEFINED_OUTSITE_INIT_VAR,
116.95 + cur.getInternalAttr());
116.96 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
116.97 + result.add(desc);
116.98 + }
116.99 + }
116.100 + }
116.101 +
116.102 + }
116.103 +
116.104 + @Override
116.105 + public String getId() {
116.106 + return ATTRIBUTE_DEFINED_OUTSIDE_INIT;
116.107 + }
116.108 +
116.109 + @Override
116.110 + public String getDescription() {
116.111 + return NbBundle.getMessage(RelativeImports.class, ATTRIBUTE_DEFINED_OUTSIDE_INIT_DESC);
116.112 + }
116.113 +
116.114 + @Override
116.115 + public boolean getDefaultEnabled() {
116.116 + return false;
116.117 + }
116.118 +
116.119 + @Override
116.120 + public JComponent getCustomizer(Preferences node) {
116.121 + return null;
116.122 + }
116.123 +
116.124 + @Override
116.125 + public boolean appliesTo(RuleContext context) {
116.126 + return true;
116.127 + }
116.128 +
116.129 + @Override
116.130 + public String getDisplayName() {
116.131 + return NbBundle.getMessage(AccessToProtected.class, ATTRIBUTE_DEFINED_OUTSIDE_INIT);
116.132 + }
116.133 +
116.134 + @Override
116.135 + public boolean showInTasklist() {
116.136 + return true;
116.137 + }
116.138 +
116.139 + @Override
116.140 + public HintSeverity getDefaultSeverity() {
116.141 + return HintSeverity.WARNING;
116.142 + }
116.143 +}
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
117.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/Bundle.properties Mon Sep 21 13:01:16 2015 +0200
117.3 @@ -0,0 +1,147 @@
117.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
117.5 +#
117.6 +# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
117.7 +#
117.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
117.9 +# Other names may be trademarks of their respective owners.
117.10 +#
117.11 +# The contents of this file are subject to the terms of either the GNU
117.12 +# General Public License Version 2 only ("GPL") or the Common
117.13 +# Development and Distribution License("CDDL") (collectively, the
117.14 +# "License"). You may not use this file except in compliance with the
117.15 +# License. You can obtain a copy of the License at
117.16 +# http://www.netbeans.org/cddl-gplv2.html
117.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
117.18 +# specific language governing permissions and limitations under the
117.19 +# License. When distributing the software, include this License Header
117.20 +# Notice in each file and include the License file at
117.21 +# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
117.22 +# particular file as subject to the "Classpath" exception as provided
117.23 +# by Oracle in the GPL Version 2 section of the License file that
117.24 +# accompanied this code. If applicable, add the following below the
117.25 +# License Header, with the fields enclosed by brackets [] replaced by
117.26 +# your own identifying information:
117.27 +# "Portions Copyrighted [year] [name of copyright owner]"
117.28 +#
117.29 +# Contributor(s):
117.30 +#
117.31 +# The Original Software is NetBeans. The Initial Developer of the Original
117.32 +# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
117.33 +# Microsystems, Inc. All Rights Reserved.
117.34 +#
117.35 +# If you wish your version of this file to be governed by only the CDDL
117.36 +# or only the GPL Version 2, indicate your decision by adding
117.37 +# "[Contributor] elects to include this software in this distribution
117.38 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
117.39 +# single choice of license, a recipient has the option to distribute
117.40 +# your version of this file under either the CDDL, the GPL Version 2 or
117.41 +# to extend the choice of license to its licensees as provided above.
117.42 +# However, if you add GPL Version 2 code and therefore, elected the GPL
117.43 +# Version 2 license, then the option applies only if the new code is
117.44 +# made subject to such option by the copyright holder.
117.45 +
117.46 +# Category descriptions in the Options Panel
117.47 +gsf-hints/text/x-python/hints/general=General
117.48 +
117.49 +# NameRule
117.50 +NameRule=Naming Conventions
117.51 +NameRuleDesc=Check class, function and variable names for style guide compliance (see http://www.python.org/dev/peps/pep-0008/ for rules)
117.52 +NameRuleWrongNoArg=First argument should be 'self' or 'cls'
117.53 +NameRuleWrongArg=First argument ({0}) should be 'self' or 'cls'
117.54 +WrongStyle=Name "{0}" is not a valid {1} name according to your code style ({2})
117.55 +Module=module
117.56 +Function=function
117.57 +Class=class
117.58 +Variable=variable
117.59 +ChangeStyle=Change preferred {0} name style to {1}
117.60 +ChangeNoStyle=Turn off {0} name style checks
117.61 +IgnoreWord=Ignore name violations for "{0}"
117.62 +NameRulePrefs.selfCb.text=First method params should be "self" or "cls"
117.63 +NameRulePrefs.moduleLabel.text=Modules:
117.64 +NameRulePrefs.classLabel.text=Classes:
117.65 +NameRulePrefs.functionLabel.text=Functions:
117.66 +NameRulePrefs.parameterLabel.text=Parameters:
117.67 +NameRulePrefs.variableLabel.text=Variables:
117.68 +NameRulePrefs.ignoreLabel.text=Ignored:
117.69 +
117.70 +CreateDocString=Create document comment
117.71 +CreateDocStringDesc=Offer to create a documentation comment for the current function, class or module
117.72 +CreateDocStringFix=Add a one-liner docstring
117.73 +CreateDocStringFixMulti=Add a multi-line docstring
117.74 +
117.75 +AssignToVariable=Assign expression to a variable
117.76 +AssignToVariableDesc=Assign expression under the caret to a variable
117.77 +AssignToVariableFix=Assign expression to a variable
117.78 +VarName=name
117.79 +
117.80 +SplitImports=Multiple imports per import statement is discouraged
117.81 +SplitImportsDesc=Split an import which imports multiple modules into individual import statements as recommended by the Python styleguide
117.82 +SplitImportsFix=Split import into individual import statements
117.83 +
117.84 +RelativeImports=Relative imports for intra-package imports are actively discouraged (as per PEP-008)
117.85 +RelativeImportsDesc=Relative imports for intra-package imports are actively discouraged (as per PEP-008) and this rule warns about usages of relative imports
117.86 +RelativeImportsFix=Replace with absolute import
117.87 +
117.88 +Deprecations=Deprecated
117.89 +DeprecationsMsg={0} is deprecated
117.90 +DeprecationsMsgDetail={0} is deprecated. {1}
117.91 +DeprecationsDesc=Check for deprecated modules
117.92 +
117.93 +SurroundWith=Surround With...
117.94 +#SurroundWithDesc=Offer to surround selected code with try/catch, etc
117.95 +SurroundWithTE=Surround With Try/Except
117.96 +SurroundWithTEF=Surround With Try/Except/Finally
117.97 +SurroundWithTF=Surround With Try/Finally
117.98 +InsertSelf=Insert a new first parameter "self"
117.99 +RenameSelf=Rename first parameter "{0}" to self
117.100 +
117.101 +ExtractCode=Extract Code
117.102 +IntroduceMethod=Extract Method
117.103 +IntroduceVariable=Introduce Variable
117.104 +IntroduceConstant=Introduce Constant
117.105 +IntroduceField=Introduce Field
117.106 +
117.107 +UnusedImport=Unused Import
117.108 +UnusedImportSymbols=Some symbols are unused ({0})
117.109 +UnusedImports=Find Unused Imports
117.110 +UnusedImportsDesc=Find imports that aren't used in this module and can be removed
117.111 +UnusedFix=Remove Unused Import
117.112 +UnusedFixSymbols=Remove {0} from import
117.113 +OrganizeImports=Clean up and Organize Imports
117.114 +DeleteAllUnused=Remove All Unused Imports
117.115 +
117.116 +Unused=Find Unused Variables
117.117 +UnusedDesc=Find variables that are defined but never used
117.118 +UnusedVariable=Unused Variable {0}
117.119 +
117.120 +Unresolved=Find Undefined Names
117.121 +UnresolvedDesc=Find names that are used but have not been bound
117.122 +UnresolvedVariable=Undefined name "{0}"
117.123 +UnresolvedVariableMaybe=Undefined name "{0}" - did you mean "{1}" ?
117.124 +FixImport=Import {0}
117.125 +
117.126 +UnresolvedAttributes=Find Unresolved classes attributes and parentages
117.127 +UnresolvedAttributesDesc=Find class attributes that are used but have not been bound and undefined inherited classes
117.128 +UnresolvedAttributesVariable=Undefined attribute "{0}"
117.129 +UnresolvedInheritanceVariable=Inheriting from undefined parent class "{0}"
117.130 +
117.131 +AccessProtected=Access Protected Attributes
117.132 +AccessProtectedDesc=Find access to protected variables/methods of non parent classes
117.133 +AccessProtectedVariable=Access to protected variable "{0}"
117.134 +
117.135 +AttributeDefinedOutsideInit=Attribute Defined Outside __init__
117.136 +AttributeDefinedOutsideInitDesc=Class Attribute defined outside __init__ constructor
117.137 +AttributeDefinedOutsideInitVariable=Attribute Defined Outside __init__ "{0}"
117.138 +
117.139 +ClassCircularRedundancy=Parent Child circular redundancy
117.140 +ClassCircularRedundancyDesc=Parent Child circular redundancy = A inherits B and B inherits A
117.141 +ClassCircularRedundancyVariable=Parent/child {0} inheritance circular redundancy
117.142 +
117.143 +AllAssignExists=Symbol defined in __all__ does not exist
117.144 +AllAssignExistsDesc=Checks that all symbols listed in __all__ actually exist
117.145 +AllAssignExistsMsg="{0}" defined in __all__ does not exist!
117.146 +UnusedDetectorPrefs.skipParams.text=Ignore unused function parameters
117.147 +UnusedDetectorPrefs.ignoredLabel.text=Ignored names:
117.148 +UnusedDetectorPrefs.skipTupleAssignments.text=Ignore unused variables in tuple-assignments
117.149 +
117.150 +OpenIDE-Module-Name=Python Hints
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/ClassCircularRedundancy.java Mon Sep 21 13:01:16 2015 +0200
118.3 @@ -0,0 +1,140 @@
118.4 +/*
118.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
118.6 + *
118.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
118.8 + *
118.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
118.10 + * Other names may be trademarks of their respective owners.
118.11 + *
118.12 + * The contents of this file are subject to the terms of either the GNU
118.13 + * General Public License Version 2 only ("GPL") or the Common
118.14 + * Development and Distribution License("CDDL") (collectively, the
118.15 + * "License"). You may not use this file except in compliance with the
118.16 + * License. You can obtain a copy of the License at
118.17 + * http://www.netbeans.org/cddl-gplv2.html
118.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
118.19 + * specific language governing permissions and limitations under the
118.20 + * License. When distributing the software, include this License Header
118.21 + * Notice in each file and include the License file at
118.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
118.23 + * particular file as subject to the "Classpath" exception as provided
118.24 + * by Oracle in the GPL Version 2 section of the License file that
118.25 + * accompanied this code. If applicable, add the following below the
118.26 + * License Header, with the fields enclosed by brackets [] replaced by
118.27 + * your own identifying information:
118.28 + * "Portions Copyrighted [year] [name of copyright owner]"
118.29 + *
118.30 + * If you wish your version of this file to be governed by only the CDDL
118.31 + * or only the GPL Version 2, indicate your decision by adding
118.32 + * "[Contributor] elects to include this software in this distribution
118.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
118.34 + * single choice of license, a recipient has the option to distribute
118.35 + * your version of this file under either the CDDL, the GPL Version 2 or
118.36 + * to extend the choice of license to its licensees as provided above.
118.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
118.38 + * Version 2 license, then the option applies only if the new code is
118.39 + * made subject to such option by the copyright holder.
118.40 + *
118.41 + * Contributor(s):
118.42 + *
118.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
118.44 + */
118.45 +package org.netbeans.modules.python.hints;
118.46 +
118.47 +import java.util.Collections;
118.48 +import java.util.HashMap;
118.49 +import java.util.List;
118.50 +import java.util.Map.Entry;
118.51 +import java.util.Set;
118.52 +import java.util.prefs.Preferences;
118.53 +import javax.swing.JComponent;
118.54 +import org.netbeans.modules.csl.api.Hint;
118.55 +import org.netbeans.modules.csl.api.HintFix;
118.56 +import org.netbeans.modules.csl.api.HintSeverity;
118.57 +import org.netbeans.modules.csl.api.OffsetRange;
118.58 +import org.netbeans.modules.csl.api.RuleContext;
118.59 +import org.netbeans.modules.python.source.PythonAstUtils;
118.60 +import org.netbeans.modules.python.source.PythonParserResult;
118.61 +import org.netbeans.modules.python.source.scopes.SymbolTable;
118.62 +import org.openide.util.NbBundle;
118.63 +import org.python.antlr.ast.ClassDef;
118.64 +import org.python.antlr.ast.Module;
118.65 +
118.66 +/**
118.67 + * check for redundancy cycling in parent child
118.68 + * @author Jean-Yves Mengant
118.69 + */
118.70 +public class ClassCircularRedundancy extends PythonAstRule {
118.71 + private final static String CLASS_CIRCULAR_REDUNDANCY = "ClassCircularRedundancy";
118.72 + private final static String CLASS_CIRCULAR_REDUNDANCY_VAR = "ClassCircularRedundancyVariable";
118.73 + private final static String CLASS_CIRCULAR_REDUNDANCY_DESC = "ClassCircularRedundancyDesc";
118.74 +
118.75 + @Override
118.76 + public Set<Class> getKinds() {
118.77 + return Collections.<Class>singleton(Module.class);
118.78 + }
118.79 +
118.80 + @Override
118.81 + public void run(PythonRuleContext context, List<Hint> result) {
118.82 + PythonParserResult info = (PythonParserResult) context.parserResult;
118.83 + SymbolTable symbolTable = info.getSymbolTable();
118.84 +
118.85 +
118.86 + HashMap<ClassDef, String> cyclingRedundancies = symbolTable.getClassesCyclingRedundancies(info);
118.87 + if (cyclingRedundancies.size() > 0) {
118.88 + Set<Entry<ClassDef, String>> wk = cyclingRedundancies.entrySet();
118.89 + for (Entry<ClassDef, String> cur : wk) {
118.90 + ClassDef curClass = cur.getKey();
118.91 + String curCyclingMsg = curClass.getInternalName() + "/" + cur.getValue(); // NOI18N
118.92 + OffsetRange range = PythonAstUtils.getNameRange(info, curClass);
118.93 + // range = PythonLexerUtils.getLexerOffsets(info, range);
118.94 + if (range != OffsetRange.NONE) {
118.95 + List<HintFix> fixList = Collections.emptyList();
118.96 + String message = NbBundle.getMessage(NameRule.class, CLASS_CIRCULAR_REDUNDANCY_VAR, curCyclingMsg);
118.97 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
118.98 + result.add(desc);
118.99 + }
118.100 + }
118.101 + }
118.102 + }
118.103 +
118.104 + @Override
118.105 + public String getId() {
118.106 + return CLASS_CIRCULAR_REDUNDANCY;
118.107 + }
118.108 +
118.109 + @Override
118.110 + public String getDescription() {
118.111 + return NbBundle.getMessage(RelativeImports.class, CLASS_CIRCULAR_REDUNDANCY_DESC);
118.112 + }
118.113 +
118.114 + @Override
118.115 + public boolean getDefaultEnabled() {
118.116 + return false;
118.117 + }
118.118 +
118.119 + @Override
118.120 + public JComponent getCustomizer(Preferences node) {
118.121 + return null;
118.122 + }
118.123 +
118.124 + @Override
118.125 + public boolean appliesTo(RuleContext context) {
118.126 + return true;
118.127 + }
118.128 +
118.129 + @Override
118.130 + public String getDisplayName() {
118.131 + return NbBundle.getMessage(AccessToProtected.class, CLASS_CIRCULAR_REDUNDANCY);
118.132 + }
118.133 +
118.134 + @Override
118.135 + public boolean showInTasklist() {
118.136 + return true;
118.137 + }
118.138 +
118.139 + @Override
118.140 + public HintSeverity getDefaultSeverity() {
118.141 + return HintSeverity.ERROR;
118.142 + }
118.143 +}
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
119.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/CreateDocString.java Mon Sep 21 13:01:16 2015 +0200
119.3 @@ -0,0 +1,241 @@
119.4 +/*
119.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
119.6 + *
119.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
119.8 + *
119.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
119.10 + * Other names may be trademarks of their respective owners.
119.11 + *
119.12 + * The contents of this file are subject to the terms of either the GNU
119.13 + * General Public License Version 2 only ("GPL") or the Common
119.14 + * Development and Distribution License("CDDL") (collectively, the
119.15 + * "License"). You may not use this file except in compliance with the
119.16 + * License. You can obtain a copy of the License at
119.17 + * http://www.netbeans.org/cddl-gplv2.html
119.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
119.19 + * specific language governing permissions and limitations under the
119.20 + * License. When distributing the software, include this License Header
119.21 + * Notice in each file and include the License file at
119.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
119.23 + * particular file as subject to the "Classpath" exception as provided
119.24 + * by Oracle in the GPL Version 2 section of the License file that
119.25 + * accompanied this code. If applicable, add the following below the
119.26 + * License Header, with the fields enclosed by brackets [] replaced by
119.27 + * your own identifying information:
119.28 + * "Portions Copyrighted [year] [name of copyright owner]"
119.29 + *
119.30 + * Contributor(s):
119.31 + *
119.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
119.33 + */
119.34 +package org.netbeans.modules.python.hints;
119.35 +
119.36 +import java.util.ArrayList;
119.37 +import java.util.Collections;
119.38 +import java.util.HashSet;
119.39 +import java.util.List;
119.40 +import java.util.Set;
119.41 +import java.util.prefs.Preferences;
119.42 +import javax.swing.JComponent;
119.43 +import javax.swing.text.BadLocationException;
119.44 +import javax.swing.text.JTextComponent;
119.45 +import javax.swing.text.Position;
119.46 +import org.netbeans.modules.python.source.PythonAstUtils;
119.47 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
119.48 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
119.49 +import org.netbeans.api.lexer.Token;
119.50 +import org.netbeans.api.lexer.TokenSequence;
119.51 +import org.netbeans.editor.BaseDocument;
119.52 +import org.netbeans.editor.Utilities;
119.53 +import org.netbeans.modules.csl.api.EditList;
119.54 +import org.netbeans.modules.csl.api.Hint;
119.55 +import org.netbeans.modules.csl.api.HintFix;
119.56 +import org.netbeans.modules.csl.api.HintSeverity;
119.57 +import org.netbeans.modules.csl.api.OffsetRange;
119.58 +import org.netbeans.modules.csl.api.PreviewableFix;
119.59 +import org.netbeans.modules.csl.api.RuleContext;
119.60 +import org.netbeans.modules.csl.spi.GsfUtilities;
119.61 +import org.netbeans.modules.editor.indent.api.IndentUtils;
119.62 +import org.netbeans.modules.python.source.PythonParserResult;
119.63 +import org.openide.util.Exceptions;
119.64 +import org.openide.util.NbBundle;
119.65 +import org.python.antlr.PythonTree;
119.66 +import org.python.antlr.ast.ClassDef;
119.67 +import org.python.antlr.ast.FunctionDef;
119.68 +
119.69 +/**
119.70 + * Offer to create docstrings.
119.71 + * @todo Handle modules?
119.72 + * @todo Handle parameter tags (for epydoc etc)
119.73 + *
119.74 + * @author Tor Norbye
119.75 + */
119.76 +public class CreateDocString extends PythonAstRule {
119.77 + @Override
119.78 + public Set<Class> getKinds() {
119.79 + Set<Class> classes = new HashSet<>();
119.80 + classes.add(FunctionDef.class);
119.81 + classes.add(ClassDef.class);
119.82 +
119.83 + return classes;
119.84 + }
119.85 +
119.86 + @Override
119.87 + public void run(PythonRuleContext context, List<Hint> result) {
119.88 +
119.89 + PythonTree node = context.node;
119.90 + if (PythonAstUtils.getDocumentationNode(node) != null) {
119.91 + return;
119.92 + }
119.93 +
119.94 + // Create new fix
119.95 + PythonParserResult info = (PythonParserResult) context.parserResult;
119.96 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
119.97 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
119.98 + BaseDocument doc = context.doc;
119.99 + try {
119.100 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
119.101 + (context.caretOffset == -1 ||
119.102 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
119.103 + List<HintFix> fixList = new ArrayList<>();
119.104 + boolean singleIsDefault = node.getClass() == FunctionDef.class;
119.105 + fixList.add(new CreateDocStringFix(context, node, !singleIsDefault));
119.106 + fixList.add(new CreateDocStringFix(context, node, singleIsDefault));
119.107 + String displayName = getDisplayName();
119.108 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
119.109 + result.add(desc);
119.110 + }
119.111 + } catch (BadLocationException ex) {
119.112 + Exceptions.printStackTrace(ex);
119.113 + }
119.114 + }
119.115 +
119.116 + @Override
119.117 + public String getId() {
119.118 + return "CreateDocString"; // NOI18N
119.119 + }
119.120 +
119.121 + @Override
119.122 + public String getDisplayName() {
119.123 + return NbBundle.getMessage(CreateDocString.class, "CreateDocString");
119.124 + }
119.125 +
119.126 + @Override
119.127 + public String getDescription() {
119.128 + return NbBundle.getMessage(CreateDocString.class, "CreateDocStringDesc");
119.129 + }
119.130 +
119.131 + @Override
119.132 + public boolean getDefaultEnabled() {
119.133 + return true;
119.134 + }
119.135 +
119.136 + @Override
119.137 + public JComponent getCustomizer(Preferences node) {
119.138 + return null;
119.139 + }
119.140 +
119.141 + @Override
119.142 + public boolean appliesTo(RuleContext context) {
119.143 + return true;
119.144 + }
119.145 +
119.146 + @Override
119.147 + public boolean showInTasklist() {
119.148 + return false;
119.149 + }
119.150 +
119.151 + @Override
119.152 + public HintSeverity getDefaultSeverity() {
119.153 + return HintSeverity.CURRENT_LINE_WARNING;
119.154 + }
119.155 +
119.156 + private static class CreateDocStringFix implements PreviewableFix {
119.157 + private final PythonRuleContext context;
119.158 + private final PythonTree node;
119.159 + private final boolean multiLine;
119.160 + private int editListPosition;
119.161 +
119.162 + private CreateDocStringFix(PythonRuleContext context, PythonTree node, boolean multiLine) {
119.163 + this.context = context;
119.164 + this.node = node;
119.165 + this.multiLine = multiLine;
119.166 + }
119.167 +
119.168 + @Override
119.169 + public String getDescription() {
119.170 + return multiLine ? NbBundle.getMessage(CreateDocString.class, "CreateDocStringFixMulti") : NbBundle.getMessage(CreateDocString.class, "CreateDocStringFix");
119.171 + }
119.172 +
119.173 + @Override
119.174 + public boolean canPreview() {
119.175 + return true;
119.176 + }
119.177 +
119.178 + @Override
119.179 + public EditList getEditList() throws Exception {
119.180 + BaseDocument doc = context.doc;
119.181 + EditList edits = new EditList(doc);
119.182 +
119.183 + OffsetRange astRange = PythonAstUtils.getRange(node);
119.184 + if (astRange != OffsetRange.NONE) {
119.185 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
119.186 + if (lexRange != OffsetRange.NONE) {
119.187 + // Find the colon
119.188 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPositionedSequence(doc, lexRange.getStart());
119.189 + if (ts != null) {
119.190 + Token<? extends PythonTokenId> token = PythonLexerUtils.findNextIncluding(ts, Collections.singletonList(PythonTokenId.COLON));
119.191 + if (token != null) {
119.192 + int offset = ts.offset();
119.193 + if (offset < lexRange.getEnd()) {
119.194 + int indent = GsfUtilities.getLineIndent(doc, lexRange.getStart()) +
119.195 + IndentUtils.indentLevelSize(doc);
119.196 + StringBuilder sb = new StringBuilder();
119.197 + sb.append(IndentUtils.createIndentString(doc, indent));
119.198 + int rowEnd = Utilities.getRowEnd(doc, offset) + 1;
119.199 + sb.append("\"\"\""); // NOI18N
119.200 + if (multiLine) {
119.201 + sb.append("\n"); // NOI18N
119.202 + sb.append(IndentUtils.createIndentString(doc, indent));
119.203 + }
119.204 + editListPosition = rowEnd + sb.length();
119.205 + if (multiLine) {
119.206 + sb.append("\n"); // NOI18N
119.207 + sb.append(IndentUtils.createIndentString(doc, indent));
119.208 + }
119.209 + sb.append("\"\"\"\n"); // NOI18N
119.210 + edits.replace(rowEnd, 0, sb.toString(), false, 0);
119.211 + }
119.212 + }
119.213 + }
119.214 + }
119.215 + }
119.216 +
119.217 + return edits;
119.218 + }
119.219 +
119.220 + @Override
119.221 + public void implement() throws Exception {
119.222 + EditList edits = getEditList();
119.223 +
119.224 + Position pos = edits.createPosition(editListPosition);
119.225 + edits.apply();
119.226 + if (pos != null && pos.getOffset() != -1) {
119.227 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
119.228 + if (target != null) {
119.229 + target.setCaretPosition(pos.getOffset());
119.230 + }
119.231 + }
119.232 + }
119.233 +
119.234 + @Override
119.235 + public boolean isSafe() {
119.236 + return true;
119.237 + }
119.238 +
119.239 + @Override
119.240 + public boolean isInteractive() {
119.241 + return false;
119.242 + }
119.243 + }
119.244 +}
120.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
120.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/Deprecations.java Mon Sep 21 13:01:16 2015 +0200
120.3 @@ -0,0 +1,184 @@
120.4 +/*
120.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
120.6 + *
120.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
120.8 + *
120.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
120.10 + * Other names may be trademarks of their respective owners.
120.11 + *
120.12 + * The contents of this file are subject to the terms of either the GNU
120.13 + * General Public License Version 2 only ("GPL") or the Common
120.14 + * Development and Distribution License("CDDL") (collectively, the
120.15 + * "License"). You may not use this file except in compliance with the
120.16 + * License. You can obtain a copy of the License at
120.17 + * http://www.netbeans.org/cddl-gplv2.html
120.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
120.19 + * specific language governing permissions and limitations under the
120.20 + * License. When distributing the software, include this License Header
120.21 + * Notice in each file and include the License file at
120.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
120.23 + * particular file as subject to the "Classpath" exception as provided
120.24 + * by Oracle in the GPL Version 2 section of the License file that
120.25 + * accompanied this code. If applicable, add the following below the
120.26 + * License Header, with the fields enclosed by brackets [] replaced by
120.27 + * your own identifying information:
120.28 + * "Portions Copyrighted [year] [name of copyright owner]"
120.29 + *
120.30 + * If you wish your version of this file to be governed by only the CDDL
120.31 + * or only the GPL Version 2, indicate your decision by adding
120.32 + * "[Contributor] elects to include this software in this distribution
120.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
120.34 + * single choice of license, a recipient has the option to distribute
120.35 + * your version of this file under either the CDDL, the GPL Version 2 or
120.36 + * to extend the choice of license to its licensees as provided above.
120.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
120.38 + * Version 2 license, then the option applies only if the new code is
120.39 + * made subject to such option by the copyright holder.
120.40 + *
120.41 + * Contributor(s):
120.42 + *
120.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
120.44 + */
120.45 +package org.netbeans.modules.python.hints;
120.46 +
120.47 +import java.util.Collections;
120.48 +import java.util.HashMap;
120.49 +import java.util.HashSet;
120.50 +import java.util.List;
120.51 +import java.util.Map;
120.52 +import java.util.Set;
120.53 +import java.util.prefs.Preferences;
120.54 +import javax.swing.JComponent;
120.55 +import javax.swing.text.BadLocationException;
120.56 +import org.netbeans.modules.python.source.PythonAstUtils;
120.57 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
120.58 +import org.netbeans.editor.BaseDocument;
120.59 +import org.netbeans.editor.Utilities;
120.60 +import org.netbeans.modules.csl.api.Hint;
120.61 +import org.netbeans.modules.csl.api.HintFix;
120.62 +import org.netbeans.modules.csl.api.HintSeverity;
120.63 +import org.netbeans.modules.csl.api.OffsetRange;
120.64 +import org.netbeans.modules.csl.api.RuleContext;
120.65 +import org.netbeans.modules.python.source.PythonParserResult;
120.66 +import org.netbeans.modules.python.source.queries.DeprecationQuery;
120.67 +import org.openide.util.Exceptions;
120.68 +import org.openide.util.NbBundle;
120.69 +import org.python.antlr.PythonTree;
120.70 +import org.python.antlr.ast.Import;
120.71 +import org.python.antlr.ast.ImportFrom;
120.72 +import org.python.antlr.ast.alias;
120.73 +
120.74 +/**
120.75 + * Handle deprecaton warnings, for modules listed as obsolete or
120.76 + * deprecated in PEP4:
120.77 + * http://www.python.org/dev/peps/pep-0004/
120.78 + *
120.79 + * Todo: Add a hint to enforce this from PEP8:
120.80 +- Comparisons to singletons like None should always be done with
120.81 +'is' or 'is not', never the equality operators.
120.82 + * In general, see the "Programming Recommendations" list from
120.83 + * http://www.python.org/dev/peps/pep-0008/ - there are lots
120.84 + * of thins to check from there. Check the PyLint list as well.
120.85 + *
120.86 + *
120.87 + * @author Tor Norbye
120.88 + */
120.89 +public class Deprecations extends PythonAstRule {
120.90 +
120.91 + @Override
120.92 + public Set<Class> getKinds() {
120.93 + HashSet<Class> kinds = new HashSet<>();
120.94 + kinds.add(Import.class);
120.95 + kinds.add(ImportFrom.class);
120.96 +
120.97 + return kinds;
120.98 + }
120.99 +
120.100 + @Override
120.101 + public void run(PythonRuleContext context, List<Hint> result) {
120.102 + PythonTree node = context.node;
120.103 + if (node instanceof Import) {
120.104 + Import imp = (Import)node;
120.105 + List<alias> names = imp.getInternalNames();
120.106 + if (names != null) {
120.107 + for (alias alias : names) {
120.108 + String name = alias.getInternalName();
120.109 + if (DeprecationQuery.isDeprecatedModule(name)) {
120.110 + addDeprecation(name, DeprecationQuery.getDeprecatedModuleDescription(name), context, result);
120.111 + }
120.112 + }
120.113 + }
120.114 + } else {
120.115 + assert node instanceof ImportFrom;
120.116 + ImportFrom imp = (ImportFrom)node;
120.117 + String name = imp.getInternalModule();
120.118 + if (DeprecationQuery.isDeprecatedModule(name)) {
120.119 + addDeprecation(name, DeprecationQuery.getDeprecatedModuleDescription(name), context, result);
120.120 + }
120.121 + }
120.122 + }
120.123 +
120.124 + private void addDeprecation(String module, String rationale, PythonRuleContext context, List<Hint> result) {
120.125 + PythonParserResult info = (PythonParserResult) context.parserResult;
120.126 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, context.node);
120.127 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
120.128 + BaseDocument doc = context.doc;
120.129 + try {
120.130 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
120.131 + (context.caretOffset == -1 ||
120.132 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
120.133 + List<HintFix> fixList = Collections.emptyList();
120.134 + String displayName;
120.135 + if (rationale.length() > 0) {
120.136 + displayName = NbBundle.getMessage(Deprecations.class, "DeprecationsMsgDetail", module, rationale);
120.137 + } else {
120.138 + displayName = NbBundle.getMessage(Deprecations.class, "DeprecationsMsg", module);
120.139 + }
120.140 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
120.141 + result.add(desc);
120.142 + }
120.143 + } catch (BadLocationException ex) {
120.144 + Exceptions.printStackTrace(ex);
120.145 + }
120.146 + }
120.147 +
120.148 + @Override
120.149 + public String getId() {
120.150 + return "Deprecations"; // NOI18N
120.151 + }
120.152 +
120.153 + @Override
120.154 + public String getDisplayName() {
120.155 + return NbBundle.getMessage(Deprecations.class, "Deprecations");
120.156 + }
120.157 +
120.158 + @Override
120.159 + public String getDescription() {
120.160 + return NbBundle.getMessage(Deprecations.class, "DeprecationsDesc");
120.161 + }
120.162 +
120.163 + @Override
120.164 + public boolean getDefaultEnabled() {
120.165 + return true;
120.166 + }
120.167 +
120.168 + @Override
120.169 + public JComponent getCustomizer(Preferences node) {
120.170 + return null;
120.171 + }
120.172 +
120.173 + @Override
120.174 + public boolean appliesTo(RuleContext context) {
120.175 + return true;
120.176 + }
120.177 +
120.178 + @Override
120.179 + public boolean showInTasklist() {
120.180 + return true;
120.181 + }
120.182 +
120.183 + @Override
120.184 + public HintSeverity getDefaultSeverity() {
120.185 + return HintSeverity.WARNING;
120.186 + }
120.187 +}
121.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
121.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/ExtractCode.java Mon Sep 21 13:01:16 2015 +0200
121.3 @@ -0,0 +1,759 @@
121.4 +/*
121.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
121.6 + *
121.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
121.8 + *
121.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
121.10 + * Other names may be trademarks of their respective owners.
121.11 + *
121.12 + * The contents of this file are subject to the terms of either the GNU
121.13 + * General Public License Version 2 only ("GPL") or the Common
121.14 + * Development and Distribution License("CDDL") (collectively, the
121.15 + * "License"). You may not use this file except in compliance with the
121.16 + * License. You can obtain a copy of the License at
121.17 + * http://www.netbeans.org/cddl-gplv2.html
121.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
121.19 + * specific language governing permissions and limitations under the
121.20 + * License. When distributing the software, include this License Header
121.21 + * Notice in each file and include the License file at
121.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
121.23 + * particular file as subject to the "Classpath" exception as provided
121.24 + * by Oracle in the GPL Version 2 section of the License file that
121.25 + * accompanied this code. If applicable, add the following below the
121.26 + * License Header, with the fields enclosed by brackets [] replaced by
121.27 + * your own identifying information:
121.28 + * "Portions Copyrighted [year] [name of copyright owner]"
121.29 + *
121.30 + * Contributor(s):
121.31 + *
121.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
121.33 + */
121.34 +package org.netbeans.modules.python.hints;
121.35 +
121.36 +import java.util.ArrayList;
121.37 +import java.util.Collections;
121.38 +import java.util.HashSet;
121.39 +import java.util.List;
121.40 +import java.util.Set;
121.41 +import java.util.prefs.Preferences;
121.42 +import javax.swing.JComponent;
121.43 +import javax.swing.text.JTextComponent;
121.44 +import org.netbeans.editor.BaseDocument;
121.45 +import org.netbeans.editor.Utilities;
121.46 +import org.netbeans.modules.csl.api.EditList;
121.47 +import org.netbeans.modules.csl.api.EditRegions;
121.48 +import org.netbeans.modules.csl.api.Hint;
121.49 +import org.netbeans.modules.csl.api.HintFix;
121.50 +import org.netbeans.modules.csl.api.HintSeverity;
121.51 +import org.netbeans.modules.csl.api.OffsetRange;
121.52 +import org.netbeans.modules.csl.api.PreviewableFix;
121.53 +import org.netbeans.modules.csl.api.RuleContext;
121.54 +import org.netbeans.modules.csl.spi.GsfUtilities;
121.55 +import org.netbeans.modules.editor.indent.api.IndentUtils;
121.56 +import org.netbeans.modules.python.source.AstPath;
121.57 +import org.netbeans.modules.python.source.PythonAstUtils;
121.58 +import org.netbeans.modules.python.source.PythonParserResult;
121.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
121.60 +import org.openide.util.Exceptions;
121.61 +import org.openide.util.NbBundle;
121.62 +import org.python.antlr.PythonTree;
121.63 +import org.python.antlr.Visitor;
121.64 +import org.python.antlr.ast.Assert;
121.65 +import org.python.antlr.ast.Assign;
121.66 +import org.python.antlr.ast.AugAssign;
121.67 +import org.python.antlr.ast.Break;
121.68 +import org.python.antlr.ast.Call;
121.69 +import org.python.antlr.ast.ClassDef;
121.70 +import org.python.antlr.ast.Continue;
121.71 +import org.python.antlr.ast.Delete;
121.72 +import org.python.antlr.ast.For;
121.73 +import org.python.antlr.ast.FunctionDef;
121.74 +import org.python.antlr.ast.Global;
121.75 +import org.python.antlr.ast.If;
121.76 +import org.python.antlr.ast.IfExp;
121.77 +import org.python.antlr.ast.Import;
121.78 +import org.python.antlr.ast.ImportFrom;
121.79 +import org.python.antlr.ast.Module;
121.80 +import org.python.antlr.ast.Name;
121.81 +import org.python.antlr.ast.Num;
121.82 +import org.python.antlr.ast.Pass;
121.83 +import org.python.antlr.ast.Print;
121.84 +import org.python.antlr.ast.Raise;
121.85 +import org.python.antlr.ast.Return;
121.86 +import org.python.antlr.ast.Str;
121.87 +import org.python.antlr.ast.Suite;
121.88 +import org.python.antlr.ast.TryExcept;
121.89 +import org.python.antlr.ast.TryFinally;
121.90 +import org.python.antlr.ast.Tuple;
121.91 +import org.python.antlr.ast.While;
121.92 +import org.python.antlr.ast.With;
121.93 +import org.python.antlr.ast.Yield;
121.94 +
121.95 +/**
121.96 + * Offer to introduce method/variable/constant
121.97 + * @todo There is no need to pass in class or top level constants to code fragments
121.98 + * @todo Handle flow control: If a code fragment contains an early return, figure out
121.99 + * how to pass that information back to the method callsite and do something clever,
121.100 + * for example pass back a to-return flag which returns the same value
121.101 + * @todo Unit tests must check instant rename as well!
121.102 + *
121.103 + * @author Tor Norbye
121.104 + */
121.105 +public class ExtractCode extends PythonSelectionRule {
121.106 + //private static final int NOT_APPLICABLE = 0;
121.107 + private static final int INTRODUCE_METHOD = 1;
121.108 + private static final int INTRODUCE_VARIABLE = 2;
121.109 + private static final int INTRODUCE_CONSTANT = 4;
121.110 + private static final int INTRODUCE_FIELD = 8;
121.111 + private static final int NON_EXPRESSIONS = INTRODUCE_VARIABLE | INTRODUCE_FIELD | INTRODUCE_CONSTANT;
121.112 + private static final int ALL = ~0;
121.113 +
121.114 + @Override
121.115 + protected int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange) {
121.116 + return ApplicabilityVisitor.getType(root, astRange);
121.117 + }
121.118 +
121.119 + @Override
121.120 + public void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability) {
121.121 + int start = range.getStart();
121.122 + int end = range.getEnd();
121.123 +
121.124 +// HACK: Only extract method works at this point
121.125 + applicability = applicability & INTRODUCE_METHOD;
121.126 +
121.127 +
121.128 + // Adjust the fix range to be right around the dot so that the light bulb ends up
121.129 + // on the same line as the caret and alt-enter works
121.130 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
121.131 + if (target != null) {
121.132 + int dot = target.getCaret().getDot();
121.133 + range = new OffsetRange(dot, dot);
121.134 + }
121.135 +
121.136 + List<HintFix> fixList = new ArrayList<>(3);
121.137 + if ((applicability & INTRODUCE_METHOD) != 0) {
121.138 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_METHOD));
121.139 + }
121.140 + if ((applicability & INTRODUCE_VARIABLE) != 0) {
121.141 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_VARIABLE));
121.142 + }
121.143 + if ((applicability & INTRODUCE_CONSTANT) != 0) {
121.144 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_CONSTANT));
121.145 + }
121.146 + if ((applicability & INTRODUCE_FIELD) != 0) {
121.147 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_FIELD));
121.148 + }
121.149 + if (fixList.size() > 0) {
121.150 + String displayName = getDisplayName();
121.151 + Hint desc = new Hint(this, displayName, context.parserResult.getSnapshot().getSource().getFileObject(),
121.152 + range, fixList, 490);
121.153 + result.add(desc);
121.154 + }
121.155 + }
121.156 +
121.157 + @Override
121.158 + public boolean appliesTo(RuleContext context) {
121.159 + return true;
121.160 + }
121.161 +
121.162 + @Override
121.163 + public String getDisplayName() {
121.164 + return NbBundle.getMessage(ExtractCode.class, "ExtractCode");
121.165 + }
121.166 +
121.167 + @Override
121.168 + public String getId() {
121.169 + return "ExtractCode"; // NOI18N
121.170 + }
121.171 +
121.172 + @Override
121.173 + public String getDescription() {
121.174 + return "";
121.175 + }
121.176 +
121.177 + @Override
121.178 + public boolean getDefaultEnabled() {
121.179 + return true;
121.180 + }
121.181 +
121.182 + @Override
121.183 + public JComponent getCustomizer(Preferences node) {
121.184 + return null;
121.185 + }
121.186 +
121.187 + @Override
121.188 + public boolean showInTasklist() {
121.189 + return false;
121.190 + }
121.191 +
121.192 + @Override
121.193 + public HintSeverity getDefaultSeverity() {
121.194 + return HintSeverity.CURRENT_LINE_WARNING;
121.195 + }
121.196 +
121.197 + private static class ExtractCodeFix implements PreviewableFix {
121.198 + private final PythonRuleContext context;
121.199 + //private Position callSitePos;
121.200 + //private Position extractedPos;
121.201 + private int finalCallSiteOffset;
121.202 + private int finalExtractedSiteOffset;
121.203 + ;
121.204 + private final int type;
121.205 + private final int start;
121.206 + private final int end;
121.207 + private String newName;
121.208 +
121.209 + private ExtractCodeFix(PythonRuleContext context,
121.210 + int start, int end, int type) {
121.211 + this.context = context;
121.212 +
121.213 + OffsetRange range = PythonLexerUtils.narrow(context.doc, new OffsetRange(start, end), false);
121.214 + this.start = range.getStart();
121.215 + this.end = range.getEnd();
121.216 +
121.217 + this.type = type;
121.218 + }
121.219 +
121.220 + @Override
121.221 + public String getDescription() {
121.222 + switch (type) {
121.223 + case INTRODUCE_VARIABLE:
121.224 + return NbBundle.getMessage(CreateDocString.class, "IntroduceVariable");
121.225 + case INTRODUCE_CONSTANT:
121.226 + return NbBundle.getMessage(CreateDocString.class, "IntroduceConstant");
121.227 + case INTRODUCE_METHOD:
121.228 + return NbBundle.getMessage(CreateDocString.class, "IntroduceMethod");
121.229 + case INTRODUCE_FIELD:
121.230 + return NbBundle.getMessage(CreateDocString.class, "IntroduceField");
121.231 + default:
121.232 + throw new IllegalArgumentException();
121.233 + }
121.234 + }
121.235 +
121.236 + @Override
121.237 + public boolean canPreview() {
121.238 + return true;
121.239 + }
121.240 +
121.241 + @Override
121.242 + public EditList getEditList() throws Exception {
121.243 + BaseDocument doc = context.doc;
121.244 + PythonParserResult info = (PythonParserResult) context.parserResult;
121.245 + EditList edits = new EditList(doc);
121.246 +
121.247 + int extractedOffset = doc.getLength();
121.248 + int prevFunctionOffset = 0;
121.249 + PythonTree root = PythonAstUtils.getRoot(info);
121.250 +
121.251 + OffsetRange narrowed = PythonLexerUtils.narrow(doc, new OffsetRange(start, end), true);
121.252 +
121.253 + int astStart = PythonAstUtils.getAstOffset(info, narrowed != OffsetRange.NONE ? narrowed.getStart() : start);
121.254 + int astEnd = PythonAstUtils.getAstOffset(info, narrowed != OffsetRange.NONE ? narrowed.getEnd() : end);
121.255 + if (astStart == -1 || astEnd == -1) {
121.256 + return edits;
121.257 + }
121.258 + AstPath startPath = AstPath.get(root, astStart);
121.259 + AstPath endPath = AstPath.get(root, astEnd);
121.260 + PythonTree localScope = PythonAstUtils.getLocalScope(startPath);
121.261 + if (localScope != null) {
121.262 + OffsetRange astRange = PythonAstUtils.getRange(localScope);
121.263 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
121.264 + if (lexRange != OffsetRange.NONE) {
121.265 + extractedOffset = lexRange.getEnd();
121.266 +
121.267 + // Function end offsets are a bit sloppy so try to deal with that
121.268 + int firstNonWhite = Utilities.getRowFirstNonWhite(doc, Math.min(extractedOffset, doc.getLength()));
121.269 + if (firstNonWhite == -1 || extractedOffset <= firstNonWhite) {
121.270 + extractedOffset = Utilities.getRowStart(doc, extractedOffset);
121.271 + }
121.272 +
121.273 + prevFunctionOffset = lexRange.getStart();
121.274 + if (extractedOffset > doc.getLength()) {
121.275 + extractedOffset = doc.getLength();
121.276 + }
121.277 + }
121.278 + }
121.279 + int callSiteOffset = start;
121.280 + int callSiteReplaceLength = end - start;
121.281 +
121.282 + int indentSize = IndentUtils.indentLevelSize(doc);
121.283 + int lineStart = Utilities.getRowStart(doc, prevFunctionOffset);
121.284 + int initialIndent = IndentUtils.lineIndent(doc, lineStart);
121.285 + String initialIndentStr = IndentUtils.createIndentString(doc, initialIndent);
121.286 +
121.287 + newName = "new_name"; // TODO - localize!
121.288 +
121.289 + // Compute input/output arguments
121.290 + PythonTree startNode = startPath.leaf();
121.291 + PythonTree endNode = endPath.leaf();
121.292 +
121.293 + InputOutputFinder finder = new InputOutputFinder(startNode, endNode, Collections.<PythonTree>emptyList());
121.294 + finder.traverse(localScope);
121.295 + List<String> inParams = new ArrayList<>(finder.getInputVars());
121.296 + List<String> outParams = new ArrayList<>(finder.getOutputVars());
121.297 + Collections.sort(inParams);
121.298 + Collections.sort(outParams);
121.299 +
121.300 + ClassDef cls = PythonAstUtils.getClassDef(startPath);
121.301 +
121.302 + // Adjust the insert location in case we are at the top level
121.303 + if (cls == null && PythonAstUtils.getFuncDef(startPath) == null) {
121.304 + extractedOffset = -1;
121.305 + PythonTree top = startPath.topModuleLevel();
121.306 + if (top != null) {
121.307 + OffsetRange astRange = PythonAstUtils.getRange(top);
121.308 + extractedOffset = PythonLexerUtils.getLexerOffset(info, astRange.getStart());
121.309 + }
121.310 +
121.311 + // We're at the top level - I can't insert the function -after- the current function
121.312 + // because that will result in a runtime error
121.313 + if (extractedOffset == -1) {
121.314 + extractedOffset = Utilities.getRowStart(doc, Math.min(doc.getLength(), start));
121.315 + }
121.316 + }
121.317 +
121.318 + String extractedCode = null;
121.319 + int extractedSiteDelta = 0;
121.320 + if (type == INTRODUCE_METHOD) {
121.321 + StringBuilder sb = new StringBuilder();
121.322 + if (Utilities.getRowStart(doc, Math.min(extractedOffset, doc.getLength())) < extractedOffset) {
121.323 + sb.append("\n"); // NOI18N
121.324 + }
121.325 + sb.append("\n"); // NOI18N
121.326 + sb.append(initialIndentStr);
121.327 + sb.append("def "); // NOI18N
121.328 + extractedSiteDelta = sb.length();
121.329 + sb.append(newName);
121.330 + sb.append("("); // NOI18N
121.331 + if (cls != null) {
121.332 + sb.append("self"); // NOI18N
121.333 + if (inParams.size() > 0) {
121.334 + sb.append(", "); // NOI18N
121.335 + }
121.336 + }
121.337 + boolean first = true;
121.338 + for (String param : inParams) {
121.339 + if (first) {
121.340 + first = false;
121.341 + } else {
121.342 + sb.append(", "); // NOI18N
121.343 + }
121.344 + sb.append(param);
121.345 + }
121.346 + sb.append("):\n"); // NOI18N
121.347 +
121.348 + // Copy in the extracted code
121.349 + int firstIndent = IndentUtils.lineIndent(doc, Utilities.getRowStart(doc, start));
121.350 + for (int offset = start; offset < end; offset = Utilities.getRowEnd(doc, offset) + 1) {
121.351 + // TODO - handle multiline literal strings correctly!!!
121.352 + if (!(Utilities.isRowEmpty(doc, offset) || Utilities.isRowWhite(doc, offset))) {
121.353 + int lineIndent = IndentUtils.lineIndent(doc, Utilities.getRowStart(doc, offset));
121.354 + int newIndent = (lineIndent - firstIndent) + initialIndent + indentSize;
121.355 + if (newIndent > 0) {
121.356 + sb.append(IndentUtils.createIndentString(doc, newIndent));
121.357 + }
121.358 + int rowFirstNonWhite = Utilities.getRowFirstNonWhite(doc, offset);
121.359 + int rowLastNonWhite = Utilities.getRowLastNonWhite(doc, offset) + 1; // +1: doesn't include last char
121.360 + sb.append(doc.getText(rowFirstNonWhite, rowLastNonWhite - rowFirstNonWhite));
121.361 + }
121.362 + sb.append("\n"); // NOI18N
121.363 + }
121.364 + sb.append("\n");
121.365 +
121.366 + if (outParams.size() > 0) {
121.367 + sb.append(IndentUtils.createIndentString(doc, initialIndent + indentSize));
121.368 + sb.append("return "); // NOI18N
121.369 + first = true;
121.370 + for (String param : outParams) {
121.371 + if (first) {
121.372 + first = false;
121.373 + } else {
121.374 + // No spaces in the comma list for return tuples
121.375 + sb.append(","); // NOI18N
121.376 + }
121.377 + sb.append(param);
121.378 + }
121.379 + sb.append("\n\n"); // NOI18N
121.380 + }
121.381 +
121.382 + // Insert the extracted code at the end
121.383 + extractedCode = sb.toString();
121.384 + } else {
121.385 + assert (type == INTRODUCE_FIELD || type == INTRODUCE_CONSTANT || type == INTRODUCE_VARIABLE);
121.386 + throw new RuntimeException("Not yet implemented");
121.387 + }
121.388 +
121.389 + // Replace the code at the extract site with just the call
121.390 + StringBuilder sb = new StringBuilder();
121.391 + if (type == INTRODUCE_METHOD) {
121.392 + // Assign to the output variables if any
121.393 + if (outParams.size() > 0) {
121.394 + boolean first = true;
121.395 + for (String param : outParams) {
121.396 + if (first) {
121.397 + first = false;
121.398 + } else {
121.399 + // No spaces in the comma list for return tuples
121.400 + sb.append(","); // NOI18N
121.401 + }
121.402 + sb.append(param);
121.403 + }
121.404 +
121.405 + sb.append(" = ");
121.406 + }
121.407 + } else {
121.408 + assert (type == INTRODUCE_FIELD || type == INTRODUCE_CONSTANT || type == INTRODUCE_VARIABLE);
121.409 + }
121.410 +
121.411 + int callSiteDelta = sb.length();
121.412 + sb.append(newName);
121.413 + if (type == INTRODUCE_METHOD) {
121.414 + sb.append('(');
121.415 + if (cls != null) {
121.416 + sb.append("self"); // NOI18N
121.417 + if (inParams.size() > 0) {
121.418 + sb.append(", "); // NOI18N
121.419 + }
121.420 + }
121.421 + boolean first = true;
121.422 + for (String param : inParams) {
121.423 + if (first) {
121.424 + first = false;
121.425 + } else {
121.426 + sb.append(", "); // NOI18N
121.427 + }
121.428 + sb.append(param);
121.429 + }
121.430 + sb.append(')');
121.431 + }
121.432 + String callSiteCode = sb.toString();
121.433 +
121.434 +
121.435 + // Apply changes
121.436 + if (extractedOffset >= callSiteOffset && extractedOffset <= callSiteOffset + callSiteReplaceLength) {
121.437 + if (extractedOffset > callSiteOffset) {
121.438 + // We're trying to insert the extracted code segment after the call - that must mean we're
121.439 + // in something like a function
121.440 + edits.replace(callSiteOffset, callSiteReplaceLength, callSiteCode + extractedCode, false, 0);
121.441 +
121.442 + // Work around bug in Document.Position
121.443 + //extractedPos = edits.createPosition(callSiteOffset+callSiteCode.length()+extractedSiteDelta, Bias.Forward);
121.444 + //callSitePos = edits.createPosition(callSiteOffset+callSiteDelta, Bias.Forward);
121.445 + finalCallSiteOffset = callSiteOffset + callSiteDelta;
121.446 + finalExtractedSiteOffset = callSiteOffset + callSiteCode.length() + extractedSiteDelta;
121.447 + } else {
121.448 + edits.replace(callSiteOffset, callSiteReplaceLength, extractedCode + callSiteCode, false, 0);
121.449 +
121.450 + // Work around bug in Document.Position
121.451 + //extractedPos = edits.createPosition(callSiteOffset+extractedSiteDelta, Bias.Forward);
121.452 + //callSitePos = edits.createPosition(callSiteOffset+extractedCode.length()+callSiteDelta, Bias.Forward);
121.453 + finalCallSiteOffset = callSiteOffset + extractedCode.length() + callSiteDelta;
121.454 + finalExtractedSiteOffset = callSiteOffset + extractedSiteDelta;
121.455 + }
121.456 + } else {
121.457 + edits.replace(extractedOffset, 0, extractedCode, false, 1);
121.458 + edits.replace(callSiteOffset, callSiteReplaceLength, callSiteCode, false, 0);
121.459 +
121.460 + // There's a bug document/editlist position code - the offsets aren't updated on my
121.461 + // edits! For now just compute the offsets directly since we know the exact edits applied
121.462 + //extractedPos = edits.createPosition(extractedOffset+extractedSiteDelta, Bias.Backward);
121.463 + //callSitePos = edits.createPosition(callSiteOffset+callSiteDelta, Bias.Backward);
121.464 + if (extractedOffset < callSiteOffset) {
121.465 + finalCallSiteOffset = callSiteOffset + callSiteDelta + extractedCode.length();
121.466 + finalExtractedSiteOffset = extractedOffset + extractedSiteDelta;
121.467 + } else {
121.468 + finalCallSiteOffset = callSiteOffset + callSiteDelta;
121.469 + finalExtractedSiteOffset = extractedOffset + extractedSiteDelta + callSiteCode.length() - callSiteReplaceLength;
121.470 + }
121.471 + }
121.472 +
121.473 + return edits;
121.474 + }
121.475 +
121.476 + @Override
121.477 + public void implement() throws Exception {
121.478 + EditList edits = getEditList();
121.479 +
121.480 + edits.apply();
121.481 +
121.482 + // Refactoring isn't necessary here since local variables and block
121.483 + // variables are limited to the local scope, so we can accurately just
121.484 + // find their positions using the AST and let the user edit them synchronously.
121.485 + Set<OffsetRange> ranges = new HashSet<>();
121.486 + int length = newName.length();
121.487 + ranges.add(new OffsetRange(finalCallSiteOffset, finalCallSiteOffset + length));
121.488 + ranges.add(new OffsetRange(finalExtractedSiteOffset, finalExtractedSiteOffset + length));
121.489 +
121.490 + // Initiate synchronous editing:
121.491 + EditRegions.getInstance().edit(context.parserResult.getSnapshot().getSource().getFileObject(), ranges, finalExtractedSiteOffset);
121.492 + }
121.493 +
121.494 + @Override
121.495 + public boolean isSafe() {
121.496 + return true;
121.497 + }
121.498 +
121.499 + @Override
121.500 + public boolean isInteractive() {
121.501 + return false;
121.502 + }
121.503 + }
121.504 +
121.505 + /** @todo Prune search in traverse, ala AstPath.
121.506 + * @todo Build up start and end AstPaths.
121.507 + */
121.508 + private static class ApplicabilityVisitor extends Visitor {
121.509 + private boolean applies = true;
121.510 + private int disabled;
121.511 + private int enabled;
121.512 + private final int start;
121.513 + private final int end;
121.514 +
121.515 + static int getType(PythonTree root, OffsetRange astRange) {
121.516 + ApplicabilityVisitor visitor = new ApplicabilityVisitor(astRange);
121.517 + try {
121.518 + visitor.visit(root);
121.519 + } catch (Exception ex) {
121.520 + Exceptions.printStackTrace(ex);
121.521 + return 0;
121.522 + }
121.523 + return visitor.getType();
121.524 + }
121.525 +
121.526 + ApplicabilityVisitor(OffsetRange astRange) {
121.527 + this.start = astRange.getStart();
121.528 + this.end = astRange.getEnd();
121.529 + }
121.530 +
121.531 + private void enable(PythonTree node, int mask) {
121.532 + if (node.getCharStartIndex() >= start && node.getCharStopIndex() <= end) {
121.533 + enabled |= mask;
121.534 + }
121.535 + }
121.536 +
121.537 + private void disable(PythonTree node, int mask) {
121.538 + if (node.getCharStartIndex() >= start && node.getCharStopIndex() <= end) {
121.539 + disabled |= mask;
121.540 + }
121.541 + }
121.542 +
121.543 + public int getType() {
121.544 + return enabled & ~disabled;
121.545 + }
121.546 +
121.547 + private void maybeBail(PythonTree node) {
121.548 + int nodeStart = node.getCharStartIndex();
121.549 + int nodeEnd = node.getCharStopIndex();
121.550 + if (nodeStart >= start && nodeStart < end) {
121.551 + applies = false;
121.552 + disable(node, ALL);
121.553 + }
121.554 + if (nodeEnd > start && nodeEnd < end) {
121.555 + applies = false;
121.556 + disable(node, ALL);
121.557 + }
121.558 + }
121.559 +
121.560 + @Override
121.561 + public void traverse(PythonTree node) throws Exception {
121.562 + if (!applies) {
121.563 + return;
121.564 + }
121.565 +
121.566 + int nodeStart = node.getCharStartIndex();
121.567 + int nodeStop = node.getCharStopIndex();
121.568 + //if (!(nodeStop < start || nodeStart > end)) {
121.569 + if (nodeStop >= start && nodeStart <= end) {
121.570 + super.traverse(node);
121.571 + }
121.572 + }
121.573 +
121.574 + @Override
121.575 + public Object visitClassDef(ClassDef node) throws Exception {
121.576 + maybeBail(node);
121.577 + return super.visitClassDef(node);
121.578 + }
121.579 +
121.580 + @Override
121.581 + public Object visitFunctionDef(FunctionDef node) throws Exception {
121.582 + maybeBail(node);
121.583 + return super.visitFunctionDef(node);
121.584 + }
121.585 +
121.586 + @Override
121.587 + public Object visitImport(Import node) throws Exception {
121.588 + disable(node, ALL);
121.589 + return super.visitImport(node);
121.590 + }
121.591 +
121.592 + @Override
121.593 + public Object visitImportFrom(ImportFrom node) throws Exception {
121.594 + disable(node, ALL);
121.595 + return super.visitImportFrom(node);
121.596 + }
121.597 +
121.598 + @Override
121.599 + public Object visitAssign(Assign node) throws Exception {
121.600 + disable(node, NON_EXPRESSIONS);
121.601 + disable(node, NON_EXPRESSIONS);
121.602 + return super.visitAssign(node);
121.603 + }
121.604 +
121.605 + @Override
121.606 + public Object visitCall(Call node) throws Exception {
121.607 + enable(node, ALL);
121.608 + disable(node, INTRODUCE_CONSTANT);
121.609 + return super.visitCall(node);
121.610 + }
121.611 +
121.612 + @Override
121.613 + public Object visitAugAssign(AugAssign node) throws Exception {
121.614 + disable(node, NON_EXPRESSIONS);
121.615 + return super.visitAugAssign(node);
121.616 + }
121.617 +
121.618 + @Override
121.619 + public Object visitBreak(Break node) throws Exception {
121.620 + disable(node, NON_EXPRESSIONS);
121.621 + return super.visitBreak(node);
121.622 + }
121.623 +
121.624 + @Override
121.625 + public Object visitContinue(Continue node) throws Exception {
121.626 + disable(node, NON_EXPRESSIONS);
121.627 + return super.visitContinue(node);
121.628 + }
121.629 +
121.630 + @Override
121.631 + public Object visitDelete(Delete node) throws Exception {
121.632 + disable(node, NON_EXPRESSIONS);
121.633 + return super.visitDelete(node);
121.634 + }
121.635 +
121.636 + @Override
121.637 + public Object visitFor(For node) throws Exception {
121.638 + disable(node, NON_EXPRESSIONS);
121.639 + return super.visitFor(node);
121.640 + }
121.641 +
121.642 + @Override
121.643 + public Object visitIf(If node) throws Exception {
121.644 + disable(node, NON_EXPRESSIONS);
121.645 + return super.visitIf(node);
121.646 + }
121.647 +
121.648 + @Override
121.649 + public Object visitIfExp(IfExp node) throws Exception {
121.650 + disable(node, NON_EXPRESSIONS);
121.651 + return super.visitIfExp(node);
121.652 + }
121.653 +
121.654 + @Override
121.655 + public Object visitPrint(Print node) throws Exception {
121.656 + disable(node, NON_EXPRESSIONS);
121.657 + return super.visitPrint(node);
121.658 + }
121.659 +
121.660 + @Override
121.661 + public Object visitYield(Yield node) throws Exception {
121.662 + disable(node, NON_EXPRESSIONS);
121.663 + return super.visitYield(node);
121.664 + }
121.665 +
121.666 + @Override
121.667 + public Object visitWith(With node) throws Exception {
121.668 + disable(node, NON_EXPRESSIONS);
121.669 + return super.visitWith(node);
121.670 + }
121.671 +
121.672 + @Override
121.673 + public Object visitWhile(While node) throws Exception {
121.674 + disable(node, NON_EXPRESSIONS);
121.675 + return super.visitWhile(node);
121.676 + }
121.677 +
121.678 + @Override
121.679 + public Object visitTryFinally(TryFinally node) throws Exception {
121.680 + disable(node, NON_EXPRESSIONS);
121.681 + return super.visitTryFinally(node);
121.682 + }
121.683 +
121.684 + @Override
121.685 + public Object visitTryExcept(TryExcept node) throws Exception {
121.686 + disable(node, NON_EXPRESSIONS);
121.687 + return super.visitTryExcept(node);
121.688 + }
121.689 +
121.690 + @Override
121.691 + public Object visitSuite(Suite node) throws Exception {
121.692 + disable(node, NON_EXPRESSIONS);
121.693 + return super.visitSuite(node);
121.694 + }
121.695 +
121.696 + @Override
121.697 + public Object visitReturn(Return node) throws Exception {
121.698 +// disable(node, NON_EXPRESSIONS);
121.699 + // TODO - handle flow control!!
121.700 + disable(node, ALL);
121.701 + return super.visitReturn(node);
121.702 + }
121.703 +
121.704 + @Override
121.705 + public Object visitModule(Module node) throws Exception {
121.706 + if (node.getCharStartIndex() > start && node.getCharStopIndex() < end) {
121.707 +// disable(node, NON_EXPRESSIONS);
121.708 + disable(node, ALL);
121.709 + }
121.710 + return super.visitModule(node);
121.711 + }
121.712 +
121.713 + @Override
121.714 + public Object visitPass(Pass node) throws Exception {
121.715 + disable(node, NON_EXPRESSIONS);
121.716 + return super.visitPass(node);
121.717 + }
121.718 +
121.719 + @Override
121.720 + public Object visitRaise(Raise node) throws Exception {
121.721 + disable(node, NON_EXPRESSIONS);
121.722 + return super.visitRaise(node);
121.723 + }
121.724 +
121.725 + @Override
121.726 + public Object visitAssert(Assert node) throws Exception {
121.727 + disable(node, NON_EXPRESSIONS);
121.728 + return super.visitAssert(node);
121.729 + }
121.730 +
121.731 + @Override
121.732 + public Object visitNum(Num node) throws Exception {
121.733 + enable(node, ALL);
121.734 + return super.visitNum(node);
121.735 + }
121.736 +
121.737 + @Override
121.738 + public Object visitName(Name node) throws Exception {
121.739 + enable(node, ALL);
121.740 + return super.visitName(node);
121.741 + }
121.742 +
121.743 + @Override
121.744 + public Object visitGlobal(Global node) throws Exception {
121.745 + enable(node, ALL);
121.746 + disable(node, INTRODUCE_CONSTANT);
121.747 + return super.visitGlobal(node);
121.748 + }
121.749 +
121.750 + @Override
121.751 + public Object visitTuple(Tuple node) throws Exception {
121.752 + enable(node, ALL);
121.753 + return super.visitTuple(node);
121.754 + }
121.755 +
121.756 + @Override
121.757 + public Object visitStr(Str node) throws Exception {
121.758 + enable(node, ALL);
121.759 + return super.visitStr(node);
121.760 + }
121.761 + }
121.762 +}
122.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
122.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/InputOutputFinder.java Mon Sep 21 13:01:16 2015 +0200
122.3 @@ -0,0 +1,304 @@
122.4 +/*
122.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
122.6 + *
122.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
122.8 + *
122.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
122.10 + * Other names may be trademarks of their respective owners.
122.11 + *
122.12 + * The contents of this file are subject to the terms of either the GNU
122.13 + * General Public License Version 2 only ("GPL") or the Common
122.14 + * Development and Distribution License("CDDL") (collectively, the
122.15 + * "License"). You may not use this file except in compliance with the
122.16 + * License. You can obtain a copy of the License at
122.17 + * http://www.netbeans.org/cddl-gplv2.html
122.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
122.19 + * specific language governing permissions and limitations under the
122.20 + * License. When distributing the software, include this License Header
122.21 + * Notice in each file and include the License file at
122.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
122.23 + * particular file as subject to the "Classpath" exception as provided
122.24 + * by Oracle in the GPL Version 2 section of the License file that
122.25 + * accompanied this code. If applicable, add the following below the
122.26 + * License Header, with the fields enclosed by brackets [] replaced by
122.27 + * your own identifying information:
122.28 + * "Portions Copyrighted [year] [name of copyright owner]"
122.29 + *
122.30 + * If you wish your version of this file to be governed by only the CDDL
122.31 + * or only the GPL Version 2, indicate your decision by adding
122.32 + * "[Contributor] elects to include this software in this distribution
122.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
122.34 + * single choice of license, a recipient has the option to distribute
122.35 + * your version of this file under either the CDDL, the GPL Version 2 or
122.36 + * to extend the choice of license to its licensees as provided above.
122.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
122.38 + * Version 2 license, then the option applies only if the new code is
122.39 + * made subject to such option by the copyright holder.
122.40 + *
122.41 + * Contributor(s):
122.42 + *
122.43 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
122.44 + */
122.45 +package org.netbeans.modules.python.hints;
122.46 +
122.47 +import java.util.HashMap;
122.48 +import java.util.HashSet;
122.49 +import java.util.List;
122.50 +import java.util.Map;
122.51 +import java.util.Set;
122.52 +import org.netbeans.modules.python.source.PythonAstUtils;
122.53 +import org.python.antlr.PythonTree;
122.54 +import org.python.antlr.Visitor;
122.55 +import org.python.antlr.ast.Assign;
122.56 +import org.python.antlr.ast.Call;
122.57 +import org.python.antlr.ast.FunctionDef;
122.58 +import org.python.antlr.ast.Name;
122.59 +import org.python.antlr.base.expr;
122.60 +
122.61 +/**
122.62 + * This visitor computes the set of input and output variables required by
122.63 + * a code block for extract method.
122.64 + * In particular, it tracks the local variable assignments inside the method,
122.65 + * and checks which are used outside of the method (which would make it an
122.66 + * output variable) and similarly, which variables are used inside the method
122.67 + * before getting assigned (which would make it an input variable).
122.68 + *
122.69 + * @author Tor Norbye
122.70 + */
122.71 +class InputOutputFinder extends Visitor {
122.72 + //private enum When { BEFORE, DURING, AFTER };
122.73 + private static final int WHEN_BEFORE = 0;
122.74 + private static final int WHEN_DURING = 1;
122.75 + private static final int WHEN_AFTER = 2;
122.76 + private final PythonTree startNode;
122.77 + private final PythonTree endNode;
122.78 + private final int startPos;
122.79 + private final int endPos;
122.80 + private final List<PythonTree> applicableBlocks;
122.81 + private int when = WHEN_BEFORE;
122.82 + private int ifs;
122.83 + //private PythonTree currentBlock;
122.84 + //private final List<PythonTree> blockStack = new ArrayList<PythonTree>(); // JDK16: Use Deque
122.85 + private Map<PythonTree, UsageScope> blockScopes = new HashMap<>();
122.86 + private UsageScope methodScope = new UsageScope(null);
122.87 + //private UsageScope blockScope;
122.88 + private PythonTree parent;
122.89 + private boolean isWriting;
122.90 +
122.91 + /** The node ranges are inclusive */
122.92 + InputOutputFinder(PythonTree startNode, PythonTree endNode, List<PythonTree> applicableBlocks) {
122.93 + this.startNode = startNode;
122.94 + this.endNode = endNode;
122.95 + this.applicableBlocks = applicableBlocks;
122.96 +
122.97 + startPos = startNode.getCharStartIndex();
122.98 + endPos = endNode.getCharStopIndex();
122.99 + }
122.100 +
122.101 + public Set<String> getInputVars() {
122.102 + UsageScope scope = methodScope;
122.103 + for (UsageScope s : blockScopes.values()) {
122.104 + if (s.block != null && !applicableBlocks.contains(s.block)) {
122.105 + continue;
122.106 + }
122.107 + scope.merge(s);
122.108 + }
122.109 +
122.110 + Set<String> inputs = new HashSet<>(scope.readDuring);
122.111 + // But not read before
122.112 + inputs.removeAll(scope.writtenBeforeReadDuring);
122.113 +
122.114 + // Also need to pass in any variables I'm modifying that are read after
122.115 + Set<String> outputs = new HashSet<>(scope.writtenDuring);
122.116 + outputs.retainAll(scope.readAfter);
122.117 + Set<String> extraOutputs = new HashSet<>(scope.writtenBefore);
122.118 + extraOutputs.retainAll(outputs);
122.119 + // unless they are written before read
122.120 + extraOutputs.removeAll(scope.writtenBeforeReadDuring);
122.121 + inputs.addAll(extraOutputs);
122.122 +
122.123 + return inputs;
122.124 + }
122.125 +
122.126 + public Set<String> getOutputVars() {
122.127 + UsageScope scope = methodScope;
122.128 + for (UsageScope s : blockScopes.values()) {
122.129 + if (s.block != null && !applicableBlocks.contains(s.block)) {
122.130 + continue;
122.131 + }
122.132 + scope.merge(s);
122.133 + }
122.134 +
122.135 + Set<String> outputs = new HashSet<>(scope.writtenDuring);
122.136 + outputs.retainAll(scope.readAfter);
122.137 +
122.138 + return outputs;
122.139 + }
122.140 +
122.141 + @Override
122.142 + public Object visitFunctionDef(FunctionDef node) throws Exception {
122.143 + // Record the parameters
122.144 +// assert when == WHEN_BEFORE; // Is this true when I extract a whole method? I can't do that, right?
122.145 + boolean x = true;
122.146 + assert x;
122.147 +
122.148 + for (String param : PythonAstUtils.getParameters(node)) {
122.149 + methodScope.write(param);
122.150 + }
122.151 +
122.152 + return super.visitFunctionDef(node);
122.153 + }
122.154 +
122.155 + @SuppressWarnings("unchecked")
122.156 + @Override
122.157 + public Object visitAssign(Assign node) throws Exception {
122.158 + // Visit the right hand side of the assignment first, such
122.159 + // that with for example
122.160 + // x = x + 1
122.161 + // we treat this as a read of x, before a write of x.
122.162 + // The Assign.traverse() implementation will do the targets first,
122.163 + // so we explicitly do it here in the opposite order instead...
122.164 +
122.165 + if (when == WHEN_BEFORE && node.getCharStartIndex() >= startPos) {
122.166 + when = WHEN_DURING;
122.167 + }
122.168 + int oldWhen = when;
122.169 +
122.170 + expr nodeValue = node.getInternalValue();
122.171 + if (nodeValue != null) {
122.172 + nodeValue.accept(this);
122.173 + }
122.174 + int newWhen = when;
122.175 + when = oldWhen;
122.176 +
122.177 + boolean oldWriting = isWriting;
122.178 + try {
122.179 + isWriting = true;
122.180 + List<expr> targets = node.getInternalTargets();
122.181 + if (targets != null) {
122.182 + for (expr expr : targets) {
122.183 + if (expr != null) {
122.184 + expr.accept(this);
122.185 + }
122.186 + }
122.187 + }
122.188 + } finally {
122.189 + isWriting = oldWriting;
122.190 + }
122.191 +
122.192 + when = newWhen;
122.193 +
122.194 + return node;
122.195 + }
122.196 +
122.197 + @Override
122.198 + public Object visitName(Name node) throws Exception {
122.199 + if (parent instanceof Call && ((Call)parent).getInternalFunc() == node) { // Name in a call is the call name, not a variable
122.200 + return super.visitName(node);
122.201 + }
122.202 +
122.203 + methodScope.read(node.getInternalId());
122.204 +
122.205 + return super.visitName(node);
122.206 + }
122.207 +
122.208 + @Override
122.209 + public void traverse(PythonTree node) throws Exception {
122.210 + if (node == startNode) {
122.211 + when = WHEN_DURING;
122.212 + }
122.213 +
122.214 + PythonTree oldParent = parent;
122.215 + parent = node;
122.216 + super.traverse(node);
122.217 + parent = oldParent;
122.218 +
122.219 + if (node == endNode) {
122.220 + when = WHEN_AFTER;
122.221 + }
122.222 +
122.223 + }
122.224 +
122.225 + private class UsageScope {
122.226 + UsageScope(PythonTree block) {
122.227 + this.block = block;
122.228 + }
122.229 +
122.230 + private void read(String name) {
122.231 + // No need to pass class references or constants in/out
122.232 + // TODO: Make this smarter such that what it really does
122.233 + // is ignore any variables that aren't defined locally - so
122.234 + // global variables for example aren't passed in since they
122.235 + // can -also- be accessed from the extracted method.
122.236 + if (Character.isUpperCase(name.charAt(0))) {
122.237 + return;
122.238 + }
122.239 +
122.240 + if (isWriting) {
122.241 + // A read in the AST for example on the left hand side of an
122.242 + // assignment is really a write
122.243 + write(name);
122.244 + return;
122.245 + }
122.246 +
122.247 + if (when == WHEN_DURING) {
122.248 + if (!writtenBeforeReadDuring.contains(name)) {
122.249 + readDuring.add(name);
122.250 + }
122.251 + } else if (when == WHEN_AFTER) {
122.252 + // I don't want a reassignment of the variable before it's been
122.253 + // read to count as a usage of the result from the fragment
122.254 + if (!writtenAfter.contains(name)) {
122.255 + readAfter.add(name);
122.256 + }
122.257 + }
122.258 + }
122.259 +
122.260 + private void write(String name) {
122.261 + // No need to pass class references or constants in/out
122.262 + // TODO: Make this smarter such that what it really does
122.263 + // is ignore any variables that aren't defined locally - so
122.264 + // global variables for example aren't passed in since they
122.265 + // can -also- be accessed from the extracted method.
122.266 + if (Character.isUpperCase(name.charAt(0))) {
122.267 + return;
122.268 + }
122.269 +
122.270 + if (when == WHEN_BEFORE) {
122.271 + writtenBefore.add(name);
122.272 + } else if (when == WHEN_DURING) {
122.273 + writtenDuring.add(name);
122.274 + if (ifs == 0 && !readDuring.contains(name)) {
122.275 + writtenBeforeReadDuring.add(name);
122.276 + }
122.277 + } else if (when == WHEN_AFTER) {
122.278 + if (ifs == 0 && !readAfter.contains(name)) {
122.279 + writtenAfter.add(name);
122.280 + }
122.281 + }
122.282 + }
122.283 +
122.284 + private void merge(UsageScope other) {
122.285 + writtenBefore.addAll(other.writtenBefore);
122.286 + readDuring.addAll(other.readDuring);
122.287 + writtenDuring.addAll(other.writtenDuring);
122.288 + writtenBeforeReadDuring.addAll(other.writtenBeforeReadDuring);
122.289 + writtenAfter.addAll(other.writtenAfter);
122.290 + readAfter.addAll(other.readAfter);
122.291 + }
122.292 + /** Block, or null if it's the local method */
122.293 + private PythonTree block;
122.294 + /** Variables that exist in scope before the code fragment */
122.295 + private final Set<String> writtenBefore = new HashSet<>();
122.296 + /** Variables that are read during the code fragment */
122.297 + private final Set<String> readDuring = new HashSet<>(); // rename readBeforeWrittenDuring
122.298 + /** Variables that are written to during the code fragment */
122.299 + private final Set<String> writtenDuring = new HashSet<>();
122.300 + /** Variables that are written to during the code fragment */
122.301 + private final Set<String> writtenBeforeReadDuring = new HashSet<>();
122.302 + /** Variables that are written PRIOR TO A READ OF THE SAME VAR after the code fragment */
122.303 + private final Set<String> writtenAfter = new HashSet<>(); // rename writtenBeforeReadAfter
122.304 + /** Variables that are read (prior to a write) after the code fragment */
122.305 + private final Set<String> readAfter = new HashSet<>(); // rename readBeforeWrittenAfter
122.306 + }
122.307 +}
123.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/NameRule.java Mon Sep 21 13:01:16 2015 +0200
123.3 @@ -0,0 +1,524 @@
123.4 +/*
123.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
123.6 + *
123.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
123.8 + *
123.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
123.10 + * Other names may be trademarks of their respective owners.
123.11 + *
123.12 + * The contents of this file are subject to the terms of either the GNU
123.13 + * General Public License Version 2 only ("GPL") or the Common
123.14 + * Development and Distribution License("CDDL") (collectively, the
123.15 + * "License"). You may not use this file except in compliance with the
123.16 + * License. You can obtain a copy of the License at
123.17 + * http://www.netbeans.org/cddl-gplv2.html
123.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
123.19 + * specific language governing permissions and limitations under the
123.20 + * License. When distributing the software, include this License Header
123.21 + * Notice in each file and include the License file at
123.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
123.23 + * particular file as subject to the "Classpath" exception as provided
123.24 + * by Oracle in the GPL Version 2 section of the License file that
123.25 + * accompanied this code. If applicable, add the following below the
123.26 + * License Header, with the fields enclosed by brackets [] replaced by
123.27 + * your own identifying information:
123.28 + * "Portions Copyrighted [year] [name of copyright owner]"
123.29 + *
123.30 + * Contributor(s):
123.31 + *
123.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
123.33 + */
123.34 +package org.netbeans.modules.python.hints;
123.35 +
123.36 +import org.netbeans.modules.python.source.NameStyle;
123.37 +import java.util.ArrayList;
123.38 +import java.util.Collections;
123.39 +import java.util.HashSet;
123.40 +import java.util.List;
123.41 +import java.util.Set;
123.42 +import java.util.prefs.Preferences;
123.43 +import javax.swing.JComponent;
123.44 +import org.netbeans.editor.BaseDocument;
123.45 +import org.netbeans.editor.Utilities;
123.46 +import org.netbeans.modules.csl.api.EditList;
123.47 +import org.netbeans.modules.csl.api.Hint;
123.48 +import org.netbeans.modules.csl.api.HintFix;
123.49 +import org.netbeans.modules.csl.api.HintSeverity;
123.50 +import org.netbeans.modules.csl.api.OffsetRange;
123.51 +import org.netbeans.modules.csl.api.PreviewableFix;
123.52 +import org.netbeans.modules.csl.api.RuleContext;
123.53 +import org.netbeans.modules.python.source.PythonAstUtils;
123.54 +import org.netbeans.modules.python.source.PythonParserResult;
123.55 +import org.netbeans.modules.python.source.PythonUtils;
123.56 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
123.57 +import org.openide.util.NbBundle;
123.58 +import org.python.antlr.PythonTree;
123.59 +import org.python.antlr.ast.ClassDef;
123.60 +import org.python.antlr.ast.FunctionDef;
123.61 +import org.python.antlr.ast.Module;
123.62 +import org.python.antlr.ast.arguments;
123.63 +
123.64 +import static org.netbeans.modules.python.source.NameStyle.*;
123.65 +
123.66 +/**
123.67 + * Check names to see if they conform to standard Python conventions.
123.68 + * These are documented here:
123.69 + * http://www.python.org/dev/peps/pep-0008/
123.70 + *
123.71 + * @todo Add fix to rename!
123.72 + * @todo Implement variable name checking!
123.73 + *
123.74 + *
123.75 + * @author Tor Norbye
123.76 + */
123.77 +public class NameRule extends PythonAstRule {
123.78 + private static final String CLASS_STYLE_NAME = "classStyle"; // NOI18N
123.79 + private static final String IGNORED_NAMES = "ignoredNames"; // NOI18N
123.80 + private static final String MODULE_STYLE_NAME = "moduleStyle"; // NOI18N
123.81 + private static final String FUNCTION_STYLE_NAME = "functionStyle"; // NOI18N
123.82 + private static final String SELF_REQUIRED_NAME = "selfRequired"; // NOI18N
123.83 + private static final String VARIABLE_STYLE_NAME = "variableStyle"; // NOI18N
123.84 + private static NameStyle moduleStyle;
123.85 + private static NameStyle functionStyle;
123.86 + private static NameStyle classStyle;
123.87 + private static NameStyle variableStyle;
123.88 + private static String ignoredNames;
123.89 + private static boolean selfRequired;
123.90 +
123.91 + public NameRule() {
123.92 + }
123.93 +
123.94 + @Override
123.95 + public boolean appliesTo(RuleContext context) {
123.96 + moduleStyle = null; // Ensure lazy init
123.97 +
123.98 + return true;
123.99 + }
123.100 +
123.101 + private static void initializeFromPrefs(PythonRuleContext context, NameRule rule) {
123.102 + Preferences pref = context.manager.getPreferences(rule);
123.103 + moduleStyle = getModuleNameStyle(pref);
123.104 + classStyle = getClassNameStyle(pref);
123.105 + functionStyle = getFunctionNameStyle(pref);
123.106 + variableStyle = getVariableNameStyle(pref);
123.107 + ignoredNames = getIgnoredNames(pref);
123.108 + selfRequired = isSelfRequired(pref);
123.109 + }
123.110 +
123.111 + @Override
123.112 + public Set<Class> getKinds() {
123.113 + Set<Class> classes = new HashSet<>();
123.114 + classes.add(Module.class);
123.115 + classes.add(FunctionDef.class);
123.116 + classes.add(ClassDef.class);
123.117 +
123.118 + return classes;
123.119 + }
123.120 +
123.121 + @Override
123.122 + public void run(PythonRuleContext context, List<Hint> result) {
123.123 + if (moduleStyle == null) {
123.124 + initializeFromPrefs(context, this);
123.125 + }
123.126 +
123.127 + // TODO - check module name!!
123.128 +
123.129 + PythonTree node = context.node;
123.130 + if (node instanceof Module) {
123.131 + if (moduleStyle != NO_PREFERENCE) {
123.132 + String moduleName = PythonUtils.getModuleName(context.parserResult.getSnapshot().getSource().getFileObject());
123.133 + if (!moduleStyle.complies(moduleName) && !moduleStyle.complies(moduleName.substring(moduleName.lastIndexOf('.') + 1))) {
123.134 + String typeKey = "Module"; // NOI18N
123.135 + String message = NbBundle.getMessage(NameRule.class, "WrongStyle", moduleName,
123.136 + NbBundle.getMessage(NameRule.class, typeKey),
123.137 + moduleStyle.getDisplayName());
123.138 + List<HintFix> hintFixes = getNameStyleFixes(moduleName, context, moduleStyle, MODULE_STYLE_NAME, typeKey);
123.139 + addError(moduleName, context, message, node, result, hintFixes);
123.140 + }
123.141 + }
123.142 + } else if (node instanceof FunctionDef) {
123.143 + FunctionDef def = (FunctionDef)node;
123.144 + if (functionStyle != NO_PREFERENCE) {
123.145 + if (!functionStyle.complies(def.getInternalName())) {
123.146 + String typeKey = "Function"; // NOI18N
123.147 + String message = NbBundle.getMessage(NameRule.class, "WrongStyle", def.getInternalName(),
123.148 + NbBundle.getMessage(NameRule.class, typeKey),
123.149 + functionStyle.getDisplayName());
123.150 + List<HintFix> hintFixes = getNameStyleFixes(def.getInternalName(), context, functionStyle, FUNCTION_STYLE_NAME, typeKey);
123.151 + addError(def.getInternalName(), context, message, def, result, hintFixes);
123.152 + }
123.153 + }
123.154 +
123.155 + // Functions should have a first argument of name "self"
123.156 + if (selfRequired && !PythonAstUtils.isStaticMethod(def)) {
123.157 + arguments args = def.getInternalArgs();
123.158 + if (args.getInternalArgs().size() > 0) {
123.159 + String name = PythonAstUtils.getName(args.getInternalArgs().get(0));
123.160 + if (!("self".equals(name) || "cls".equals(name))) { // NOI18N
123.161 + // Make sure it's a class; other methods don't have to
123.162 + if (PythonAstUtils.isClassMethod(context.path, def)) {
123.163 + String message = NbBundle.getMessage(NameRule.class,
123.164 + // TODO - determine if it should be cls or def
123.165 + "NameRuleWrongArg", // NOI18N
123.166 + name);
123.167 + List<HintFix> fixList = new ArrayList<>(2);
123.168 + fixList.add(new SelfParamFix(context, true, def, null));
123.169 + List<String> parameters = PythonAstUtils.getParameters(def);
123.170 + if (parameters.size() > 0) {
123.171 + fixList.add(new SelfParamFix(context, false, def, parameters.get(0)));
123.172 + }
123.173 + addError(null, context, message, args, result, fixList);
123.174 + }
123.175 + }
123.176 + } else if (PythonAstUtils.isClassMethod(context.path, def)) {
123.177 + String message = NbBundle.getMessage(NameRule.class,
123.178 + // TODO - determine if it should be cls or def
123.179 + "NameRuleWrongNoArg"); // NOI18N
123.180 + List<HintFix> fixList = Collections.<HintFix>singletonList(new SelfParamFix(context, true, def, null));
123.181 + addError(null, context, message, args, result, fixList);
123.182 + }
123.183 + }
123.184 + } else if (node instanceof ClassDef) {
123.185 + if (functionStyle != NO_PREFERENCE) {
123.186 + ClassDef def = (ClassDef)node;
123.187 + if (!classStyle.complies(def.getInternalName())) {
123.188 + String typeKey = "Class"; // NOI18N
123.189 + String message = NbBundle.getMessage(NameRule.class, "WrongStyle", def.getInternalName(),
123.190 + NbBundle.getMessage(NameRule.class, typeKey),
123.191 + classStyle.getDisplayName());
123.192 + List<HintFix> hintFixes = getNameStyleFixes(def.getInternalName(), context, classStyle, CLASS_STYLE_NAME, typeKey);
123.193 + addError(def.getInternalName(), context, message, def, result, hintFixes);
123.194 + }
123.195 + }
123.196 + }
123.197 + }
123.198 +
123.199 + private List<HintFix> getNameStyleFixes(String name, PythonRuleContext context, NameStyle currentStyle, String key, String type) {
123.200 + List<HintFix> fixes = new ArrayList<>(5);
123.201 +
123.202 + fixes.add(new IgnoreWordFix(name, this, context));
123.203 +
123.204 + for (NameStyle style : NameStyle.values()) {
123.205 + if (style == currentStyle || style == NO_PREFERENCE) {
123.206 + continue;
123.207 + }
123.208 +
123.209 + if (style.complies(name)) {
123.210 + ChangeStyleFix cs = new ChangeStyleFix(this, context, style, key, type);
123.211 + fixes.add(cs);
123.212 + }
123.213 + }
123.214 +
123.215 + // No preference always last
123.216 + fixes.add(new ChangeStyleFix(this, context, NO_PREFERENCE, key, type));
123.217 +
123.218 + return fixes;
123.219 + }
123.220 +
123.221 + private void addError(String name, PythonRuleContext context, String message, PythonTree node, List<Hint> result, List<HintFix> fixList) {
123.222 + if (name != null && ignoredNames.length() > 0) {
123.223 + for (String ignoredName : ignoredNames.split(",")) { // NOI18N
123.224 + ignoredName = ignoredName.trim();
123.225 + if (name.equals(ignoredName)) {
123.226 + return;
123.227 + }
123.228 + }
123.229 + }
123.230 +
123.231 + PythonParserResult info = (PythonParserResult)context.parserResult;
123.232 + OffsetRange range;
123.233 + if (node instanceof Module) {
123.234 + range = new OffsetRange(0, 0);
123.235 + } else {
123.236 +
123.237 + range = PythonAstUtils.getNameRange(info, node);
123.238 + }
123.239 + range = PythonLexerUtils.getLexerOffsets(info, range);
123.240 + if (range != OffsetRange.NONE) {
123.241 + if (fixList == null) {
123.242 + fixList = Collections.emptyList();
123.243 + }
123.244 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 1500);
123.245 + result.add(desc);
123.246 + }
123.247 + }
123.248 +
123.249 + @Override
123.250 + public String getId() {
123.251 + return "NameRule"; // NOI18N
123.252 + }
123.253 +
123.254 + @Override
123.255 + public String getDisplayName() {
123.256 + return NbBundle.getMessage(NameRule.class, "NameRule");
123.257 + }
123.258 +
123.259 + @Override
123.260 + public String getDescription() {
123.261 + return NbBundle.getMessage(NameRule.class, "NameRuleDesc");
123.262 + }
123.263 +
123.264 + @Override
123.265 + public boolean getDefaultEnabled() {
123.266 + return true;
123.267 + }
123.268 +
123.269 + @Override
123.270 + public boolean showInTasklist() {
123.271 + return true;
123.272 + }
123.273 +
123.274 + @Override
123.275 + public HintSeverity getDefaultSeverity() {
123.276 + return HintSeverity.WARNING;
123.277 + }
123.278 +
123.279 + @Override
123.280 + public JComponent getCustomizer(Preferences node) {
123.281 + moduleStyle = null; // Ensure lazy init after this
123.282 + return new NameRulePrefs(this, node);
123.283 + }
123.284 +
123.285 + static NameStyle getNameStyle(String key, NameStyle deflt, Preferences pref) {
123.286 + String value = pref.get(key, deflt.name());
123.287 +
123.288 + return NameStyle.valueOf(value);
123.289 + }
123.290 +
123.291 + static NameStyle getModuleNameStyle(Preferences pref) {
123.292 + return getNameStyle(MODULE_STYLE_NAME, NameStyle.NO_PREFERENCE, pref);
123.293 + }
123.294 +
123.295 + static NameStyle getClassNameStyle(Preferences pref) {
123.296 + return getNameStyle(CLASS_STYLE_NAME, NameStyle.CAPITALIZED_WORDS, pref);
123.297 + }
123.298 +
123.299 + static NameStyle getVariableNameStyle(Preferences pref) {
123.300 + return getNameStyle(VARIABLE_STYLE_NAME, NameStyle.LOWERCASE_WITH_UNDERSCORES, pref);
123.301 + }
123.302 +
123.303 + static NameStyle getFunctionNameStyle(Preferences pref) {
123.304 + return getNameStyle(FUNCTION_STYLE_NAME, NameStyle.LOWERCASE_WITH_UNDERSCORES, pref);
123.305 + }
123.306 +
123.307 + static boolean isSelfRequired(Preferences pref) {
123.308 + return pref.getBoolean(SELF_REQUIRED_NAME, true);
123.309 + }
123.310 +
123.311 + static String getIgnoredNames(Preferences pref) {
123.312 + return pref.get(IGNORED_NAMES, "");
123.313 + }
123.314 +
123.315 + void setModuleNameStyle(Preferences pref, NameStyle style) {
123.316 + pref.put(MODULE_STYLE_NAME, style.name());
123.317 + }
123.318 +
123.319 + void setClassNameStyle(Preferences pref, NameStyle style) {
123.320 + pref.put(CLASS_STYLE_NAME, style.name());
123.321 + }
123.322 +
123.323 + void setFunctionNameStyle(Preferences pref, NameStyle style) {
123.324 + pref.put(FUNCTION_STYLE_NAME, style.name());
123.325 + }
123.326 +
123.327 + void setVariableNameStyle(Preferences pref, NameStyle style) {
123.328 + pref.put(VARIABLE_STYLE_NAME, style.name());
123.329 + }
123.330 +
123.331 + void setIgnoredNames(Preferences pref, String ignoredNames) {
123.332 + pref.put(IGNORED_NAMES, ignoredNames);
123.333 + }
123.334 +
123.335 + void setSelfRequired(Preferences pref, boolean requireSelf) {
123.336 + pref.putBoolean(SELF_REQUIRED_NAME, requireSelf);
123.337 + }
123.338 +
123.339 + private static class IgnoreWordFix implements HintFix {
123.340 + private String name;
123.341 + private NameRule rule;
123.342 + private PythonRuleContext context;
123.343 +
123.344 + public IgnoreWordFix(String name, NameRule rule, PythonRuleContext context) {
123.345 + this.name = name;
123.346 + this.rule = rule;
123.347 + this.context = context;
123.348 + }
123.349 +
123.350 + @Override
123.351 + public String getDescription() {
123.352 + return NbBundle.getMessage(NameRule.class, "IgnoreWord", name);
123.353 + }
123.354 +
123.355 + @Override
123.356 + public void implement() throws Exception {
123.357 + Preferences pref = context.manager.getPreferences(rule);
123.358 + String ignored = getIgnoredNames(pref);
123.359 + if (ignored.length() > 0) {
123.360 + ignored = ignored + "," + name; // NOI18N
123.361 + } else {
123.362 + ignored = name;
123.363 + }
123.364 + pref.put(IGNORED_NAMES, ignored);
123.365 +
123.366 + context.manager.refreshHints(context);
123.367 + }
123.368 +
123.369 + @Override
123.370 + public boolean isSafe() {
123.371 + return true;
123.372 + }
123.373 +
123.374 + @Override
123.375 + public boolean isInteractive() {
123.376 + return true;
123.377 + }
123.378 + }
123.379 +
123.380 + private static class ChangeStyleFix implements HintFix {
123.381 + private NameRule rule;
123.382 + private PythonRuleContext context;
123.383 + private NameStyle style;
123.384 + private String key;
123.385 + private String typeKey;
123.386 +
123.387 + public ChangeStyleFix(NameRule rule, PythonRuleContext context, NameStyle style, String key, String type) {
123.388 + this.rule = rule;
123.389 + this.context = context;
123.390 + this.style = style;
123.391 + this.key = key;
123.392 + this.typeKey = type;
123.393 + }
123.394 +
123.395 + @Override
123.396 + public String getDescription() {
123.397 + if (style == NO_PREFERENCE) {
123.398 + return NbBundle.getMessage(NameRule.class, "ChangeNoStyle", NbBundle.getMessage(NameRule.class, typeKey));
123.399 + } else {
123.400 + return NbBundle.getMessage(NameRule.class, "ChangeStyle", NbBundle.getMessage(NameRule.class, typeKey), style.getDisplayName());
123.401 + }
123.402 + }
123.403 +
123.404 + @Override
123.405 + public void implement() throws Exception {
123.406 + Preferences pref = context.manager.getPreferences(rule);
123.407 + pref.put(key, style.name());
123.408 +
123.409 + context.manager.refreshHints(context);
123.410 + }
123.411 +
123.412 + @Override
123.413 + public boolean isSafe() {
123.414 + return true;
123.415 + }
123.416 +
123.417 + @Override
123.418 + public boolean isInteractive() {
123.419 + return true;
123.420 + }
123.421 + }
123.422 +
123.423 + /**
123.424 + * Fix to insert self argument or rename first argument to self
123.425 + */
123.426 + private static class SelfParamFix implements PreviewableFix {
123.427 + private final PythonRuleContext context;
123.428 + private final FunctionDef func;
123.429 + private final boolean insert;
123.430 + private final String first;
123.431 +
123.432 + private SelfParamFix(PythonRuleContext context, boolean insert, FunctionDef func, String first) {
123.433 + this.context = context;
123.434 + this.insert = insert;
123.435 + this.func = func;
123.436 + this.first = first;
123.437 +
123.438 + assert insert || first != null;
123.439 + }
123.440 +
123.441 + @Override
123.442 + public String getDescription() {
123.443 + if (insert) {
123.444 + return NbBundle.getMessage(CreateDocString.class, "InsertSelf");
123.445 + } else {
123.446 + return NbBundle.getMessage(CreateDocString.class, "RenameSelf", first);
123.447 + }
123.448 + }
123.449 +
123.450 + @Override
123.451 + public boolean canPreview() {
123.452 + return true;
123.453 + }
123.454 +
123.455 + @Override
123.456 + public EditList getEditList() throws Exception {
123.457 + return getEditList(true);
123.458 + }
123.459 +
123.460 + private EditList getEditList(boolean previewOnly) throws Exception {
123.461 + BaseDocument doc = context.doc;
123.462 + EditList edits = new EditList(doc);
123.463 +
123.464 + OffsetRange astRange = PythonAstUtils.getNameRange((PythonParserResult) context.parserResult, func);
123.465 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
123.466 + if (lexRange == OffsetRange.NONE) {
123.467 + return edits;
123.468 + }
123.469 + int paramStart = lexRange.getEnd();
123.470 + if (insert) {
123.471 + String missing;
123.472 + int lineEnd = Utilities.getRowEnd(doc, paramStart);
123.473 + int offset = paramStart;
123.474 + if (lineEnd > paramStart) {
123.475 + String line = doc.getText(paramStart, lineEnd - paramStart);
123.476 + int paren = line.indexOf('(');
123.477 + int colon = line.indexOf(':');
123.478 + if (paren != -1) {
123.479 + offset = paramStart + paren + 1;
123.480 + missing = "self"; // NOI18N
123.481 + List<String> parameters = PythonAstUtils.getParameters(func);
123.482 + if (parameters.size() > 0) {
123.483 + missing = "self, "; // NOI18N
123.484 + } else {
123.485 + missing = "self"; // NOI18N
123.486 + }
123.487 + } else if (colon != -1) {
123.488 + offset = paramStart + colon;
123.489 + missing = "(self)"; // NOI18N
123.490 + } else {
123.491 + return edits;
123.492 + }
123.493 + } else {
123.494 + missing = "(self)"; // NOI18N
123.495 + }
123.496 + edits.replace(offset, 0, missing, false, 0);
123.497 + } else {
123.498 + String text = doc.getText(paramStart, doc.getLength() - paramStart);
123.499 + int offset = text.indexOf(first);
123.500 + if (offset != -1) {
123.501 + offset += paramStart;
123.502 + edits.replace(offset, first.length(), "self", false, 0); // NOI18N
123.503 + }
123.504 + }
123.505 +
123.506 +
123.507 + return edits;
123.508 + }
123.509 +
123.510 + @Override
123.511 + public void implement() throws Exception {
123.512 + EditList edits = getEditList(true);
123.513 +
123.514 + edits.apply();
123.515 + }
123.516 +
123.517 + @Override
123.518 + public boolean isSafe() {
123.519 + return true;
123.520 + }
123.521 +
123.522 + @Override
123.523 + public boolean isInteractive() {
123.524 + return false;
123.525 + }
123.526 + }
123.527 +}
124.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
124.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/NameRulePrefs.form Mon Sep 21 13:01:16 2015 +0200
124.3 @@ -0,0 +1,182 @@
124.4 +<?xml version="1.0" encoding="UTF-8" ?>
124.5 +
124.6 +<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
124.7 + <AuxValues>
124.8 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
124.9 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
124.10 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
124.11 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
124.12 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
124.13 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
124.14 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
124.15 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
124.16 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
124.17 + </AuxValues>
124.18 +
124.19 + <Layout>
124.20 + <DimensionLayout dim="0">
124.21 + <Group type="103" groupAlignment="0" attributes="0">
124.22 + <Group type="102" attributes="0">
124.23 + <Group type="103" groupAlignment="0" attributes="0">
124.24 + <Group type="102" alignment="0" attributes="0">
124.25 + <Group type="103" groupAlignment="0" attributes="0">
124.26 + <Component id="moduleLabel" alignment="0" min="-2" max="-2" attributes="0"/>
124.27 + <Component id="classLabel" alignment="0" min="-2" max="-2" attributes="0"/>
124.28 + <Component id="functionLabel" alignment="0" min="-2" max="-2" attributes="0"/>
124.29 + <Component id="variableLabel" alignment="0" min="-2" max="-2" attributes="0"/>
124.30 + </Group>
124.31 + <EmptySpace max="-2" attributes="0"/>
124.32 + <Group type="103" groupAlignment="1" max="-2" attributes="0">
124.33 + <Component id="variableCombo" alignment="0" max="32767" attributes="1"/>
124.34 + <Component id="classCombo" alignment="0" max="32767" attributes="1"/>
124.35 + <Component id="moduleCombo" alignment="0" pref="234" max="32767" attributes="1"/>
124.36 + <Component id="functionCombo" alignment="1" max="32767" attributes="1"/>
124.37 + </Group>
124.38 + </Group>
124.39 + <Component id="parameterLabel" alignment="0" min="-2" max="-2" attributes="0"/>
124.40 + <Component id="selfCb" alignment="0" min="-2" max="-2" attributes="0"/>
124.41 + <Group type="102" alignment="0" attributes="0">
124.42 + <Component id="ignoreLabel" min="-2" max="-2" attributes="0"/>
124.43 + <EmptySpace max="-2" attributes="0"/>
124.44 + <Component id="ignoredText" max="32767" attributes="0"/>
124.45 + </Group>
124.46 + </Group>
124.47 + <EmptySpace max="-2" attributes="0"/>
124.48 + </Group>
124.49 + </Group>
124.50 + </DimensionLayout>
124.51 + <DimensionLayout dim="1">
124.52 + <Group type="103" groupAlignment="0" attributes="0">
124.53 + <Group type="102" alignment="0" attributes="0">
124.54 + <Group type="103" groupAlignment="3" attributes="0">
124.55 + <Component id="moduleLabel" alignment="3" min="-2" max="-2" attributes="0"/>
124.56 + <Component id="moduleCombo" alignment="3" min="-2" max="-2" attributes="0"/>
124.57 + </Group>
124.58 + <EmptySpace max="-2" attributes="0"/>
124.59 + <Group type="103" groupAlignment="3" attributes="0">
124.60 + <Component id="classLabel" alignment="3" min="-2" max="-2" attributes="0"/>
124.61 + <Component id="classCombo" alignment="3" min="-2" max="-2" attributes="0"/>
124.62 + </Group>
124.63 + <EmptySpace max="-2" attributes="0"/>
124.64 + <Group type="103" groupAlignment="3" attributes="0">
124.65 + <Component id="functionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
124.66 + <Component id="functionCombo" alignment="3" min="-2" max="-2" attributes="0"/>
124.67 + </Group>
124.68 + <EmptySpace max="-2" attributes="0"/>
124.69 + <Group type="103" groupAlignment="3" attributes="0">
124.70 + <Component id="variableLabel" alignment="3" min="-2" max="-2" attributes="0"/>
124.71 + <Component id="variableCombo" alignment="3" min="-2" max="-2" attributes="0"/>
124.72 + </Group>
124.73 + <EmptySpace type="separate" max="-2" attributes="0"/>
124.74 + <Component id="parameterLabel" min="-2" max="-2" attributes="0"/>
124.75 + <EmptySpace max="-2" attributes="0"/>
124.76 + <Component id="selfCb" min="-2" max="-2" attributes="0"/>
124.77 + <EmptySpace type="separate" max="-2" attributes="0"/>
124.78 + <Group type="103" groupAlignment="3" attributes="0">
124.79 + <Component id="ignoreLabel" alignment="3" min="-2" max="-2" attributes="0"/>
124.80 + <Component id="ignoredText" alignment="3" min="-2" max="-2" attributes="0"/>
124.81 + </Group>
124.82 + <EmptySpace max="32767" attributes="0"/>
124.83 + </Group>
124.84 + </Group>
124.85 + </DimensionLayout>
124.86 + </Layout>
124.87 + <SubComponents>
124.88 + <Component class="javax.swing.JLabel" name="classLabel">
124.89 + <Properties>
124.90 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.91 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.classLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.92 + </Property>
124.93 + </Properties>
124.94 + </Component>
124.95 + <Component class="javax.swing.JLabel" name="functionLabel">
124.96 + <Properties>
124.97 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.98 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.functionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.99 + </Property>
124.100 + </Properties>
124.101 + </Component>
124.102 + <Component class="javax.swing.JLabel" name="moduleLabel">
124.103 + <Properties>
124.104 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.105 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.moduleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.106 + </Property>
124.107 + </Properties>
124.108 + </Component>
124.109 + <Component class="javax.swing.JLabel" name="parameterLabel">
124.110 + <Properties>
124.111 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.112 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.parameterLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.113 + </Property>
124.114 + </Properties>
124.115 + </Component>
124.116 + <Component class="javax.swing.JCheckBox" name="selfCb">
124.117 + <Properties>
124.118 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.119 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.selfCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.120 + </Property>
124.121 + </Properties>
124.122 + <Events>
124.123 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
124.124 + </Events>
124.125 + </Component>
124.126 + <Component class="javax.swing.JComboBox" name="moduleCombo">
124.127 + <Properties>
124.128 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
124.129 + <Connection code="getNameStyleModel()" type="code"/>
124.130 + </Property>
124.131 + </Properties>
124.132 + <Events>
124.133 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
124.134 + </Events>
124.135 + </Component>
124.136 + <Component class="javax.swing.JComboBox" name="classCombo">
124.137 + <Properties>
124.138 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
124.139 + <Connection code="getNameStyleModel()" type="code"/>
124.140 + </Property>
124.141 + </Properties>
124.142 + <Events>
124.143 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
124.144 + </Events>
124.145 + </Component>
124.146 + <Component class="javax.swing.JComboBox" name="functionCombo">
124.147 + <Properties>
124.148 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
124.149 + <Connection code="getNameStyleModel()" type="code"/>
124.150 + </Property>
124.151 + </Properties>
124.152 + <Events>
124.153 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
124.154 + </Events>
124.155 + </Component>
124.156 + <Component class="javax.swing.JLabel" name="variableLabel">
124.157 + <Properties>
124.158 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.159 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.variableLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.160 + </Property>
124.161 + <Property name="enabled" type="boolean" value="false"/>
124.162 + </Properties>
124.163 + </Component>
124.164 + <Component class="javax.swing.JComboBox" name="variableCombo">
124.165 + <Properties>
124.166 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
124.167 + <Connection code="getNameStyleModel()" type="code"/>
124.168 + </Property>
124.169 + <Property name="enabled" type="boolean" value="false"/>
124.170 + </Properties>
124.171 + <Events>
124.172 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
124.173 + </Events>
124.174 + </Component>
124.175 + <Component class="javax.swing.JLabel" name="ignoreLabel">
124.176 + <Properties>
124.177 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
124.178 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.ignoreLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
124.179 + </Property>
124.180 + </Properties>
124.181 + </Component>
124.182 + <Component class="javax.swing.JTextField" name="ignoredText">
124.183 + </Component>
124.184 + </SubComponents>
124.185 +</Form>
125.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/NameRulePrefs.java Mon Sep 21 13:01:16 2015 +0200
125.3 @@ -0,0 +1,292 @@
125.4 +/*
125.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
125.6 + *
125.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
125.8 + *
125.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
125.10 + * Other names may be trademarks of their respective owners.
125.11 + *
125.12 + * The contents of this file are subject to the terms of either the GNU
125.13 + * General Public License Version 2 only ("GPL") or the Common
125.14 + * Development and Distribution License("CDDL") (collectively, the
125.15 + * "License"). You may not use this file except in compliance with the
125.16 + * License. You can obtain a copy of the License at
125.17 + * http://www.netbeans.org/cddl-gplv2.html
125.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
125.19 + * specific language governing permissions and limitations under the
125.20 + * License. When distributing the software, include this License Header
125.21 + * Notice in each file and include the License file at
125.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
125.23 + * particular file as subject to the "Classpath" exception as provided
125.24 + * by Oracle in the GPL Version 2 section of the License file that
125.25 + * accompanied this code. If applicable, add the following below the
125.26 + * License Header, with the fields enclosed by brackets [] replaced by
125.27 + * your own identifying information:
125.28 + * "Portions Copyrighted [year] [name of copyright owner]"
125.29 + *
125.30 + * If you wish your version of this file to be governed by only the CDDL
125.31 + * or only the GPL Version 2, indicate your decision by adding
125.32 + * "[Contributor] elects to include this software in this distribution
125.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
125.34 + * single choice of license, a recipient has the option to distribute
125.35 + * your version of this file under either the CDDL, the GPL Version 2 or
125.36 + * to extend the choice of license to its licensees as provided above.
125.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
125.38 + * Version 2 license, then the option applies only if the new code is
125.39 + * made subject to such option by the copyright holder.
125.40 + *
125.41 + * Contributor(s):
125.42 + *
125.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
125.44 + */
125.45 +package org.netbeans.modules.python.hints;
125.46 +
125.47 +import org.netbeans.modules.python.source.NameStyle;
125.48 +import java.awt.Component;
125.49 +import java.util.prefs.Preferences;
125.50 +import javax.swing.ComboBoxModel;
125.51 +import javax.swing.DefaultComboBoxModel;
125.52 +import javax.swing.JLabel;
125.53 +import javax.swing.JList;
125.54 +import javax.swing.ListCellRenderer;
125.55 +
125.56 +/**
125.57 + *
125.58 + * @author Tor Norbye
125.59 + */
125.60 +public class NameRulePrefs extends javax.swing.JPanel {
125.61 + private NameRule rule;
125.62 + private Preferences prefs;
125.63 +
125.64 + /** Creates new form NameRulePrefs */
125.65 + public NameRulePrefs(NameRule rule, Preferences prefs) {
125.66 + this.rule = rule;
125.67 + this.prefs = prefs;
125.68 +
125.69 + initComponents();
125.70 +
125.71 + ListCellRenderer renderer = new NameStyleRenderer();
125.72 + moduleCombo.setRenderer(renderer);
125.73 + functionCombo.setRenderer(renderer);
125.74 + classCombo.setRenderer(renderer);
125.75 + variableCombo.setRenderer(renderer);
125.76 +
125.77 + moduleCombo.setSelectedItem(NameRule.getModuleNameStyle(prefs));
125.78 + functionCombo.setSelectedItem(NameRule.getFunctionNameStyle(prefs));
125.79 + classCombo.setSelectedItem(NameRule.getClassNameStyle(prefs));
125.80 + variableCombo.setSelectedItem(NameRule.getVariableNameStyle(prefs));
125.81 +
125.82 + selfCb.setSelected(NameRule.isSelfRequired(prefs));
125.83 + ignoredText.setText(NameRule.getIgnoredNames(prefs));
125.84 + }
125.85 +
125.86 + private ComboBoxModel getNameStyleModel() {
125.87 + return new DefaultComboBoxModel(NameStyle.values());
125.88 + }
125.89 +
125.90 + private static class NameStyleRenderer extends JLabel implements ListCellRenderer/*, UIResource*/ {
125.91 + public NameStyleRenderer() {
125.92 + setOpaque(true);
125.93 + }
125.94 +
125.95 + @Override
125.96 + public Component getListCellRendererComponent(JList list, Object value,
125.97 + int index, boolean isSelected, boolean cellHasFocus) {
125.98 + // #93658: GTK needs name to render cell renderer "natively"
125.99 + setName("ComboBox.listRenderer"); // NOI18N
125.100 +
125.101 + if (isSelected) {
125.102 + setBackground(list.getSelectionBackground());
125.103 + setForeground(list.getSelectionForeground());
125.104 + } else {
125.105 + setBackground(list.getBackground());
125.106 + setForeground(list.getForeground());
125.107 + }
125.108 +
125.109 + if (value instanceof NameStyle) {
125.110 + setText(((NameStyle)value).getDisplayName());
125.111 + }
125.112 +
125.113 + return this;
125.114 + }
125.115 +
125.116 + // #93658: GTK needs name to render cell renderer "natively"
125.117 + public
125.118 + @Override
125.119 + String getName() {
125.120 + String name = super.getName();
125.121 + return name == null ? "ComboBox.renderer" : name; // NOI18N
125.122 + }
125.123 + }
125.124 +
125.125 + /** This method is called from within the constructor to
125.126 + * initialize the form.
125.127 + * WARNING: Do NOT modify this code. The content of this method is
125.128 + * always regenerated by the Form Editor.
125.129 + */
125.130 + @SuppressWarnings("unchecked")
125.131 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
125.132 + private void initComponents() {
125.133 +
125.134 + classLabel = new javax.swing.JLabel();
125.135 + functionLabel = new javax.swing.JLabel();
125.136 + moduleLabel = new javax.swing.JLabel();
125.137 + parameterLabel = new javax.swing.JLabel();
125.138 + selfCb = new javax.swing.JCheckBox();
125.139 + moduleCombo = new javax.swing.JComboBox();
125.140 + classCombo = new javax.swing.JComboBox();
125.141 + functionCombo = new javax.swing.JComboBox();
125.142 + variableLabel = new javax.swing.JLabel();
125.143 + variableCombo = new javax.swing.JComboBox();
125.144 + ignoreLabel = new javax.swing.JLabel();
125.145 + ignoredText = new javax.swing.JTextField();
125.146 +
125.147 + classLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.classLabel.text")); // NOI18N
125.148 +
125.149 + functionLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.functionLabel.text")); // NOI18N
125.150 +
125.151 + moduleLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.moduleLabel.text")); // NOI18N
125.152 +
125.153 + parameterLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.parameterLabel.text")); // NOI18N
125.154 +
125.155 + selfCb.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.selfCb.text")); // NOI18N
125.156 + selfCb.addActionListener(new java.awt.event.ActionListener() {
125.157 + public void actionPerformed(java.awt.event.ActionEvent evt) {
125.158 + changed(evt);
125.159 + }
125.160 + });
125.161 +
125.162 + moduleCombo.setModel(getNameStyleModel());
125.163 + moduleCombo.addActionListener(new java.awt.event.ActionListener() {
125.164 + public void actionPerformed(java.awt.event.ActionEvent evt) {
125.165 + changed(evt);
125.166 + }
125.167 + });
125.168 +
125.169 + classCombo.setModel(getNameStyleModel());
125.170 + classCombo.addActionListener(new java.awt.event.ActionListener() {
125.171 + public void actionPerformed(java.awt.event.ActionEvent evt) {
125.172 + changed(evt);
125.173 + }
125.174 + });
125.175 +
125.176 + functionCombo.setModel(getNameStyleModel());
125.177 + functionCombo.addActionListener(new java.awt.event.ActionListener() {
125.178 + public void actionPerformed(java.awt.event.ActionEvent evt) {
125.179 + changed(evt);
125.180 + }
125.181 + });
125.182 +
125.183 + variableLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.variableLabel.text")); // NOI18N
125.184 + variableLabel.setEnabled(false);
125.185 +
125.186 + variableCombo.setModel(getNameStyleModel());
125.187 + variableCombo.setEnabled(false);
125.188 + variableCombo.addActionListener(new java.awt.event.ActionListener() {
125.189 + public void actionPerformed(java.awt.event.ActionEvent evt) {
125.190 + changed(evt);
125.191 + }
125.192 + });
125.193 +
125.194 + ignoreLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.ignoreLabel.text")); // NOI18N
125.195 +
125.196 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
125.197 + this.setLayout(layout);
125.198 + layout.setHorizontalGroup(
125.199 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
125.200 + .addGroup(layout.createSequentialGroup()
125.201 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
125.202 + .addGroup(layout.createSequentialGroup()
125.203 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
125.204 + .addComponent(moduleLabel)
125.205 + .addComponent(classLabel)
125.206 + .addComponent(functionLabel)
125.207 + .addComponent(variableLabel))
125.208 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
125.209 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
125.210 + .addComponent(variableCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
125.211 + .addComponent(classCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
125.212 + .addComponent(moduleCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, 234, Short.MAX_VALUE)
125.213 + .addComponent(functionCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
125.214 + .addComponent(parameterLabel)
125.215 + .addComponent(selfCb)
125.216 + .addGroup(layout.createSequentialGroup()
125.217 + .addComponent(ignoreLabel)
125.218 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
125.219 + .addComponent(ignoredText)))
125.220 + .addContainerGap())
125.221 + );
125.222 + layout.setVerticalGroup(
125.223 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
125.224 + .addGroup(layout.createSequentialGroup()
125.225 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
125.226 + .addComponent(moduleLabel)
125.227 + .addComponent(moduleCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
125.228 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
125.229 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
125.230 + .addComponent(classLabel)
125.231 + .addComponent(classCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
125.232 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
125.233 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
125.234 + .addComponent(functionLabel)
125.235 + .addComponent(functionCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
125.236 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
125.237 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
125.238 + .addComponent(variableLabel)
125.239 + .addComponent(variableCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
125.240 + .addGap(18, 18, 18)
125.241 + .addComponent(parameterLabel)
125.242 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
125.243 + .addComponent(selfCb)
125.244 + .addGap(18, 18, 18)
125.245 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
125.246 + .addComponent(ignoreLabel)
125.247 + .addComponent(ignoredText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
125.248 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
125.249 + );
125.250 + }// </editor-fold>//GEN-END:initComponents
125.251 +
125.252 + private void changed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changed
125.253 + Object source = evt.getSource();
125.254 +
125.255 + if (source == moduleCombo) {
125.256 + NameStyle style = (NameStyle)moduleCombo.getSelectedItem();
125.257 + if (style != null) {
125.258 + rule.setModuleNameStyle(prefs, style);
125.259 + }
125.260 + } else if (source == functionCombo) {
125.261 + NameStyle style = (NameStyle)functionCombo.getSelectedItem();
125.262 + if (style != null) {
125.263 + rule.setFunctionNameStyle(prefs, style);
125.264 + }
125.265 + } else if (source == classCombo) {
125.266 + NameStyle style = (NameStyle)classCombo.getSelectedItem();
125.267 + if (style != null) {
125.268 + rule.setClassNameStyle(prefs, style);
125.269 + }
125.270 + } else if (source == variableCombo) {
125.271 + NameStyle style = (NameStyle)variableCombo.getSelectedItem();
125.272 + if (style != null) {
125.273 + rule.setVariableNameStyle(prefs, style);
125.274 + }
125.275 + } else if (source == ignoredText) {
125.276 + rule.setIgnoredNames(prefs, ignoredText.getText().trim());
125.277 + } else if (source == selfCb) {
125.278 + rule.setSelfRequired(prefs, selfCb.isSelected());
125.279 + }
125.280 + }//GEN-LAST:event_changed
125.281 + // Variables declaration - do not modify//GEN-BEGIN:variables
125.282 + private javax.swing.JComboBox classCombo;
125.283 + private javax.swing.JLabel classLabel;
125.284 + private javax.swing.JComboBox functionCombo;
125.285 + private javax.swing.JLabel functionLabel;
125.286 + private javax.swing.JLabel ignoreLabel;
125.287 + private javax.swing.JTextField ignoredText;
125.288 + private javax.swing.JComboBox moduleCombo;
125.289 + private javax.swing.JLabel moduleLabel;
125.290 + private javax.swing.JLabel parameterLabel;
125.291 + private javax.swing.JCheckBox selfCb;
125.292 + private javax.swing.JComboBox variableCombo;
125.293 + private javax.swing.JLabel variableLabel;
125.294 + // End of variables declaration//GEN-END:variables
125.295 +}
126.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
126.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonAstRule.java Mon Sep 21 13:01:16 2015 +0200
126.3 @@ -0,0 +1,51 @@
126.4 +/*
126.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
126.6 + *
126.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
126.8 + *
126.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
126.10 + * Other names may be trademarks of their respective owners.
126.11 + *
126.12 + * The contents of this file are subject to the terms of either the GNU
126.13 + * General Public License Version 2 only ("GPL") or the Common
126.14 + * Development and Distribution License("CDDL") (collectively, the
126.15 + * "License"). You may not use this file except in compliance with the
126.16 + * License. You can obtain a copy of the License at
126.17 + * http://www.netbeans.org/cddl-gplv2.html
126.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
126.19 + * specific language governing permissions and limitations under the
126.20 + * License. When distributing the software, include this License Header
126.21 + * Notice in each file and include the License file at
126.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
126.23 + * particular file as subject to the "Classpath" exception as provided
126.24 + * by Oracle in the GPL Version 2 section of the License file that
126.25 + * accompanied this code. If applicable, add the following below the
126.26 + * License Header, with the fields enclosed by brackets [] replaced by
126.27 + * your own identifying information:
126.28 + * "Portions Copyrighted [year] [name of copyright owner]"
126.29 + *
126.30 + * Contributor(s):
126.31 + *
126.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
126.33 + */
126.34 +package org.netbeans.modules.python.hints;
126.35 +
126.36 +import java.util.List;
126.37 +import java.util.Set;
126.38 +import org.netbeans.modules.csl.api.Hint;
126.39 +import org.netbeans.modules.csl.api.Rule.AstRule;
126.40 +
126.41 +public abstract class PythonAstRule implements AstRule {
126.42 + /**
126.43 + * Get the ElementKinds this rule should run on.
126.44 + * The integers should correspond to values in {@link org.mozilla.javascript.Token}
126.45 + */
126.46 + @Override
126.47 + public abstract Set<Class> getKinds();
126.48 +
126.49 + /**
126.50 + * Run the test on given CompilationUnit and return list of Errors or
126.51 + * warrnings to be shown in the editor.
126.52 + */
126.53 + public abstract void run(PythonRuleContext context, List<Hint> result);
126.54 +}
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonHintOptions.java Mon Sep 21 13:01:16 2015 +0200
127.3 @@ -0,0 +1,71 @@
127.4 +/*
127.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
127.6 + *
127.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
127.8 + *
127.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
127.10 + * Other names may be trademarks of their respective owners.
127.11 + *
127.12 + * The contents of this file are subject to the terms of either the GNU
127.13 + * General Public License Version 2 only ("GPL") or the Common
127.14 + * Development and Distribution License("CDDL") (collectively, the
127.15 + * "License"). You may not use this file except in compliance with the
127.16 + * License. You can obtain a copy of the License at
127.17 + * http://www.netbeans.org/cddl-gplv2.html
127.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
127.19 + * specific language governing permissions and limitations under the
127.20 + * License. When distributing the software, include this License Header
127.21 + * Notice in each file and include the License file at
127.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
127.23 + * particular file as subject to the "Classpath" exception as provided
127.24 + * by Oracle in the GPL Version 2 section of the License file that
127.25 + * accompanied this code. If applicable, add the following below the
127.26 + * License Header, with the fields enclosed by brackets [] replaced by
127.27 + * your own identifying information:
127.28 + * "Portions Copyrighted [year] [name of copyright owner]"
127.29 + *
127.30 + * Contributor(s):
127.31 + *
127.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
127.33 + */
127.34 +package org.netbeans.modules.python.hints;
127.35 +
127.36 +import org.netbeans.modules.csl.api.HintsProvider;
127.37 +import org.netbeans.modules.csl.api.HintsProvider.HintsManager;
127.38 +import org.netbeans.modules.python.api.PythonMIMEResolver;
127.39 +import org.netbeans.spi.options.AdvancedOption;
127.40 +import org.netbeans.spi.options.OptionsPanelController;
127.41 +import org.openide.util.NbBundle;
127.42 +
127.43 +/**
127.44 + * Hint settings for Python
127.45 + */
127.46 +public class PythonHintOptions extends AdvancedOption {
127.47 + OptionsPanelController panelController;
127.48 +
127.49 + @Override
127.50 + public String getDisplayName() {
127.51 + return NbBundle.getMessage(PythonHintOptions.class, "CTL_Hints_DisplayName"); // NOI18N
127.52 + }
127.53 +
127.54 + @Override
127.55 + public String getTooltip() {
127.56 + return NbBundle.getMessage(PythonHintOptions.class, "CTL_Hints_ToolTip"); // NOI18N
127.57 + }
127.58 +
127.59 + @Override
127.60 + public synchronized OptionsPanelController create() {
127.61 + if (panelController == null) {
127.62 + HintsManager manager = HintsProvider.HintsManager.getManagerForMimeType(PythonMIMEResolver.PYTHON_MIME_TYPE);
127.63 + assert manager != null;
127.64 + panelController = manager.getOptionsController();
127.65 + }
127.66 +
127.67 + return panelController;
127.68 + }
127.69 +
127.70 + //TODO: temporary solution, this should be solved on GSF level
127.71 + public static OptionsPanelController createStatic() {
127.72 + return new PythonHintOptions().create();
127.73 + }
127.74 +}
128.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonHintsProvider.java Mon Sep 21 13:01:16 2015 +0200
128.3 @@ -0,0 +1,433 @@
128.4 +/*
128.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
128.6 + *
128.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
128.8 + *
128.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
128.10 + * Other names may be trademarks of their respective owners.
128.11 + *
128.12 + * The contents of this file are subject to the terms of either the GNU
128.13 + * General Public License Version 2 only ("GPL") or the Common
128.14 + * Development and Distribution License("CDDL") (collectively, the
128.15 + * "License"). You may not use this file except in compliance with the
128.16 + * License. You can obtain a copy of the License at
128.17 + * http://www.netbeans.org/cddl-gplv2.html
128.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
128.19 + * specific language governing permissions and limitations under the
128.20 + * License. When distributing the software, include this License Header
128.21 + * Notice in each file and include the License file at
128.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
128.23 + * particular file as subject to the "Classpath" exception as provided
128.24 + * by Oracle in the GPL Version 2 section of the License file that
128.25 + * accompanied this code. If applicable, add the following below the
128.26 + * License Header, with the fields enclosed by brackets [] replaced by
128.27 + * your own identifying information:
128.28 + * "Portions Copyrighted [year] [name of copyright owner]"
128.29 + *
128.30 + * Contributor(s):
128.31 + *
128.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
128.33 + */
128.34 +package org.netbeans.modules.python.hints;
128.35 +
128.36 +import java.util.Collections;
128.37 +import java.util.HashMap;
128.38 +import java.util.Iterator;
128.39 +import java.util.LinkedList;
128.40 +import java.util.List;
128.41 +import java.util.Map;
128.42 +import java.util.Map.Entry;
128.43 +import java.util.Set;
128.44 +import org.netbeans.modules.csl.api.Error;
128.45 +import org.netbeans.modules.csl.api.Hint;
128.46 +import org.netbeans.modules.csl.api.HintFix;
128.47 +import org.netbeans.modules.csl.api.HintSeverity;
128.48 +import org.netbeans.modules.csl.api.HintsProvider;
128.49 +import org.netbeans.modules.csl.api.HintsProvider.HintsManager;
128.50 +import org.netbeans.modules.csl.api.OffsetRange;
128.51 +import org.netbeans.modules.csl.api.Rule;
128.52 +import org.netbeans.modules.csl.api.RuleContext;
128.53 +import org.netbeans.modules.csl.spi.GsfUtilities;
128.54 +import org.netbeans.modules.csl.spi.ParserResult;
128.55 +import org.netbeans.modules.python.source.AstPath;
128.56 +import org.netbeans.modules.python.source.PythonAstUtils;
128.57 +import org.netbeans.modules.python.source.PythonParserResult;
128.58 +import org.openide.util.Exceptions;
128.59 +import org.python.antlr.PythonTree;
128.60 +import org.python.antlr.Visitor;
128.61 +
128.62 +/**
128.63 + *
128.64 + * @todo Write rules based on the PythonChecker ideas:
128.65 + * http://pychecker.sourceforge.net/
128.66 + * @todo Write rules based on the PyLint ideas:
128.67 + * http://www.logilab.org/projects/pylint
128.68 + * http://www.logilab.org/card/pylintfeatures
128.69 + *
128.70 + * @author Tor Norbye
128.71 + */
128.72 +public class PythonHintsProvider implements HintsProvider {
128.73 + private boolean cancelled;
128.74 +
128.75 + public PythonHintsProvider() {
128.76 + }
128.77 +
128.78 + private static class ScopeRule implements Rule {
128.79 + @Override
128.80 + public boolean appliesTo(RuleContext context) {
128.81 + return true;
128.82 + }
128.83 +
128.84 + @Override
128.85 + public String getDisplayName() {
128.86 + return "";
128.87 + }
128.88 +
128.89 + @Override
128.90 + public boolean showInTasklist() {
128.91 + return true;
128.92 + }
128.93 +
128.94 + @Override
128.95 + public HintSeverity getDefaultSeverity() {
128.96 + return HintSeverity.ERROR;
128.97 + }
128.98 + }
128.99 +
128.100 + @Override
128.101 + public void computeErrors(HintsManager manager, RuleContext context, List<Hint> result, List<Error> unhandled) {
128.102 + ParserResult parserResult = context.parserResult;
128.103 + if (parserResult == null) {
128.104 + return;
128.105 + }
128.106 +
128.107 + PythonParserResult pr = (PythonParserResult)parserResult;
128.108 + List<Error> scopeErrors = pr.getSymbolTable().getErrors();
128.109 + if (scopeErrors.size() > 0) {
128.110 + List<HintFix> fixList = Collections.emptyList();
128.111 + Rule rule = new ScopeRule(); // HACK! Just need a rule that will return a severity!
128.112 + for (Error error : scopeErrors) {
128.113 + Hint desc = new Hint(rule, error.getDisplayName(), error.getFile(),
128.114 + new OffsetRange(error.getStartPosition(), error.getEndPosition()), fixList, 10);
128.115 + result.add(desc);
128.116 + }
128.117 + }
128.118 +
128.119 + List<? extends Error> errors = parserResult.getDiagnostics();
128.120 + if (errors == null || errors.size() == 0) {
128.121 + return;
128.122 + }
128.123 +//
128.124 +// cancelled = false;
128.125 +//
128.126 +// @SuppressWarnings("unchecked")
128.127 +// Map<String,List<JsErrorRule>> hints = (Map)manager.getErrors();
128.128 +//
128.129 +// if (hints.isEmpty() || isCancelled()) {
128.130 + unhandled.addAll(errors);
128.131 +// return;
128.132 +// }
128.133 +//
128.134 +// for (Error error : errors) {
128.135 +// if (!applyErrorRules(manager, context, error, hints, result)) {
128.136 +// unhandled.add(error);
128.137 +// }
128.138 +// }
128.139 + }
128.140 +
128.141 + @Override
128.142 + public void computeSelectionHints(HintsManager manager, RuleContext context, List<Hint> result, int start, int end) {
128.143 + cancelled = false;
128.144 +
128.145 + if (GsfUtilities.isCodeTemplateEditing(context.doc)) {
128.146 + return;
128.147 + }
128.148 +
128.149 + ParserResult parserResult = context.parserResult;
128.150 + if (parserResult == null) {
128.151 + return;
128.152 + }
128.153 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
128.154 +
128.155 + if (root == null) {
128.156 + return;
128.157 + }
128.158 + @SuppressWarnings("unchecked")
128.159 + List<? extends Rule.SelectionRule> hints = manager.getSelectionHints();
128.160 +
128.161 + if (hints.isEmpty()) {
128.162 + return;
128.163 + }
128.164 +
128.165 + if (isCancelled()) {
128.166 + return;
128.167 + }
128.168 +
128.169 + try {
128.170 + context.doc.readLock();
128.171 + applySelectionRules(manager, context, hints, result);
128.172 + } finally {
128.173 + context.doc.readUnlock();
128.174 + }
128.175 +}
128.176 +
128.177 + private void applySelectionRules(HintsManager manager, RuleContext context, List<? extends Rule.SelectionRule> rules, List<Hint> result) {
128.178 +
128.179 + PythonRuleContext pythonContext = (PythonRuleContext)context;
128.180 +
128.181 + for (Rule.SelectionRule rule : rules) {
128.182 + if (!rule.appliesTo(context)) {
128.183 + continue;
128.184 + }
128.185 +
128.186 + if(!(rule instanceof PythonSelectionRule)) {
128.187 + continue;
128.188 + }
128.189 +
128.190 + if (!manager.isEnabled((PythonSelectionRule)rule)) {
128.191 + continue;
128.192 + }
128.193 +
128.194 + try {
128.195 + context.doc.readLock();
128.196 + ((PythonSelectionRule)rule).run(pythonContext, result);
128.197 + } finally {
128.198 + context.doc.readUnlock();
128.199 + }
128.200 + }
128.201 + }
128.202 +
128.203 + @Override
128.204 + public void computeHints(HintsManager manager, RuleContext context, List<Hint> result) {
128.205 + cancelled = false;
128.206 +
128.207 + if (context.parserResult == null) {
128.208 + return;
128.209 + }
128.210 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
128.211 +
128.212 + if (root == null) {
128.213 + return;
128.214 + }
128.215 + @SuppressWarnings("unchecked")
128.216 + Map<Class, List<PythonAstRule>> hints = (Map)manager.getHints(false, context);
128.217 +
128.218 + if (hints.isEmpty()) {
128.219 + return;
128.220 + }
128.221 +
128.222 + if (isCancelled()) {
128.223 + return;
128.224 + }
128.225 +
128.226 +// AstPath path = new AstPath();
128.227 +// path.descend(root);
128.228 +//
128.229 +// //applyRules(manager, NodeTypes.ROOTNODE, root, path, info, hints, descriptions);
128.230 +// applyHints(manager, context, -1, root, path, hints, result);
128.231 +//
128.232 +// scan(manager, context, root, path, hints, result);
128.233 +// path.ascend();
128.234 +
128.235 +
128.236 + RuleApplicator finder = new RuleApplicator(manager, context, hints, result);
128.237 + try {
128.238 + context.doc.readLock();
128.239 + finder.visit(root);
128.240 + } catch (Exception ex) {
128.241 + Exceptions.printStackTrace(ex);
128.242 + } finally {
128.243 + context.doc.readUnlock();
128.244 + }
128.245 + }
128.246 +
128.247 + @SuppressWarnings("unchecked")
128.248 + @Override
128.249 + public void computeSuggestions(HintsManager manager, RuleContext context, List<Hint> result, int caretOffset) {
128.250 + cancelled = false;
128.251 + if (context.parserResult == null) {
128.252 + return;
128.253 + }
128.254 +
128.255 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
128.256 +
128.257 + if (root == null) {
128.258 + return;
128.259 + }
128.260 +
128.261 + Map<Class, List<PythonAstRule>> suggestions = new HashMap<>();
128.262 + suggestions.putAll((Map)manager.getHints(true, context));
128.263 +
128.264 + Set<Entry<Class, List<PythonAstRule>>> entrySet = (Set)manager.getSuggestions().entrySet();
128.265 + for (Entry<Class, List<PythonAstRule>> e : entrySet) {
128.266 + List<PythonAstRule> rules = suggestions.get(e.getKey());
128.267 +
128.268 + if (rules != null) {
128.269 + List<PythonAstRule> res = new LinkedList<>();
128.270 +
128.271 + res.addAll(rules);
128.272 + res.addAll(e.getValue());
128.273 +
128.274 + suggestions.put(e.getKey(), res);
128.275 + } else {
128.276 + suggestions.put(e.getKey(), e.getValue());
128.277 + }
128.278 + }
128.279 +
128.280 + if (suggestions.isEmpty()) {
128.281 + return;
128.282 + }
128.283 +
128.284 +
128.285 + if (isCancelled()) {
128.286 + return;
128.287 + }
128.288 +
128.289 + try {
128.290 + context.doc.readLock();
128.291 +
128.292 + PythonParserResult info = (PythonParserResult)context.parserResult;
128.293 + int astOffset = PythonAstUtils.getAstOffset(info, caretOffset);
128.294 + AstPath path = AstPath.get(root, astOffset);
128.295 + Iterator<PythonTree> it = path.leafToRoot();
128.296 + while (it.hasNext()) {
128.297 + if (isCancelled()) {
128.298 + return;
128.299 + }
128.300 +
128.301 + PythonTree node = it.next();
128.302 +
128.303 + applySuggestions(manager, context, node.getClass(), node, path, suggestions, result);
128.304 + }
128.305 + } finally {
128.306 + context.doc.readUnlock();
128.307 + }
128.308 +
128.309 + //applyRules(NodeTypes.ROOTNODE, path, info, suggestions, caretOffset, result);
128.310 + }
128.311 +
128.312 + private void applySuggestions(HintsManager manager, RuleContext context, Class nodeType, PythonTree node, AstPath path, Map<Class, List<PythonAstRule>> hints,
128.313 + List<Hint> result) {
128.314 + List<PythonAstRule> rules = hints.get(nodeType);
128.315 +
128.316 + if (rules != null) {
128.317 + PythonRuleContext pyCtx = (PythonRuleContext)context;
128.318 + pyCtx.node = node;
128.319 + pyCtx.path = path;
128.320 +
128.321 + try {
128.322 + context.doc.readLock();
128.323 + for (PythonAstRule rule : rules) {
128.324 + if (manager.isEnabled(rule)) {
128.325 + rule.run(pyCtx, result);
128.326 + }
128.327 + }
128.328 + } finally {
128.329 + context.doc.readUnlock();
128.330 + }
128.331 + }
128.332 + }
128.333 +
128.334 +// /** Apply error rules and return true iff somebody added an error description for it */
128.335 +// private boolean applyErrorRules(HintsManager manager, RuleContext context, Error error, Map<String,List<JsErrorRule>> hints,
128.336 +// List<Hint> result) {
128.337 +// String code = error.getKey();
128.338 +// if (code != null) {
128.339 +// List<JsErrorRule> rules = hints.get(code);
128.340 +//
128.341 +// if (rules != null) {
128.342 +// int countBefore = result.size();
128.343 +// PythonRuleContext jsContext = (PythonRuleContext)context;
128.344 +//
128.345 +// boolean disabled = false;
128.346 +// for (JsErrorRule rule : rules) {
128.347 +// if (!manager.isEnabled(rule)) {
128.348 +// disabled = true;
128.349 +// } else if (rule.appliesTo(context)) {
128.350 +// rule.run(jsContext, error, result);
128.351 +// }
128.352 +// }
128.353 +//
128.354 +// return disabled || countBefore < result.size() || jsContext.remove;
128.355 +// }
128.356 +// }
128.357 +//
128.358 +// return false;
128.359 +// }
128.360 +//
128.361 +// private void applySelectionRules(HintsManager manager, RuleContext context, List<JsSelectionRule> rules,
128.362 +// List<Hint> result) {
128.363 +//
128.364 +// for (JsSelectionRule rule : rules) {
128.365 +// if (!rule.appliesTo(context)) {
128.366 +// continue;
128.367 +// }
128.368 +//
128.369 +// //if (!manager.isEnabled(rule)) {
128.370 +// // continue;
128.371 +// //}
128.372 +//
128.373 +// rule.run(context, result);
128.374 +// }
128.375 +// }
128.376 +//
128.377 + @Override
128.378 + public void cancel() {
128.379 + cancelled = true;
128.380 + }
128.381 +
128.382 + private boolean isCancelled() {
128.383 + return cancelled;
128.384 + }
128.385 +
128.386 + @Override
128.387 + public RuleContext createRuleContext() {
128.388 + return new PythonRuleContext();
128.389 + }
128.390 +
128.391 + @Override
128.392 + public List<Rule> getBuiltinRules() {
128.393 + return Collections.emptyList();
128.394 + }
128.395 +
128.396 + private static class RuleApplicator extends Visitor {
128.397 + private HintsManager manager;
128.398 + private RuleContext context;
128.399 + private AstPath path;
128.400 + private Map<Class, List<PythonAstRule>> hints;
128.401 + private List<Hint> result;
128.402 +
128.403 + public RuleApplicator(HintsManager manager, RuleContext context, Map<Class, List<PythonAstRule>> hints, List<Hint> result) {
128.404 + this.manager = manager;
128.405 + this.context = context;
128.406 + this.hints = hints;
128.407 + this.result = result;
128.408 +
128.409 + path = new AstPath();
128.410 + }
128.411 +
128.412 + @Override
128.413 + public void traverse(PythonTree node) throws Exception {
128.414 + path.descend(node);
128.415 + applyHints(node);
128.416 + super.traverse(node);
128.417 + path.ascend();
128.418 + }
128.419 +
128.420 + private void applyHints(PythonTree node) {
128.421 + List<PythonAstRule> rules = hints.get(node.getClass());
128.422 +
128.423 + if (rules != null) {
128.424 + PythonRuleContext jsContext = (PythonRuleContext)context;
128.425 + jsContext.node = node;
128.426 + jsContext.path = path;
128.427 +
128.428 + for (PythonAstRule rule : rules) {
128.429 + if (manager.isEnabled(rule)) {
128.430 + rule.run(jsContext, result);
128.431 + }
128.432 + }
128.433 + }
128.434 + }
128.435 + }
128.436 +}
129.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
129.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonRuleContext.java Mon Sep 21 13:01:16 2015 +0200
129.3 @@ -0,0 +1,45 @@
129.4 +/*
129.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
129.6 + *
129.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
129.8 + *
129.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
129.10 + * Other names may be trademarks of their respective owners.
129.11 + *
129.12 + * The contents of this file are subject to the terms of either the GNU
129.13 + * General Public License Version 2 only ("GPL") or the Common
129.14 + * Development and Distribution License("CDDL") (collectively, the
129.15 + * "License"). You may not use this file except in compliance with the
129.16 + * License. You can obtain a copy of the License at
129.17 + * http://www.netbeans.org/cddl-gplv2.html
129.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
129.19 + * specific language governing permissions and limitations under the
129.20 + * License. When distributing the software, include this License Header
129.21 + * Notice in each file and include the License file at
129.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
129.23 + * particular file as subject to the "Classpath" exception as provided
129.24 + * by Oracle in the GPL Version 2 section of the License file that
129.25 + * accompanied this code. If applicable, add the following below the
129.26 + * License Header, with the fields enclosed by brackets [] replaced by
129.27 + * your own identifying information:
129.28 + * "Portions Copyrighted [year] [name of copyright owner]"
129.29 + *
129.30 + * Contributor(s):
129.31 + *
129.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
129.33 + */
129.34 +package org.netbeans.modules.python.hints;
129.35 +
129.36 +import org.netbeans.modules.python.source.AstPath;
129.37 +import org.python.antlr.PythonTree;
129.38 +
129.39 +/**
129.40 + * Information about the current context a rule is being asked to evaluate.
129.41 + *
129.42 + * @author Tor Norbye
129.43 + */
129.44 +public class PythonRuleContext extends org.netbeans.modules.csl.api.RuleContext {
129.45 + public AstPath path;
129.46 + public PythonTree node;
129.47 + public boolean remove;
129.48 +}
130.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
130.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonSelectionRule.java Mon Sep 21 13:01:16 2015 +0200
130.3 @@ -0,0 +1,128 @@
130.4 +/*
130.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
130.6 + *
130.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
130.8 + *
130.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
130.10 + * Other names may be trademarks of their respective owners.
130.11 + *
130.12 + * The contents of this file are subject to the terms of either the GNU
130.13 + * General Public License Version 2 only ("GPL") or the Common
130.14 + * Development and Distribution License("CDDL") (collectively, the
130.15 + * "License"). You may not use this file except in compliance with the
130.16 + * License. You can obtain a copy of the License at
130.17 + * http://www.netbeans.org/cddl-gplv2.html
130.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
130.19 + * specific language governing permissions and limitations under the
130.20 + * License. When distributing the software, include this License Header
130.21 + * Notice in each file and include the License file at
130.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
130.23 + * particular file as subject to the "Classpath" exception as provided
130.24 + * by Oracle in the GPL Version 2 section of the License file that
130.25 + * accompanied this code. If applicable, add the following below the
130.26 + * License Header, with the fields enclosed by brackets [] replaced by
130.27 + * your own identifying information:
130.28 + * "Portions Copyrighted [year] [name of copyright owner]"
130.29 + *
130.30 + * Contributor(s):
130.31 + *
130.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
130.33 + */
130.34 +package org.netbeans.modules.python.hints;
130.35 +
130.36 +import javax.swing.text.BadLocationException;
130.37 +import java.util.List;
130.38 +import org.netbeans.modules.python.source.PythonAstUtils;
130.39 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
130.40 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
130.41 +import org.netbeans.api.lexer.Token;
130.42 +import org.netbeans.api.lexer.TokenId;
130.43 +import org.netbeans.editor.BaseDocument;
130.44 +import org.netbeans.editor.Utilities;
130.45 +import org.netbeans.modules.csl.api.Hint;
130.46 +import org.netbeans.modules.csl.api.OffsetRange;
130.47 +import org.netbeans.modules.csl.api.Rule.SelectionRule;
130.48 +import org.netbeans.modules.csl.api.Rule.UserConfigurableRule;
130.49 +import org.openide.util.Exceptions;
130.50 +import org.python.antlr.PythonTree;
130.51 +
130.52 +/**
130.53 + * Represents a rule to be run on text selection
130.54 + *
130.55 + * @author Tor Norbye
130.56 + */
130.57 +public abstract class PythonSelectionRule implements SelectionRule, UserConfigurableRule {
130.58 + protected abstract int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange);
130.59 +
130.60 + //public abstract void run(PythonRuleContext context, List<Hint> result);
130.61 + public void run(PythonRuleContext context, List<Hint> result) {
130.62 + // TODO - decide if this code represents a complete statement...
130.63 + // For now - that's true iff there's no code to the left on the
130.64 + // start line and code to the right on the end line
130.65 + BaseDocument doc = context.doc;
130.66 + int originalStart = context.selectionStart;
130.67 + int originalEnd = context.selectionEnd;
130.68 + int docLength = doc.getLength();
130.69 +
130.70 + if (originalEnd > docLength) {
130.71 + return;
130.72 + }
130.73 + OffsetRange narrowed = PythonLexerUtils.narrow(doc, new OffsetRange(originalStart, originalEnd), false);
130.74 + if (narrowed == OffsetRange.NONE) {
130.75 + return;
130.76 + }
130.77 +
130.78 + int start = narrowed.getStart();
130.79 + int end = narrowed.getEnd();
130.80 + try {
130.81 + if (start > Utilities.getRowFirstNonWhite(doc, Math.min(docLength, start))) {
130.82 + return;
130.83 + }
130.84 + if (end < Utilities.getRowLastNonWhite(doc, Math.min(docLength, end)) + 1) {
130.85 + return;
130.86 + }
130.87 + } catch (BadLocationException ex) {
130.88 + Exceptions.printStackTrace(ex);
130.89 + }
130.90 +
130.91 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
130.92 + if (root == null) {
130.93 + return;
130.94 + }
130.95 +
130.96 + OffsetRange astRange = PythonAstUtils.getAstOffsets(context.parserResult, new OffsetRange(start, end));
130.97 + if (astRange == OffsetRange.NONE) {
130.98 + return;
130.99 + }
130.100 +
130.101 + int applicability = getApplicability(context, root, astRange);
130.102 + if (applicability == 0) {
130.103 + return;
130.104 + }
130.105 + // Don't allow extract with if you're inside strings or comments
130.106 + Token<? extends PythonTokenId> startToken = PythonLexerUtils.getToken(doc, start);
130.107 + Token<? extends PythonTokenId> endToken = PythonLexerUtils.getToken(doc, end);
130.108 + if (startToken == null || endToken == null) {
130.109 + return;
130.110 + }
130.111 + TokenId startId = startToken.id();
130.112 + if (startId == PythonTokenId.STRING_LITERAL ||
130.113 + (startId == PythonTokenId.COMMENT && start > 0 && startToken == PythonLexerUtils.getToken(doc, start - 1))) {
130.114 + return;
130.115 + }
130.116 + TokenId endId = endToken.id();
130.117 + if (endId == PythonTokenId.STRING_LITERAL) {
130.118 + return;
130.119 + }
130.120 +
130.121 + // TODO - don't enable inside comments or strings!!
130.122 + // TODO - if you are including functions or classes it should probably
130.123 + // be disabled!
130.124 +
130.125 + OffsetRange range = new OffsetRange(originalStart, originalEnd);
130.126 +
130.127 + run(context, result, range, applicability);
130.128 + }
130.129 +
130.130 + public abstract void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability);
130.131 +}
131.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
131.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/RelativeImports.java Mon Sep 21 13:01:16 2015 +0200
131.3 @@ -0,0 +1,246 @@
131.4 +/*
131.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
131.6 + *
131.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
131.8 + *
131.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
131.10 + * Other names may be trademarks of their respective owners.
131.11 + *
131.12 + * The contents of this file are subject to the terms of either the GNU
131.13 + * General Public License Version 2 only ("GPL") or the Common
131.14 + * Development and Distribution License("CDDL") (collectively, the
131.15 + * "License"). You may not use this file except in compliance with the
131.16 + * License. You can obtain a copy of the License at
131.17 + * http://www.netbeans.org/cddl-gplv2.html
131.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
131.19 + * specific language governing permissions and limitations under the
131.20 + * License. When distributing the software, include this License Header
131.21 + * Notice in each file and include the License file at
131.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
131.23 + * particular file as subject to the "Classpath" exception as provided
131.24 + * by Oracle in the GPL Version 2 section of the License file that
131.25 + * accompanied this code. If applicable, add the following below the
131.26 + * License Header, with the fields enclosed by brackets [] replaced by
131.27 + * your own identifying information:
131.28 + * "Portions Copyrighted [year] [name of copyright owner]"
131.29 + *
131.30 + * If you wish your version of this file to be governed by only the CDDL
131.31 + * or only the GPL Version 2, indicate your decision by adding
131.32 + * "[Contributor] elects to include this software in this distribution
131.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
131.34 + * single choice of license, a recipient has the option to distribute
131.35 + * your version of this file under either the CDDL, the GPL Version 2 or
131.36 + * to extend the choice of license to its licensees as provided above.
131.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
131.38 + * Version 2 license, then the option applies only if the new code is
131.39 + * made subject to such option by the copyright holder.
131.40 + *
131.41 + * Contributor(s):
131.42 + *
131.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
131.44 + */
131.45 +package org.netbeans.modules.python.hints;
131.46 +
131.47 +import java.util.ArrayList;
131.48 +import java.util.Collections;
131.49 +import java.util.List;
131.50 +import java.util.Set;
131.51 +import java.util.prefs.Preferences;
131.52 +import javax.swing.JComponent;
131.53 +import javax.swing.text.BadLocationException;
131.54 +import org.netbeans.modules.python.source.PythonAstUtils;
131.55 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
131.56 +import org.netbeans.editor.BaseDocument;
131.57 +import org.netbeans.editor.Utilities;
131.58 +import org.netbeans.modules.csl.api.EditList;
131.59 +import org.netbeans.modules.csl.api.Hint;
131.60 +import org.netbeans.modules.csl.api.HintFix;
131.61 +import org.netbeans.modules.csl.api.HintSeverity;
131.62 +import org.netbeans.modules.csl.api.OffsetRange;
131.63 +import org.netbeans.modules.csl.api.PreviewableFix;
131.64 +import org.netbeans.modules.csl.api.RuleContext;
131.65 +import org.netbeans.modules.csl.spi.ParserResult;
131.66 +import org.netbeans.modules.python.source.PythonParserResult;
131.67 +import org.openide.filesystems.FileObject;
131.68 +import org.openide.util.Exceptions;
131.69 +import org.openide.util.NbBundle;
131.70 +import org.python.antlr.PythonTree;
131.71 +import org.python.antlr.ast.ImportFrom;
131.72 +
131.73 +/**
131.74 + * Import statements should be one per line. This quickfix
131.75 + * offers to make it so.
131.76 + *
131.77 + * @todo Ensure that
131.78 + * {@code from __future__ import absolute_import}
131.79 + * is present, at least until Python 2.7
131.80 + *
131.81 + * @author Tor Norbye
131.82 + */
131.83 +public class RelativeImports extends PythonAstRule {
131.84 + @Override
131.85 + public Set<Class> getKinds() {
131.86 + return Collections.singleton((Class)ImportFrom.class);
131.87 + }
131.88 +
131.89 + @Override
131.90 + public void run(PythonRuleContext context, List<Hint> result) {
131.91 + ImportFrom imp = (ImportFrom)context.node;
131.92 + if (imp.getInternalModule() != null && imp.getInternalModule().startsWith(".")) {
131.93 + PythonTree node = context.node;
131.94 + PythonParserResult info = (PythonParserResult) context.parserResult;
131.95 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
131.96 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
131.97 + BaseDocument doc = context.doc;
131.98 + try {
131.99 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
131.100 + (context.caretOffset == -1 ||
131.101 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
131.102 + List<HintFix> fixList = new ArrayList<>();
131.103 + fixList.add(new RelativeImportsFix(context, imp));
131.104 + String displayName = getDisplayName();
131.105 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
131.106 + result.add(desc);
131.107 + }
131.108 + } catch (BadLocationException ex) {
131.109 + Exceptions.printStackTrace(ex);
131.110 + }
131.111 + }
131.112 + }
131.113 +
131.114 + @Override
131.115 + public String getId() {
131.116 + return "RelativeImports"; // NOI18N
131.117 + }
131.118 +
131.119 + @Override
131.120 + public String getDisplayName() {
131.121 + return NbBundle.getMessage(RelativeImports.class, "RelativeImports");
131.122 + }
131.123 +
131.124 + @Override
131.125 + public String getDescription() {
131.126 + return NbBundle.getMessage(RelativeImports.class, "RelativeImportsDesc");
131.127 + }
131.128 +
131.129 + @Override
131.130 + public boolean getDefaultEnabled() {
131.131 + return true;
131.132 + }
131.133 +
131.134 + @Override
131.135 + public JComponent getCustomizer(Preferences node) {
131.136 + return null;
131.137 + }
131.138 +
131.139 + @Override
131.140 + public boolean appliesTo(RuleContext context) {
131.141 + return true;
131.142 + }
131.143 +
131.144 + @Override
131.145 + public boolean showInTasklist() {
131.146 + return true;
131.147 + }
131.148 +
131.149 + @Override
131.150 + public HintSeverity getDefaultSeverity() {
131.151 + return HintSeverity.WARNING;
131.152 + }
131.153 +
131.154 + private static class RelativeImportsFix implements PreviewableFix {
131.155 + private final PythonRuleContext context;
131.156 + private final ImportFrom imp;
131.157 +
131.158 + private RelativeImportsFix(PythonRuleContext context, ImportFrom imp) {
131.159 + this.context = context;
131.160 + this.imp = imp;
131.161 + }
131.162 +
131.163 + @Override
131.164 + public String getDescription() {
131.165 + return NbBundle.getMessage(RelativeImports.class, "RelativeImportsFix");
131.166 + }
131.167 +
131.168 + @Override
131.169 + public boolean canPreview() {
131.170 + return true;
131.171 + }
131.172 +
131.173 + @Override
131.174 + public EditList getEditList() throws Exception {
131.175 + BaseDocument doc = context.doc;
131.176 + EditList edits = new EditList(doc);
131.177 +
131.178 + // Algorithm:
131.179 + // (1) Figure out which package we are in
131.180 + // (2) Subtrack package elements per dot
131.181 + // (3) Replace relative reference
131.182 +
131.183 + OffsetRange astRange = PythonAstUtils.getRange(imp);
131.184 + if (astRange != OffsetRange.NONE) {
131.185 + PythonParserResult info = (PythonParserResult)context.parserResult;
131.186 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
131.187 + if (lexRange != OffsetRange.NONE) {
131.188 + FileObject fo = info.getSnapshot().getSource().getFileObject();
131.189 + if (fo != null) {
131.190 + String path = imp.getInternalModule();
131.191 + int i = 0;
131.192 + for (; i < path.length(); i++) {
131.193 + if (path.charAt(i) != '.') {
131.194 + break;
131.195 + }
131.196 + }
131.197 + int levels = i;
131.198 + path = path.substring(levels);
131.199 +
131.200 + for (int j = 0; j < levels; j++) {
131.201 + if (fo != null) {
131.202 + fo = fo.getParent();
131.203 + }
131.204 + }
131.205 +
131.206 + // Finally, find out the absolute path we are in
131.207 + // Hopefully, I will have access to the python load path
131.208 + // here. But in the mean time, I can just see which
131.209 + // packages I am in...
131.210 + while (fo != null) {
131.211 + if (fo.getFileObject("__init__.py") != null) { // NOI18N
131.212 + // Yep, we're still in a package
131.213 + if (path.length() > 0) {
131.214 + path = fo.getName() + "." + path; // NOI18N
131.215 + } else {
131.216 + path = fo.getName();
131.217 + }
131.218 + }
131.219 + fo = fo.getParent();
131.220 + }
131.221 + String text = doc.getText(lexRange.getStart(), lexRange.getLength());
131.222 + int relativePos = text.indexOf(imp.getInternalModule());
131.223 + if (relativePos != -1) {
131.224 + edits.replace(lexRange.getStart() + relativePos, imp.getInternalModule().length(), path, false, 0);
131.225 + }
131.226 + }
131.227 + }
131.228 + }
131.229 +
131.230 + return edits;
131.231 + }
131.232 +
131.233 + @Override
131.234 + public void implement() throws Exception {
131.235 + EditList edits = getEditList();
131.236 + edits.apply();
131.237 + }
131.238 +
131.239 + @Override
131.240 + public boolean isSafe() {
131.241 + return true;
131.242 + }
131.243 +
131.244 + @Override
131.245 + public boolean isInteractive() {
131.246 + return false;
131.247 + }
131.248 + }
131.249 +}
132.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
132.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/SplitImports.java Mon Sep 21 13:01:16 2015 +0200
132.3 @@ -0,0 +1,222 @@
132.4 +/*
132.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
132.6 + *
132.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
132.8 + *
132.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
132.10 + * Other names may be trademarks of their respective owners.
132.11 + *
132.12 + * The contents of this file are subject to the terms of either the GNU
132.13 + * General Public License Version 2 only ("GPL") or the Common
132.14 + * Development and Distribution License("CDDL") (collectively, the
132.15 + * "License"). You may not use this file except in compliance with the
132.16 + * License. You can obtain a copy of the License at
132.17 + * http://www.netbeans.org/cddl-gplv2.html
132.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
132.19 + * specific language governing permissions and limitations under the
132.20 + * License. When distributing the software, include this License Header
132.21 + * Notice in each file and include the License file at
132.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
132.23 + * particular file as subject to the "Classpath" exception as provided
132.24 + * by Oracle in the GPL Version 2 section of the License file that
132.25 + * accompanied this code. If applicable, add the following below the
132.26 + * License Header, with the fields enclosed by brackets [] replaced by
132.27 + * your own identifying information:
132.28 + * "Portions Copyrighted [year] [name of copyright owner]"
132.29 + *
132.30 + * If you wish your version of this file to be governed by only the CDDL
132.31 + * or only the GPL Version 2, indicate your decision by adding
132.32 + * "[Contributor] elects to include this software in this distribution
132.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
132.34 + * single choice of license, a recipient has the option to distribute
132.35 + * your version of this file under either the CDDL, the GPL Version 2 or
132.36 + * to extend the choice of license to its licensees as provided above.
132.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
132.38 + * Version 2 license, then the option applies only if the new code is
132.39 + * made subject to such option by the copyright holder.
132.40 + *
132.41 + * Contributor(s):
132.42 + *
132.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
132.44 + */
132.45 +package org.netbeans.modules.python.hints;
132.46 +
132.47 +import java.util.ArrayList;
132.48 +import java.util.Collections;
132.49 +import java.util.List;
132.50 +import java.util.Set;
132.51 +import java.util.prefs.Preferences;
132.52 +import javax.swing.JComponent;
132.53 +import javax.swing.text.BadLocationException;
132.54 +import org.netbeans.modules.python.source.PythonAstUtils;
132.55 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
132.56 +import org.netbeans.editor.BaseDocument;
132.57 +import org.netbeans.editor.Utilities;
132.58 +import org.netbeans.modules.csl.api.EditList;
132.59 +import org.netbeans.modules.csl.api.Hint;
132.60 +import org.netbeans.modules.csl.api.HintFix;
132.61 +import org.netbeans.modules.csl.api.HintSeverity;
132.62 +import org.netbeans.modules.csl.api.OffsetRange;
132.63 +import org.netbeans.modules.csl.api.PreviewableFix;
132.64 +import org.netbeans.modules.csl.api.RuleContext;
132.65 +import org.netbeans.modules.csl.spi.GsfUtilities;
132.66 +import org.netbeans.modules.editor.indent.api.IndentUtils;
132.67 +import org.netbeans.modules.python.source.PythonParserResult;
132.68 +import org.netbeans.modules.python.source.CodeStyle;
132.69 +import org.openide.util.Exceptions;
132.70 +import org.openide.util.NbBundle;
132.71 +import org.python.antlr.PythonTree;
132.72 +import org.python.antlr.ast.Import;
132.73 +import org.python.antlr.ast.alias;
132.74 +
132.75 +/**
132.76 + * Import statements should be one per line. This quickfix
132.77 + * offers to make it so.
132.78 + *
132.79 + * @author Tor Norbye
132.80 + */
132.81 +public class SplitImports extends PythonAstRule {
132.82 + @Override
132.83 + public Set<Class> getKinds() {
132.84 + return Collections.singleton((Class)Import.class);
132.85 + }
132.86 +
132.87 + @Override
132.88 + public void run(PythonRuleContext context, List<Hint> result) {
132.89 + Import imp = (Import)context.node;
132.90 + List<alias> names = imp.getInternalNames();
132.91 + if (names != null && names.size() > 1) {
132.92 + PythonTree node = context.node;
132.93 + PythonParserResult info = (PythonParserResult)context.parserResult;
132.94 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
132.95 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
132.96 + BaseDocument doc = context.doc;
132.97 + try {
132.98 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
132.99 + (context.caretOffset == -1 ||
132.100 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
132.101 + List<HintFix> fixList = new ArrayList<>();
132.102 + fixList.add(new SplitImportsFix(context, imp));
132.103 + String displayName = getDisplayName();
132.104 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
132.105 + result.add(desc);
132.106 + }
132.107 + } catch (BadLocationException ex) {
132.108 + Exceptions.printStackTrace(ex);
132.109 + }
132.110 + }
132.111 + }
132.112 +
132.113 + @Override
132.114 + public String getId() {
132.115 + return "SplitImports"; // NOI18N
132.116 + }
132.117 +
132.118 + @Override
132.119 + public String getDisplayName() {
132.120 + return NbBundle.getMessage(SplitImports.class, "SplitImports");
132.121 + }
132.122 +
132.123 + @Override
132.124 + public String getDescription() {
132.125 + return NbBundle.getMessage(SplitImports.class, "SplitImportsDesc");
132.126 + }
132.127 +
132.128 + @Override
132.129 + public boolean getDefaultEnabled() {
132.130 + return true;
132.131 + }
132.132 +
132.133 + @Override
132.134 + public JComponent getCustomizer(Preferences node) {
132.135 + return null;
132.136 + }
132.137 +
132.138 + @Override
132.139 + public boolean appliesTo(RuleContext context) {
132.140 + CodeStyle codeStyle = CodeStyle.getDefault(context.doc);
132.141 + return codeStyle == null || codeStyle.oneImportPerLine();
132.142 + }
132.143 +
132.144 + @Override
132.145 + public boolean showInTasklist() {
132.146 + return true;
132.147 + }
132.148 +
132.149 + @Override
132.150 + public HintSeverity getDefaultSeverity() {
132.151 + return HintSeverity.WARNING;
132.152 + }
132.153 +
132.154 + private static class SplitImportsFix implements PreviewableFix {
132.155 + private final PythonRuleContext context;
132.156 + private final Import imp;
132.157 +
132.158 + private SplitImportsFix(PythonRuleContext context, Import imp) {
132.159 + this.context = context;
132.160 + this.imp = imp;
132.161 + }
132.162 +
132.163 + @Override
132.164 + public String getDescription() {
132.165 + return NbBundle.getMessage(SplitImports.class, "SplitImportsFix");
132.166 + }
132.167 +
132.168 + @Override
132.169 + public boolean canPreview() {
132.170 + return true;
132.171 + }
132.172 +
132.173 + @Override
132.174 + public EditList getEditList() throws Exception {
132.175 + BaseDocument doc = context.doc;
132.176 + EditList edits = new EditList(doc);
132.177 +
132.178 + OffsetRange astRange = PythonAstUtils.getRange(imp);
132.179 + if (astRange != OffsetRange.NONE) {
132.180 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
132.181 + if (lexRange != OffsetRange.NONE) {
132.182 + int indent = GsfUtilities.getLineIndent(doc, lexRange.getStart());
132.183 + StringBuilder sb = new StringBuilder();
132.184 + List<alias> names = imp.getInternalNames();
132.185 + if (names != null) {
132.186 + for (alias at : names) {
132.187 + if (indent > 0 && sb.length() > 0) {
132.188 + sb.append(IndentUtils.createIndentString(doc, indent));
132.189 + }
132.190 + sb.append("import "); // NOI18N
132.191 + sb.append(at.getInternalName());
132.192 + if (at.getInternalAsname() != null && at.getInternalAsname().length() > 0) {
132.193 + sb.append(" as "); // NOI18N
132.194 + sb.append(at.getInternalAsname());
132.195 + }
132.196 + sb.append("\n");
132.197 + }
132.198 + }
132.199 + // Remove the final newline since Import doesn't include it
132.200 + sb.setLength(sb.length() - 1);
132.201 +
132.202 + edits.replace(lexRange.getStart(), lexRange.getLength(), sb.toString(), false, 0);
132.203 + }
132.204 + }
132.205 +
132.206 + return edits;
132.207 + }
132.208 +
132.209 + @Override
132.210 + public void implement() throws Exception {
132.211 + EditList edits = getEditList();
132.212 + edits.apply();
132.213 + }
132.214 +
132.215 + @Override
132.216 + public boolean isSafe() {
132.217 + return true;
132.218 + }
132.219 +
132.220 + @Override
132.221 + public boolean isInteractive() {
132.222 + return false;
132.223 + }
132.224 + }
132.225 +}
133.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
133.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/SurroundWith.java Mon Sep 21 13:01:16 2015 +0200
133.3 @@ -0,0 +1,377 @@
133.4 +/*
133.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
133.6 + *
133.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
133.8 + *
133.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
133.10 + * Other names may be trademarks of their respective owners.
133.11 + *
133.12 + * The contents of this file are subject to the terms of either the GNU
133.13 + * General Public License Version 2 only ("GPL") or the Common
133.14 + * Development and Distribution License("CDDL") (collectively, the
133.15 + * "License"). You may not use this file except in compliance with the
133.16 + * License. You can obtain a copy of the License at
133.17 + * http://www.netbeans.org/cddl-gplv2.html
133.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
133.19 + * specific language governing permissions and limitations under the
133.20 + * License. When distributing the software, include this License Header
133.21 + * Notice in each file and include the License file at
133.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
133.23 + * particular file as subject to the "Classpath" exception as provided
133.24 + * by Oracle in the GPL Version 2 section of the License file that
133.25 + * accompanied this code. If applicable, add the following below the
133.26 + * License Header, with the fields enclosed by brackets [] replaced by
133.27 + * your own identifying information:
133.28 + * "Portions Copyrighted [year] [name of copyright owner]"
133.29 + *
133.30 + * Contributor(s):
133.31 + *
133.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
133.33 + */
133.34 +package org.netbeans.modules.python.hints;
133.35 +
133.36 +import java.util.ArrayList;
133.37 +import java.util.List;
133.38 +import java.util.prefs.Preferences;
133.39 +import javax.swing.JComponent;
133.40 +import javax.swing.text.JTextComponent;
133.41 +import javax.swing.text.Position;
133.42 +import org.netbeans.editor.BaseDocument;
133.43 +import org.netbeans.editor.Utilities;
133.44 +import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
133.45 +import org.netbeans.modules.csl.api.EditList;
133.46 +import org.netbeans.modules.csl.api.Hint;
133.47 +import org.netbeans.modules.csl.api.HintFix;
133.48 +import org.netbeans.modules.csl.api.HintSeverity;
133.49 +import org.netbeans.modules.csl.api.OffsetRange;
133.50 +import org.netbeans.modules.csl.api.PreviewableFix;
133.51 +import org.netbeans.modules.csl.api.RuleContext;
133.52 +import org.netbeans.modules.csl.spi.GsfUtilities;
133.53 +import org.netbeans.modules.editor.indent.api.IndentUtils;
133.54 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
133.55 +import org.openide.util.Exceptions;
133.56 +import org.openide.util.NbBundle;
133.57 +import org.python.antlr.PythonTree;
133.58 +import org.python.antlr.Visitor;
133.59 +import org.python.antlr.ast.ClassDef;
133.60 +import org.python.antlr.ast.FunctionDef;
133.61 +import org.python.antlr.ast.Import;
133.62 +import org.python.antlr.ast.ImportFrom;
133.63 +
133.64 +/**
133.65 + * Offer to surround code with for example try/except/finally
133.66 + *
133.67 + * @author Tor Norbye
133.68 + */
133.69 +public class SurroundWith extends PythonSelectionRule {
133.70 + @Override
133.71 + protected int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange) {
133.72 + if (!ApplicabilityVisitor.applies(root, astRange)) {
133.73 + return 0;
133.74 + }
133.75 +
133.76 + return 1;
133.77 + }
133.78 +
133.79 + @Override
133.80 + public void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability) {
133.81 + int start = range.getStart();
133.82 + int end = range.getEnd();
133.83 +
133.84 + // Adjust the fix range to be right around the dot so that the light bulb ends up
133.85 + // on the same line as the caret and alt-enter works
133.86 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
133.87 + if (target != null) {
133.88 + int dot = target.getCaret().getDot();
133.89 + range = new OffsetRange(dot, dot);
133.90 + }
133.91 +
133.92 + List<HintFix> fixList = new ArrayList<>(3);
133.93 + fixList.add(new SurroundWithFix(context, start, end, false, true));
133.94 + fixList.add(new SurroundWithFix(context, start, end, true, true));
133.95 + fixList.add(new SurroundWithFix(context, start, end, true, false));
133.96 + String displayName = getDisplayName();
133.97 + Hint desc = new Hint(this, displayName, context.parserResult.getSnapshot().getSource().getFileObject(),
133.98 + range, fixList, 1500);
133.99 + result.add(desc);
133.100 + }
133.101 +
133.102 + @Override
133.103 + public boolean appliesTo(RuleContext context) {
133.104 + return true;
133.105 + }
133.106 +
133.107 + @Override
133.108 + public String getDisplayName() {
133.109 + return NbBundle.getMessage(SurroundWith.class, "SurroundWith");
133.110 + }
133.111 +
133.112 + @Override
133.113 + public boolean showInTasklist() {
133.114 + return false;
133.115 + }
133.116 +
133.117 + @Override
133.118 + public HintSeverity getDefaultSeverity() {
133.119 + return HintSeverity.CURRENT_LINE_WARNING;
133.120 + }
133.121 +
133.122 + @Override
133.123 + public String getId() {
133.124 + return "SurroundWith"; // NOI18N
133.125 + }
133.126 +
133.127 + @Override
133.128 + public String getDescription() {
133.129 + return "";
133.130 + }
133.131 +
133.132 + @Override
133.133 + public boolean getDefaultEnabled() {
133.134 + return true;
133.135 + }
133.136 +
133.137 + @Override
133.138 + public JComponent getCustomizer(Preferences node) {
133.139 + return null;
133.140 + }
133.141 +
133.142 + private static class SurroundWithFix implements PreviewableFix {
133.143 + private final PythonRuleContext context;
133.144 + private final boolean includeFinally;
133.145 + private final boolean includeExcept;
133.146 + private Position startPos;
133.147 + private Position endPos;
133.148 + private Position codeTemplatePos;
133.149 + private String codeTemplateText;
133.150 + private final int start;
133.151 + private final int end;
133.152 +
133.153 + private SurroundWithFix(PythonRuleContext context,
133.154 + int start, int end,
133.155 + boolean includeFinally, boolean includeExcept) {
133.156 + assert includeExcept || includeFinally;
133.157 +
133.158 + this.context = context;
133.159 +
133.160 + OffsetRange range = PythonLexerUtils.narrow(context.doc, new OffsetRange(start, end), false);
133.161 + this.start = range.getStart();
133.162 + this.end = range.getEnd();
133.163 + this.includeFinally = includeFinally;
133.164 + this.includeExcept = includeExcept;
133.165 + }
133.166 +
133.167 + @Override
133.168 + public String getDescription() {
133.169 + if (includeExcept && includeFinally) {
133.170 + return NbBundle.getMessage(CreateDocString.class, "SurroundWithTEF");
133.171 + } else if (includeExcept) {
133.172 + return NbBundle.getMessage(CreateDocString.class, "SurroundWithTE");
133.173 + } else {
133.174 + assert includeFinally;
133.175 + return NbBundle.getMessage(CreateDocString.class, "SurroundWithTF");
133.176 + }
133.177 + }
133.178 +
133.179 + @Override
133.180 + public boolean canPreview() {
133.181 + return true;
133.182 + }
133.183 +
133.184 + @Override
133.185 + public EditList getEditList() throws Exception {
133.186 + return getEditList(true);
133.187 + }
133.188 +
133.189 + private EditList getEditList(boolean previewOnly) throws Exception {
133.190 + BaseDocument doc = context.doc;
133.191 + EditList edits = new EditList(doc);
133.192 +
133.193 + int indentSize = IndentUtils.indentLevelSize(doc);
133.194 + String oneIndent = IndentUtils.createIndentString(doc, indentSize);
133.195 + //int initialIndent = GsfUtilities.getLineIndent(doc, start);
133.196 + int lineStart = Utilities.getRowStart(doc, start);
133.197 + String initialIndentStr = IndentUtils.createIndentString(doc, IndentUtils.lineIndent(doc, lineStart));
133.198 + int nextLine = Utilities.getRowEnd(doc, end) + 1;
133.199 + if (nextLine > doc.getLength()) {
133.200 + nextLine = doc.getLength();
133.201 + edits.replace(nextLine, 0, "\n", false, 1);
133.202 + }
133.203 +
133.204 + // Indent the selected lines
133.205 + edits.replace(lineStart, 0, initialIndentStr + "try:\n", false, 1);
133.206 + for (int offset = start; offset < end; offset = Utilities.getRowEnd(doc, offset) + 1) {
133.207 + edits.replace(offset, 0, oneIndent, false, 1);
133.208 + }
133.209 +
133.210 + StringBuilder sb = new StringBuilder();
133.211 + if (includeExcept) {
133.212 + sb.append(initialIndentStr);
133.213 + sb.append("except ");
133.214 + if (!previewOnly) {
133.215 + sb.append("${except default=\"");
133.216 + }
133.217 + sb.append("Exception, e");
133.218 + if (!previewOnly) {
133.219 + sb.append("\"}");
133.220 + }
133.221 + sb.append(":\n");
133.222 + sb.append(initialIndentStr);
133.223 + sb.append(oneIndent);
133.224 + int caretDelta = sb.length();
133.225 + startPos = edits.createPosition(nextLine + caretDelta);
133.226 + if (!previewOnly) {
133.227 + sb.append("${action default=\"");
133.228 + }
133.229 + sb.append("print \"Exception: \", e");
133.230 + if (!previewOnly) {
133.231 + sb.append("\"}");
133.232 + }
133.233 + caretDelta = sb.length();
133.234 + endPos = edits.createPosition(nextLine + caretDelta);
133.235 + sb.append("\n");
133.236 + if (!previewOnly && !includeExcept) {
133.237 + sb.append("${cursor}");
133.238 + }
133.239 + }
133.240 + if (includeFinally) {
133.241 + sb.append(initialIndentStr);
133.242 + sb.append("finally:\n");
133.243 + sb.append(initialIndentStr);
133.244 + sb.append(oneIndent);
133.245 + if (!previewOnly) {
133.246 + sb.append("${finally default=\"\"}\n${cursor}");
133.247 + }
133.248 + int caretDelta = sb.length();
133.249 + if (!includeExcept) {
133.250 + endPos = startPos = edits.createPosition(nextLine + caretDelta);
133.251 + }
133.252 + sb.append("\n");
133.253 + }
133.254 + if (previewOnly) {
133.255 + edits.replace(nextLine, 0, sb.toString(), false, 1);
133.256 + } else {
133.257 + codeTemplatePos = edits.createPosition(nextLine, Position.Bias.Backward);
133.258 + codeTemplateText = sb.toString();
133.259 + }
133.260 +
133.261 + return edits;
133.262 + }
133.263 +
133.264 + @Override
133.265 + public void implement() throws Exception {
133.266 + EditList edits = getEditList(true);
133.267 +
133.268 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
133.269 + edits.apply();
133.270 + if (target != null) {
133.271 + if (codeTemplateText != null && codeTemplatePos != null) {
133.272 + final CodeTemplateManager ctm = CodeTemplateManager.get(context.doc);
133.273 + if (ctm != null) {
133.274 + target.getCaret().setDot(codeTemplatePos.getOffset());
133.275 + ctm.createTemporary(codeTemplateText).insert(target);
133.276 + }
133.277 + } else if (startPos != null && endPos != null) {
133.278 + target.setSelectionStart(startPos.getOffset());
133.279 + target.setSelectionEnd(endPos.getOffset());
133.280 + }
133.281 + }
133.282 + }
133.283 +
133.284 + @Override
133.285 + public boolean isSafe() {
133.286 + return true;
133.287 + }
133.288 +
133.289 + @Override
133.290 + public boolean isInteractive() {
133.291 + return false;
133.292 + }
133.293 + }
133.294 +
133.295 + /** @todo Prune search in traverse, ala AstPath.
133.296 + * @todo Build up start and end AstPaths.
133.297 + */
133.298 + private static class ApplicabilityVisitor extends Visitor {
133.299 + private boolean applies = true;
133.300 + private final int start;
133.301 + private final int end;
133.302 +
133.303 + static boolean applies(PythonTree root, OffsetRange astRange) {
133.304 + ApplicabilityVisitor visitor = new ApplicabilityVisitor(astRange);
133.305 + try {
133.306 + visitor.visit(root);
133.307 + } catch (Exception ex) {
133.308 + Exceptions.printStackTrace(ex);
133.309 + return false;
133.310 + }
133.311 + return visitor.isApplicable();
133.312 + }
133.313 +
133.314 + ApplicabilityVisitor(OffsetRange astRange) {
133.315 + this.start = astRange.getStart();
133.316 + this.end = astRange.getEnd();
133.317 + }
133.318 +
133.319 + public boolean isApplicable() {
133.320 + return applies;
133.321 + }
133.322 +
133.323 + private void maybeBail(PythonTree node) {
133.324 + int nodeStart = node.getCharStartIndex();
133.325 + int nodeEnd = node.getCharStopIndex();
133.326 + if (nodeStart >= start && nodeStart < end) {
133.327 + applies = false;
133.328 + }
133.329 + if (nodeEnd > start && nodeEnd < end) {
133.330 + applies = false;
133.331 + }
133.332 + }
133.333 +
133.334 + @Override
133.335 + public void traverse(PythonTree node) throws Exception {
133.336 + if (!applies) {
133.337 + return;
133.338 + }
133.339 +
133.340 + int nodeStart = node.getCharStartIndex();
133.341 + int nodeStop = node.getCharStopIndex();
133.342 + //if (!(nodeStop < start || nodeStart > end)) {
133.343 + if (nodeStop >= start && nodeStart <= end) {
133.344 + super.traverse(node);
133.345 + }
133.346 + }
133.347 +
133.348 + @Override
133.349 + public Object visitClassDef(ClassDef node) throws Exception {
133.350 + maybeBail(node);
133.351 + return super.visitClassDef(node);
133.352 + }
133.353 +
133.354 + @Override
133.355 + public Object visitFunctionDef(FunctionDef node) throws Exception {
133.356 + maybeBail(node);
133.357 + return super.visitFunctionDef(node);
133.358 + }
133.359 +
133.360 + @Override
133.361 + public Object visitImport(Import node) throws Exception {
133.362 + maybeBail(node);
133.363 + return super.visitImport(node);
133.364 + }
133.365 +
133.366 + @Override
133.367 + public Object visitImportFrom(ImportFrom node) throws Exception {
133.368 + maybeBail(node);
133.369 + return super.visitImportFrom(node);
133.370 + }
133.371 +
133.372 + // Module is okay - you get this when you select all text in a simple "script" file
133.373 + // with only statements
133.374 + //@Override
133.375 + //public Object visitModule(Module node) throws Exception {
133.376 + // maybeBail(node);
133.377 + // return super.visitModule(node);
133.378 + //}
133.379 + }
133.380 +}
134.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
134.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnresolvedClassComponents.java Mon Sep 21 13:01:16 2015 +0200
134.3 @@ -0,0 +1,207 @@
134.4 +/*
134.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
134.6 + *
134.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
134.8 + *
134.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
134.10 + * Other names may be trademarks of their respective owners.
134.11 + *
134.12 + * The contents of this file are subject to the terms of either the GNU
134.13 + * General Public License Version 2 only ("GPL") or the Common
134.14 + * Development and Distribution License("CDDL") (collectively, the
134.15 + * "License"). You may not use this file except in compliance with the
134.16 + * License. You can obtain a copy of the License at
134.17 + * http://www.netbeans.org/cddl-gplv2.html
134.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
134.19 + * specific language governing permissions and limitations under the
134.20 + * License. When distributing the software, include this License Header
134.21 + * Notice in each file and include the License file at
134.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
134.23 + * particular file as subject to the "Classpath" exception as provided
134.24 + * by Oracle in the GPL Version 2 section of the License file that
134.25 + * accompanied this code. If applicable, add the following below the
134.26 + * License Header, with the fields enclosed by brackets [] replaced by
134.27 + * your own identifying information:
134.28 + * "Portions Copyrighted [year] [name of copyright owner]"
134.29 + *
134.30 + * If you wish your version of this file to be governed by only the CDDL
134.31 + * or only the GPL Version 2, indicate your decision by adding
134.32 + * "[Contributor] elects to include this software in this distribution
134.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
134.34 + * single choice of license, a recipient has the option to distribute
134.35 + * your version of this file under either the CDDL, the GPL Version 2 or
134.36 + * to extend the choice of license to its licensees as provided above.
134.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
134.38 + * Version 2 license, then the option applies only if the new code is
134.39 + * made subject to such option by the copyright holder.
134.40 + *
134.41 + * Contributor(s):
134.42 + *
134.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
134.44 + */
134.45 +package org.netbeans.modules.python.hints;
134.46 +
134.47 +import java.util.Collections;
134.48 +import java.util.List;
134.49 +import java.util.Set;
134.50 +import java.util.prefs.Preferences;
134.51 +import javax.swing.JComponent;
134.52 +import org.netbeans.modules.csl.api.Hint;
134.53 +import org.netbeans.modules.csl.api.HintFix;
134.54 +import org.netbeans.modules.csl.api.HintSeverity;
134.55 +import org.netbeans.modules.csl.api.OffsetRange;
134.56 +import org.netbeans.modules.csl.api.RuleContext;
134.57 +import org.netbeans.modules.python.source.PythonAstUtils;
134.58 +import org.netbeans.modules.python.source.PythonParserResult;
134.59 +import org.netbeans.modules.python.source.ImportManager;
134.60 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
134.61 +import org.netbeans.modules.python.source.scopes.SymbolTable;
134.62 +import org.openide.util.NbBundle;
134.63 +import org.python.antlr.PythonTree;
134.64 +import org.python.antlr.ast.Module;
134.65 +
134.66 +/**
134.67 + * Detect Unresolved class attributes
134.68 + *
134.69 + * @author Jean-Yves Mengant
134.70 + */
134.71 +public class UnresolvedClassComponents extends PythonAstRule {
134.72 +
134.73 + private final static String CLASS_UNRESOLVED_ATTRIBUTES = "UnresolvedAttributes";
134.74 + private final static String CLASS_UNRESOLVED_INHERITANCE_VAR = "UnresolvedInheritanceVariable";
134.75 + private final static String CLASS_UNRESOLVED_ATTRIBUTES_VAR = "UnresolvedAttributesVariable";
134.76 + private final static String CLASS_UNRESOLVED_ATTRIBUTES_DESC = "UnresolvedAttributesDesc";
134.77 +
134.78 +
134.79 +
134.80 + public UnresolvedClassComponents() {
134.81 + }
134.82 +
134.83 + @Override
134.84 + public boolean appliesTo(RuleContext context) {
134.85 + return true;
134.86 + }
134.87 +
134.88 + @Override
134.89 + public Set<Class> getKinds() {
134.90 + return Collections.<Class>singleton(Module.class);
134.91 + }
134.92 +
134.93 + private void populateMessages( PythonParserResult info, List<PythonTree> unresolved , List<Hint> result ,boolean isClass ) {
134.94 + if (unresolved.size() > 0) {
134.95 +
134.96 + for (PythonTree node : unresolved) {
134.97 + // Compute suggestions
134.98 + String name = PythonAstUtils.getName(node);
134.99 + if (name == null) {
134.100 + name = "";
134.101 + }
134.102 + List<HintFix> fixList = Collections.emptyList();
134.103 + String message ;
134.104 + if ( isClass)
134.105 + message = NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_INHERITANCE_VAR, name);
134.106 + else
134.107 + message = NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES_VAR, name);
134.108 + OffsetRange range = PythonAstUtils.getRange( node);
134.109 + range = PythonLexerUtils.getLexerOffsets(info, range);
134.110 + if (range != OffsetRange.NONE) {
134.111 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
134.112 + result.add(desc);
134.113 + }
134.114 + }
134.115 + }
134.116 + }
134.117 +
134.118 +
134.119 + @Override
134.120 + public void run(PythonRuleContext context, List<Hint> result) {
134.121 + PythonParserResult info = (PythonParserResult) context.parserResult;
134.122 + SymbolTable symbolTable = info.getSymbolTable();
134.123 +
134.124 + List<PythonTree> unresolvedAttributes = symbolTable.getUnresolvedAttributes(info);
134.125 + populateMessages(info,unresolvedAttributes,result,false) ;
134.126 + List<PythonTree> unresolvedParents = symbolTable.getUnresolvedParents(info);
134.127 + populateMessages(info,unresolvedParents,result,true) ;
134.128 + }
134.129 +
134.130 + @Override
134.131 + public String getId() {
134.132 + return CLASS_UNRESOLVED_ATTRIBUTES; // NOI18N
134.133 + }
134.134 +
134.135 + @Override
134.136 + public String getDisplayName() {
134.137 + return NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES);
134.138 + }
134.139 +
134.140 + @Override
134.141 + public String getDescription() {
134.142 + return NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES_DESC);
134.143 + }
134.144 +
134.145 + @Override
134.146 + public boolean getDefaultEnabled() {
134.147 + return false;
134.148 + }
134.149 +
134.150 + @Override
134.151 + public boolean showInTasklist() {
134.152 + return true;
134.153 + }
134.154 +
134.155 + @Override
134.156 + public HintSeverity getDefaultSeverity() {
134.157 + return HintSeverity.ERROR;
134.158 + }
134.159 +
134.160 + @Override
134.161 + public JComponent getCustomizer(Preferences node) {
134.162 + return null;
134.163 + }
134.164 +
134.165 + private static class ImportFix implements HintFix {
134.166 + private final PythonRuleContext context;
134.167 + private final PythonTree node;
134.168 + private final String module;
134.169 +
134.170 + private ImportFix(PythonRuleContext context, PythonTree node, String module) {
134.171 + this.context = context;
134.172 + this.node = node;
134.173 + this.module = module;
134.174 + }
134.175 +
134.176 + @Override
134.177 + public String getDescription() {
134.178 + return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
134.179 + }
134.180 +
134.181 + @Override
134.182 + public void implement() throws Exception {
134.183 + String mod = this.module;
134.184 + String symbol = null;
134.185 + int colon = mod.indexOf(':');
134.186 + if (colon != -1) {
134.187 + int end = mod.indexOf('(', colon + 1);
134.188 + if (end == -1) {
134.189 + end = mod.indexOf(';', colon + 1);
134.190 + if (end == -1) {
134.191 + end = mod.length();
134.192 + }
134.193 + }
134.194 + symbol = mod.substring(colon + 1, end).trim();
134.195 + mod = mod.substring(0, colon).trim();
134.196 + }
134.197 + new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
134.198 + }
134.199 +
134.200 + @Override
134.201 + public boolean isSafe() {
134.202 + return true;
134.203 + }
134.204 +
134.205 + @Override
134.206 + public boolean isInteractive() {
134.207 + return false;
134.208 + }
134.209 + }
134.210 +}
135.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
135.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnresolvedDetector.java Mon Sep 21 13:01:16 2015 +0200
135.3 @@ -0,0 +1,232 @@
135.4 +/*
135.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
135.6 + *
135.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
135.8 + *
135.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
135.10 + * Other names may be trademarks of their respective owners.
135.11 + *
135.12 + * The contents of this file are subject to the terms of either the GNU
135.13 + * General Public License Version 2 only ("GPL") or the Common
135.14 + * Development and Distribution License("CDDL") (collectively, the
135.15 + * "License"). You may not use this file except in compliance with the
135.16 + * License. You can obtain a copy of the License at
135.17 + * http://www.netbeans.org/cddl-gplv2.html
135.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
135.19 + * specific language governing permissions and limitations under the
135.20 + * License. When distributing the software, include this License Header
135.21 + * Notice in each file and include the License file at
135.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
135.23 + * particular file as subject to the "Classpath" exception as provided
135.24 + * by Oracle in the GPL Version 2 section of the License file that
135.25 + * accompanied this code. If applicable, add the following below the
135.26 + * License Header, with the fields enclosed by brackets [] replaced by
135.27 + * your own identifying information:
135.28 + * "Portions Copyrighted [year] [name of copyright owner]"
135.29 + *
135.30 + * If you wish your version of this file to be governed by only the CDDL
135.31 + * or only the GPL Version 2, indicate your decision by adding
135.32 + * "[Contributor] elects to include this software in this distribution
135.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
135.34 + * single choice of license, a recipient has the option to distribute
135.35 + * your version of this file under either the CDDL, the GPL Version 2 or
135.36 + * to extend the choice of license to its licensees as provided above.
135.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
135.38 + * Version 2 license, then the option applies only if the new code is
135.39 + * made subject to such option by the copyright holder.
135.40 + *
135.41 + * Contributor(s):
135.42 + *
135.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
135.44 + */
135.45 +package org.netbeans.modules.python.hints;
135.46 +
135.47 +import java.util.ArrayList;
135.48 +import java.util.Collections;
135.49 +import java.util.List;
135.50 +import java.util.Set;
135.51 +import java.util.prefs.Preferences;
135.52 +import javax.swing.JComponent;
135.53 +import org.netbeans.modules.csl.api.Hint;
135.54 +import org.netbeans.modules.csl.api.HintFix;
135.55 +import org.netbeans.modules.csl.api.HintSeverity;
135.56 +import org.netbeans.modules.csl.api.OffsetRange;
135.57 +import org.netbeans.modules.csl.api.RuleContext;
135.58 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
135.59 +import org.netbeans.modules.python.source.PythonAstUtils;
135.60 +import org.netbeans.modules.python.source.PythonIndex;
135.61 +import org.netbeans.modules.python.source.PythonParserResult;
135.62 +import org.netbeans.modules.python.source.elements.IndexedElement;
135.63 +import org.netbeans.modules.python.source.ImportManager;
135.64 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
135.65 +import org.netbeans.modules.python.source.scopes.SymbolTable;
135.66 +import org.openide.util.NbBundle;
135.67 +import org.python.antlr.PythonTree;
135.68 +import org.python.antlr.ast.Attribute;
135.69 +import org.python.antlr.ast.Call;
135.70 +import org.python.antlr.ast.Module;
135.71 +
135.72 +/**
135.73 + * Detect Unresolved variables
135.74 + *
135.75 + * @author Tor Norbye
135.76 + */
135.77 +public class UnresolvedDetector extends PythonAstRule {
135.78 + public UnresolvedDetector() {
135.79 + }
135.80 +
135.81 + @Override
135.82 + public boolean appliesTo(RuleContext context) {
135.83 + return true;
135.84 + }
135.85 +
135.86 + @Override
135.87 + public Set<Class> getKinds() {
135.88 + return Collections.<Class>singleton(Module.class);
135.89 + }
135.90 +
135.91 + @Override
135.92 + public void run(PythonRuleContext context, List<Hint> result) {
135.93 + PythonParserResult info = (PythonParserResult) context.parserResult;
135.94 + SymbolTable symbolTable = info.getSymbolTable();
135.95 +
135.96 + List<PythonTree> unresolvedNames = symbolTable.getUnresolved(info);
135.97 + if (unresolvedNames.size() > 0) {
135.98 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
135.99 +
135.100 + for (PythonTree node : unresolvedNames) {
135.101 + // Compute suggestions
135.102 + String name = PythonAstUtils.getName(node);
135.103 + if (name == null) {
135.104 + name = "";
135.105 + }
135.106 + // Ignore keywords and builtin
135.107 + if (PythonLexerUtils.isKeywordOrBuiltin(name)) {
135.108 + continue;
135.109 + }
135.110 +
135.111 + List<HintFix> fixList = new ArrayList<>(3);
135.112 + // Is is a reference to a module?
135.113 + boolean tryModule = false;
135.114 + if (node.getParent() instanceof Call) {
135.115 + Call call = (Call)node.getParent();
135.116 + PythonTree t = call.getInternalFunc();
135.117 + if (t instanceof Attribute) {
135.118 + tryModule = true;
135.119 + }
135.120 + }
135.121 + String message = NbBundle.getMessage(NameRule.class, "UnresolvedVariable", name);
135.122 + if (name.equals("true")) { // NOI18N
135.123 + // Help for new language converts...
135.124 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "True"); // NOI18N
135.125 + } else if (name.equals("false")) {
135.126 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "False"); // NOI18N
135.127 + } else if (name.equals("nil") || name.equals("null")) {
135.128 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "None"); // NOI18N
135.129 + } else if (name.equals("this")) {
135.130 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "self"); // NOI18N
135.131 + } else if (tryModule) {
135.132 + Set<IndexedElement> moduleElements = index.getModules(name, QuerySupport.Kind.EXACT);
135.133 + if (moduleElements.size() > 0) {
135.134 + fixList.add(new ImportFix(context, node, name));
135.135 + }
135.136 + } else {
135.137 + Set<String> modules = index.getImportsFor(name, true);
135.138 + if (modules.size() > 0) {
135.139 + for (String module : modules) {
135.140 + fixList.add(new ImportFix(context, node, module));
135.141 + }
135.142 + }
135.143 + }
135.144 +
135.145 + OffsetRange range = PythonAstUtils.getNameRange(info, node);
135.146 + range = PythonLexerUtils.getLexerOffsets(info, range);
135.147 + if (range != OffsetRange.NONE) {
135.148 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
135.149 + result.add(desc);
135.150 + }
135.151 + }
135.152 + }
135.153 + }
135.154 +
135.155 + @Override
135.156 + public String getId() {
135.157 + return "Unresolved"; // NOI18N
135.158 + }
135.159 +
135.160 + @Override
135.161 + public String getDisplayName() {
135.162 + return NbBundle.getMessage(NameRule.class, "Unresolved");
135.163 + }
135.164 +
135.165 + @Override
135.166 + public String getDescription() {
135.167 + return NbBundle.getMessage(NameRule.class, "UnresolvedDesc");
135.168 + }
135.169 +
135.170 + @Override
135.171 + public boolean getDefaultEnabled() {
135.172 + return false;
135.173 + }
135.174 +
135.175 + @Override
135.176 + public boolean showInTasklist() {
135.177 + return true;
135.178 + }
135.179 +
135.180 + @Override
135.181 + public HintSeverity getDefaultSeverity() {
135.182 + return HintSeverity.ERROR;
135.183 + }
135.184 +
135.185 + @Override
135.186 + public JComponent getCustomizer(Preferences node) {
135.187 + return null;
135.188 + }
135.189 +
135.190 + private static class ImportFix implements HintFix {
135.191 + private final PythonRuleContext context;
135.192 + private final PythonTree node;
135.193 + private final String module;
135.194 +
135.195 + private ImportFix(PythonRuleContext context, PythonTree node, String module) {
135.196 + this.context = context;
135.197 + this.node = node;
135.198 + this.module = module;
135.199 + }
135.200 +
135.201 + @Override
135.202 + public String getDescription() {
135.203 + return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
135.204 + }
135.205 +
135.206 + @Override
135.207 + public void implement() throws Exception {
135.208 + String mod = this.module;
135.209 + String symbol = null;
135.210 + int colon = mod.indexOf(':');
135.211 + if (colon != -1) {
135.212 + int end = mod.indexOf('(', colon + 1);
135.213 + if (end == -1) {
135.214 + end = mod.indexOf(';', colon + 1);
135.215 + if (end == -1) {
135.216 + end = mod.length();
135.217 + }
135.218 + }
135.219 + symbol = mod.substring(colon + 1, end).trim();
135.220 + mod = mod.substring(0, colon).trim();
135.221 + }
135.222 + new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
135.223 + }
135.224 +
135.225 + @Override
135.226 + public boolean isSafe() {
135.227 + return true;
135.228 + }
135.229 +
135.230 + @Override
135.231 + public boolean isInteractive() {
135.232 + return false;
135.233 + }
135.234 + }
135.235 +}
136.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
136.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedDetector.java Mon Sep 21 13:01:16 2015 +0200
136.3 @@ -0,0 +1,244 @@
136.4 +/*
136.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
136.6 + *
136.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
136.8 + *
136.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
136.10 + * Other names may be trademarks of their respective owners.
136.11 + *
136.12 + * The contents of this file are subject to the terms of either the GNU
136.13 + * General Public License Version 2 only ("GPL") or the Common
136.14 + * Development and Distribution License("CDDL") (collectively, the
136.15 + * "License"). You may not use this file except in compliance with the
136.16 + * License. You can obtain a copy of the License at
136.17 + * http://www.netbeans.org/cddl-gplv2.html
136.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
136.19 + * specific language governing permissions and limitations under the
136.20 + * License. When distributing the software, include this License Header
136.21 + * Notice in each file and include the License file at
136.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
136.23 + * particular file as subject to the "Classpath" exception as provided
136.24 + * by Oracle in the GPL Version 2 section of the License file that
136.25 + * accompanied this code. If applicable, add the following below the
136.26 + * License Header, with the fields enclosed by brackets [] replaced by
136.27 + * your own identifying information:
136.28 + * "Portions Copyrighted [year] [name of copyright owner]"
136.29 + *
136.30 + * If you wish your version of this file to be governed by only the CDDL
136.31 + * or only the GPL Version 2, indicate your decision by adding
136.32 + * "[Contributor] elects to include this software in this distribution
136.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
136.34 + * single choice of license, a recipient has the option to distribute
136.35 + * your version of this file under either the CDDL, the GPL Version 2 or
136.36 + * to extend the choice of license to its licensees as provided above.
136.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
136.38 + * Version 2 license, then the option applies only if the new code is
136.39 + * made subject to such option by the copyright holder.
136.40 + *
136.41 + * Contributor(s):
136.42 + *
136.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
136.44 + */
136.45 +package org.netbeans.modules.python.hints;
136.46 +
136.47 +import java.util.ArrayList;
136.48 +import java.util.Collections;
136.49 +import java.util.HashSet;
136.50 +import java.util.List;
136.51 +import java.util.Set;
136.52 +import java.util.prefs.Preferences;
136.53 +import javax.swing.JComponent;
136.54 +import org.netbeans.modules.csl.api.Hint;
136.55 +import org.netbeans.modules.csl.api.HintFix;
136.56 +import org.netbeans.modules.csl.api.HintSeverity;
136.57 +import org.netbeans.modules.csl.api.OffsetRange;
136.58 +import org.netbeans.modules.csl.api.RuleContext;
136.59 +import org.netbeans.modules.python.source.PythonAstUtils;
136.60 +import org.netbeans.modules.python.source.PythonParserResult;
136.61 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
136.62 +import org.netbeans.modules.python.source.scopes.SymbolTable;
136.63 +import org.openide.util.NbBundle;
136.64 +import org.python.antlr.PythonTree;
136.65 +import org.python.antlr.ast.Assign;
136.66 +import org.python.antlr.ast.For;
136.67 +import org.python.antlr.ast.Module;
136.68 +import org.python.antlr.ast.Tuple;
136.69 +import org.python.antlr.base.expr;
136.70 +
136.71 +/**
136.72 + * Detect unused variables
136.73 + *
136.74 + * @todo Find a more reliable way of detecting return tuples without relying on the
136.75 + * parent reference
136.76 + *
136.77 + * @author Tor Norbye
136.78 + */
136.79 +public class UnusedDetector extends PythonAstRule {
136.80 + /** Default names ignored */
136.81 + private static final String DEFAULT_IGNORED_NAMES = "_, dummy";
136.82 + private static final String PARAMS_KEY = "params"; // NOI18N
136.83 + private static final String SKIP_TUPLE_ASSIGN_KEY = "skipTuples"; // NOI18N
136.84 + private static final String IGNORED_KEY = "ignorednames"; // NOI18N
136.85 +
136.86 + public UnusedDetector() {
136.87 + }
136.88 +
136.89 + @Override
136.90 + public boolean appliesTo(RuleContext context) {
136.91 + return true;
136.92 + }
136.93 +
136.94 + @Override
136.95 + public Set<Class> getKinds() {
136.96 + return Collections.<Class>singleton(Module.class);
136.97 + }
136.98 +
136.99 + @Override
136.100 + public void run(PythonRuleContext context, List<Hint> result) {
136.101 + PythonParserResult info = (PythonParserResult) context.parserResult;
136.102 + SymbolTable symbolTable = info.getSymbolTable();
136.103 +
136.104 + boolean skipParams = true;
136.105 + Preferences pref = context.manager.getPreferences(this);
136.106 + if (pref != null) {
136.107 + skipParams = getSkipParameters(pref);
136.108 + }
136.109 +
136.110 + List<PythonTree> unusedNames = symbolTable.getUnused(true, skipParams);
136.111 + if (unusedNames.size() == 0) {
136.112 + return;
136.113 + }
136.114 +
136.115 + boolean skipTupleAssigns = true;
136.116 + Set<String> ignoreNames = Collections.emptySet();
136.117 + if (pref != null) {
136.118 + skipParams = getSkipParameters(pref);
136.119 + skipTupleAssigns = getSkipTupleAssignments(pref);
136.120 + String ignoreNamesStr = getIgnoreNames(pref);
136.121 + if (ignoreNamesStr.length() > 0) {
136.122 + ignoreNames = new HashSet<>();
136.123 + for (String s : ignoreNamesStr.split(",")) { // NOI18N
136.124 + ignoreNames.add(s.trim());
136.125 + }
136.126 + }
136.127 + }
136.128 +
136.129 + for (PythonTree node : unusedNames) {
136.130 + if (skipTupleAssigns && isTupleAssignment(node)) {
136.131 + continue;
136.132 + }
136.133 + String name = PythonAstUtils.getName(node);
136.134 + if (name == null) {
136.135 + name = "";
136.136 + }
136.137 + if (ignoreNames.contains(name)) {
136.138 + continue;
136.139 + }
136.140 + OffsetRange range = PythonAstUtils.getNameRange(info, node);
136.141 + range = PythonLexerUtils.getLexerOffsets(info, range);
136.142 + if (range != OffsetRange.NONE) {
136.143 + List<HintFix> fixList = new ArrayList<>(3);
136.144 + String message = NbBundle.getMessage(NameRule.class, "UnusedVariable", name);
136.145 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
136.146 + result.add(desc);
136.147 + }
136.148 + }
136.149 + }
136.150 +
136.151 + private boolean isTupleAssignment(PythonTree node) {
136.152 + // This may not work right since the parent pointers often aren't set right;
136.153 + // find a more efficient way to do it correctly than a path search for each node
136.154 + if (node.getParent() instanceof Tuple) {
136.155 + // Allow tuples in tuples
136.156 + PythonTree parentParent = node.getParent().getParent();
136.157 + while (parentParent instanceof Tuple) {
136.158 + parentParent = parentParent.getParent();
136.159 + node = node.getParent();
136.160 + }
136.161 + if (parentParent instanceof Assign) {
136.162 + Assign assign = (Assign)parentParent;
136.163 + List<expr> targets = assign.getInternalTargets();
136.164 + if (targets != null && targets.size() > 0 && targets.get(0) == node.getParent()) {
136.165 + return true;
136.166 + }
136.167 + }
136.168 + if (parentParent instanceof For &&
136.169 + ((For)parentParent).getInternalTarget() == node.getParent()) {
136.170 + return true;
136.171 + }
136.172 + }
136.173 +
136.174 + return false;
136.175 + }
136.176 +
136.177 + @Override
136.178 + public String getId() {
136.179 + return "Unused"; // NOI18N
136.180 + }
136.181 +
136.182 + @Override
136.183 + public String getDisplayName() {
136.184 + return NbBundle.getMessage(NameRule.class, "Unused");
136.185 + }
136.186 +
136.187 + @Override
136.188 + public String getDescription() {
136.189 + return NbBundle.getMessage(NameRule.class, "UnusedDesc");
136.190 + }
136.191 +
136.192 + @Override
136.193 + public boolean getDefaultEnabled() {
136.194 + return true;
136.195 + }
136.196 +
136.197 + @Override
136.198 + public boolean showInTasklist() {
136.199 + return true;
136.200 + }
136.201 +
136.202 + @Override
136.203 + public HintSeverity getDefaultSeverity() {
136.204 + return HintSeverity.WARNING;
136.205 + }
136.206 +
136.207 + @Override
136.208 + public JComponent getCustomizer(Preferences node) {
136.209 + return new UnusedDetectorPrefs(node);
136.210 + }
136.211 +
136.212 + static boolean getSkipParameters(Preferences prefs) {
136.213 + return prefs.getBoolean(PARAMS_KEY, true);
136.214 + }
136.215 +
136.216 + static void setSkipParameters(Preferences prefs, boolean skipParams) {
136.217 + if (skipParams) {
136.218 + prefs.remove(PARAMS_KEY);
136.219 + } else {
136.220 + prefs.putBoolean(PARAMS_KEY, false);
136.221 + }
136.222 + }
136.223 +
136.224 + static boolean getSkipTupleAssignments(Preferences prefs) {
136.225 + return prefs.getBoolean(SKIP_TUPLE_ASSIGN_KEY, true);
136.226 + }
136.227 +
136.228 + static void setSkipTupleAssignments(Preferences prefs, boolean skipTupleAssigns) {
136.229 + if (skipTupleAssigns) {
136.230 + prefs.remove(SKIP_TUPLE_ASSIGN_KEY);
136.231 + } else {
136.232 + prefs.putBoolean(SKIP_TUPLE_ASSIGN_KEY, false);
136.233 + }
136.234 + }
136.235 +
136.236 + static String getIgnoreNames(Preferences prefs) {
136.237 + return prefs.get(IGNORED_KEY, DEFAULT_IGNORED_NAMES);
136.238 + }
136.239 +
136.240 + static void setIgnoreNames(Preferences prefs, String ignoredNames) {
136.241 + if (ignoredNames.length() == 0) {
136.242 + prefs.remove(IGNORED_KEY);
136.243 + } else {
136.244 + prefs.put(IGNORED_KEY, ignoredNames);
136.245 + }
136.246 + }
136.247 +}
137.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
137.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedDetectorPrefs.form Mon Sep 21 13:01:16 2015 +0200
137.3 @@ -0,0 +1,84 @@
137.4 +<?xml version="1.0" encoding="UTF-8" ?>
137.5 +
137.6 +<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
137.7 + <AuxValues>
137.8 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
137.9 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
137.10 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
137.11 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
137.12 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
137.13 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
137.14 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="2"/>
137.15 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
137.16 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
137.17 + </AuxValues>
137.18 +
137.19 + <Layout>
137.20 + <DimensionLayout dim="0">
137.21 + <Group type="103" groupAlignment="0" attributes="0">
137.22 + <Component id="skipParams" min="-2" max="-2" attributes="0"/>
137.23 + <Component id="skipTupleAssignments" alignment="0" min="-2" max="-2" attributes="0"/>
137.24 + <Group type="102" alignment="0" attributes="0">
137.25 + <Component id="ignoredLabel" min="-2" max="-2" attributes="0"/>
137.26 + <EmptySpace max="-2" attributes="0"/>
137.27 + <Component id="ignoredNames" min="-2" max="-2" attributes="0"/>
137.28 + </Group>
137.29 + </Group>
137.30 + </DimensionLayout>
137.31 + <DimensionLayout dim="1">
137.32 + <Group type="103" groupAlignment="0" attributes="0">
137.33 + <Group type="102" attributes="0">
137.34 + <Component id="skipParams" min="-2" max="-2" attributes="0"/>
137.35 + <EmptySpace max="-2" attributes="0"/>
137.36 + <Component id="skipTupleAssignments" min="-2" max="-2" attributes="0"/>
137.37 + <EmptySpace max="-2" attributes="0"/>
137.38 + <Group type="103" groupAlignment="3" attributes="0">
137.39 + <Component id="ignoredLabel" alignment="3" min="-2" max="-2" attributes="0"/>
137.40 + <Component id="ignoredNames" alignment="3" min="-2" max="-2" attributes="0"/>
137.41 + </Group>
137.42 + <EmptySpace max="32767" attributes="0"/>
137.43 + </Group>
137.44 + </Group>
137.45 + </DimensionLayout>
137.46 + </Layout>
137.47 + <SubComponents>
137.48 + <Component class="javax.swing.JCheckBox" name="skipParams">
137.49 + <Properties>
137.50 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
137.51 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.skipParams.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
137.52 + </Property>
137.53 + </Properties>
137.54 + <Events>
137.55 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
137.56 + </Events>
137.57 + </Component>
137.58 + <Component class="javax.swing.JCheckBox" name="skipTupleAssignments">
137.59 + <Properties>
137.60 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
137.61 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.skipTupleAssignments.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
137.62 + </Property>
137.63 + </Properties>
137.64 + <Events>
137.65 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
137.66 + </Events>
137.67 + </Component>
137.68 + <Component class="javax.swing.JTextField" name="ignoredNames">
137.69 + <Properties>
137.70 + <Property name="columns" type="int" value="25"/>
137.71 + </Properties>
137.72 + <Events>
137.73 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
137.74 + </Events>
137.75 + </Component>
137.76 + <Component class="javax.swing.JLabel" name="ignoredLabel">
137.77 + <Properties>
137.78 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
137.79 + <ComponentRef name="ignoredNames"/>
137.80 + </Property>
137.81 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
137.82 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.ignoredLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
137.83 + </Property>
137.84 + </Properties>
137.85 + </Component>
137.86 + </SubComponents>
137.87 +</Form>
138.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
138.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedDetectorPrefs.java Mon Sep 21 13:01:16 2015 +0200
138.3 @@ -0,0 +1,152 @@
138.4 +/*
138.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
138.6 + *
138.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
138.8 + *
138.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
138.10 + * Other names may be trademarks of their respective owners.
138.11 + *
138.12 + * The contents of this file are subject to the terms of either the GNU
138.13 + * General Public License Version 2 only ("GPL") or the Common
138.14 + * Development and Distribution License("CDDL") (collectively, the
138.15 + * "License"). You may not use this file except in compliance with the
138.16 + * License. You can obtain a copy of the License at
138.17 + * http://www.netbeans.org/cddl-gplv2.html
138.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
138.19 + * specific language governing permissions and limitations under the
138.20 + * License. When distributing the software, include this License Header
138.21 + * Notice in each file and include the License file at
138.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
138.23 + * particular file as subject to the "Classpath" exception as provided
138.24 + * by Oracle in the GPL Version 2 section of the License file that
138.25 + * accompanied this code. If applicable, add the following below the
138.26 + * License Header, with the fields enclosed by brackets [] replaced by
138.27 + * your own identifying information:
138.28 + * "Portions Copyrighted [year] [name of copyright owner]"
138.29 + *
138.30 + * If you wish your version of this file to be governed by only the CDDL
138.31 + * or only the GPL Version 2, indicate your decision by adding
138.32 + * "[Contributor] elects to include this software in this distribution
138.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
138.34 + * single choice of license, a recipient has the option to distribute
138.35 + * your version of this file under either the CDDL, the GPL Version 2 or
138.36 + * to extend the choice of license to its licensees as provided above.
138.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
138.38 + * Version 2 license, then the option applies only if the new code is
138.39 + * made subject to such option by the copyright holder.
138.40 + *
138.41 + * Contributor(s):
138.42 + *
138.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
138.44 + */
138.45 +
138.46 +/*
138.47 + * UnusedDetectorPrefs.java
138.48 + *
138.49 + * Created on Nov 10, 2008, 9:48:35 AM
138.50 + */
138.51 +package org.netbeans.modules.python.hints;
138.52 +
138.53 +import java.awt.event.ActionListener;
138.54 +import java.util.prefs.Preferences;
138.55 +
138.56 +/**
138.57 + * Preferences where users can configure the unused detector rules
138.58 + *
138.59 + * @author Tor Norbye
138.60 + */
138.61 +public class UnusedDetectorPrefs extends javax.swing.JPanel implements ActionListener {
138.62 + private Preferences prefs;
138.63 +
138.64 + /** Creates new form UnusedDetectorPrefs */
138.65 + public UnusedDetectorPrefs(Preferences prefs) {
138.66 + initComponents();
138.67 + this.prefs = prefs;
138.68 + skipParams.setSelected(UnusedDetector.getSkipParameters(prefs));
138.69 + skipTupleAssignments.setSelected(UnusedDetector.getSkipTupleAssignments(prefs));
138.70 + String ignore = UnusedDetector.getIgnoreNames(prefs);
138.71 + if (ignore == null) {
138.72 + ignore = "";
138.73 + }
138.74 + ignoredNames.setText(ignore);
138.75 + }
138.76 +
138.77 + @SuppressWarnings("unchecked")
138.78 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
138.79 + private void initComponents() {
138.80 +
138.81 + skipParams = new javax.swing.JCheckBox();
138.82 + skipTupleAssignments = new javax.swing.JCheckBox();
138.83 + ignoredNames = new javax.swing.JTextField();
138.84 + ignoredLabel = new javax.swing.JLabel();
138.85 +
138.86 + skipParams.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.skipParams.text")); // NOI18N
138.87 + skipParams.addActionListener(this);
138.88 +
138.89 + skipTupleAssignments.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.skipTupleAssignments.text")); // NOI18N
138.90 + skipTupleAssignments.addActionListener(this);
138.91 +
138.92 + ignoredNames.setColumns(25);
138.93 + ignoredNames.addActionListener(this);
138.94 +
138.95 + ignoredLabel.setLabelFor(ignoredNames);
138.96 + ignoredLabel.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.ignoredLabel.text")); // NOI18N
138.97 +
138.98 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
138.99 + this.setLayout(layout);
138.100 + layout.setHorizontalGroup(
138.101 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
138.102 + .addComponent(skipParams)
138.103 + .addComponent(skipTupleAssignments)
138.104 + .addGroup(layout.createSequentialGroup()
138.105 + .addComponent(ignoredLabel)
138.106 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
138.107 + .addComponent(ignoredNames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
138.108 + );
138.109 + layout.setVerticalGroup(
138.110 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
138.111 + .addGroup(layout.createSequentialGroup()
138.112 + .addComponent(skipParams)
138.113 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
138.114 + .addComponent(skipTupleAssignments)
138.115 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
138.116 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
138.117 + .addComponent(ignoredLabel)
138.118 + .addComponent(ignoredNames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
138.119 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
138.120 + );
138.121 + }
138.122 +
138.123 + // Code for dispatching events from components to event handlers.
138.124 +
138.125 + public void actionPerformed(java.awt.event.ActionEvent evt) {
138.126 + if (evt.getSource() == skipParams) {
138.127 + UnusedDetectorPrefs.this.changed(evt);
138.128 + }
138.129 + else if (evt.getSource() == skipTupleAssignments) {
138.130 + UnusedDetectorPrefs.this.changed(evt);
138.131 + }
138.132 + else if (evt.getSource() == ignoredNames) {
138.133 + UnusedDetectorPrefs.this.changed(evt);
138.134 + }
138.135 + }// </editor-fold>//GEN-END:initComponents
138.136 +
138.137 + private void changed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changed
138.138 + Object source = evt.getSource();
138.139 + if (source == ignoredNames) {
138.140 + UnusedDetector.setIgnoreNames(prefs, ignoredNames.getText().trim());
138.141 + } else if (source == skipParams) {
138.142 + UnusedDetector.setSkipParameters(prefs, skipParams.isSelected());
138.143 + } else if (source == skipTupleAssignments) {
138.144 + UnusedDetector.setSkipTupleAssignments(prefs, skipTupleAssignments.isSelected());
138.145 + } else {
138.146 + assert false : source;
138.147 + }
138.148 + }//GEN-LAST:event_changed
138.149 + // Variables declaration - do not modify//GEN-BEGIN:variables
138.150 + private javax.swing.JLabel ignoredLabel;
138.151 + private javax.swing.JTextField ignoredNames;
138.152 + private javax.swing.JCheckBox skipParams;
138.153 + private javax.swing.JCheckBox skipTupleAssignments;
138.154 + // End of variables declaration//GEN-END:variables
138.155 +}
139.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedImports.java Mon Sep 21 13:01:16 2015 +0200
139.3 @@ -0,0 +1,286 @@
139.4 +/*
139.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
139.6 + *
139.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
139.8 + *
139.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
139.10 + * Other names may be trademarks of their respective owners.
139.11 + *
139.12 + * The contents of this file are subject to the terms of either the GNU
139.13 + * General Public License Version 2 only ("GPL") or the Common
139.14 + * Development and Distribution License("CDDL") (collectively, the
139.15 + * "License"). You may not use this file except in compliance with the
139.16 + * License. You can obtain a copy of the License at
139.17 + * http://www.netbeans.org/cddl-gplv2.html
139.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
139.19 + * specific language governing permissions and limitations under the
139.20 + * License. When distributing the software, include this License Header
139.21 + * Notice in each file and include the License file at
139.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
139.23 + * particular file as subject to the "Classpath" exception as provided
139.24 + * by Oracle in the GPL Version 2 section of the License file that
139.25 + * accompanied this code. If applicable, add the following below the
139.26 + * License Header, with the fields enclosed by brackets [] replaced by
139.27 + * your own identifying information:
139.28 + * "Portions Copyrighted [year] [name of copyright owner]"
139.29 + *
139.30 + * If you wish your version of this file to be governed by only the CDDL
139.31 + * or only the GPL Version 2, indicate your decision by adding
139.32 + * "[Contributor] elects to include this software in this distribution
139.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
139.34 + * single choice of license, a recipient has the option to distribute
139.35 + * your version of this file under either the CDDL, the GPL Version 2 or
139.36 + * to extend the choice of license to its licensees as provided above.
139.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
139.38 + * Version 2 license, then the option applies only if the new code is
139.39 + * made subject to such option by the copyright holder.
139.40 + *
139.41 + * Contributor(s):
139.42 + *
139.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
139.44 + */
139.45 +package org.netbeans.modules.python.hints;
139.46 +
139.47 +import java.util.ArrayList;
139.48 +import java.util.Collections;
139.49 +import java.util.HashMap;
139.50 +import java.util.List;
139.51 +import java.util.Map;
139.52 +import java.util.Set;
139.53 +import java.util.prefs.Preferences;
139.54 +import javax.swing.JComponent;
139.55 +import org.netbeans.editor.BaseDocument;
139.56 +import org.netbeans.modules.csl.api.EditList;
139.57 +import org.netbeans.modules.csl.api.Hint;
139.58 +import org.netbeans.modules.csl.api.HintFix;
139.59 +import org.netbeans.modules.csl.api.HintSeverity;
139.60 +import org.netbeans.modules.csl.api.OffsetRange;
139.61 +import org.netbeans.modules.csl.api.RuleContext;
139.62 +import org.netbeans.modules.python.source.PythonAstUtils;
139.63 +import org.netbeans.modules.python.source.PythonParserResult;
139.64 +import org.netbeans.modules.python.source.ImportEntry;
139.65 +import org.netbeans.modules.python.source.ImportManager;
139.66 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
139.67 +import org.netbeans.modules.python.source.scopes.SymbolTable;
139.68 +import org.openide.filesystems.FileObject;
139.69 +import org.openide.util.NbBundle;
139.70 +import org.python.antlr.PythonTree;
139.71 +import org.python.antlr.ast.Import;
139.72 +import org.python.antlr.ast.ImportFrom;
139.73 +import org.python.antlr.ast.Module;
139.74 +import org.python.antlr.ast.alias;
139.75 +
139.76 +/**
139.77 + * Detect unused imports
139.78 + *
139.79 + * @author Tor Norbye
139.80 + */
139.81 +public class UnusedImports extends PythonAstRule {
139.82 + public UnusedImports() {
139.83 + }
139.84 +
139.85 + @Override
139.86 + public boolean appliesTo(RuleContext context) {
139.87 + FileObject fo = context.parserResult.getSnapshot().getSource().getFileObject();
139.88 + return fo == null || !fo.getName().equals("__init__"); // NOI18N
139.89 + }
139.90 +
139.91 + @Override
139.92 + public Set<Class> getKinds() {
139.93 + return Collections.<Class>singleton(Module.class);
139.94 + }
139.95 +
139.96 + @Override
139.97 + public void run(PythonRuleContext context, List<Hint> result) {
139.98 + computeUnusedImports(this, context, result, null);
139.99 + }
139.100 +
139.101 + private static void computeUnusedImports(UnusedImports detector, PythonRuleContext context, List<Hint> result, Map<PythonTree, List<String>> unused) {
139.102 + assert result == null || unused == null; // compute either results or set of unused
139.103 +
139.104 + PythonParserResult info = (PythonParserResult) context.parserResult;
139.105 + SymbolTable symbolTable = info.getSymbolTable();
139.106 + List<ImportEntry> unusedImports = symbolTable.getUnusedImports();
139.107 + if (unusedImports.isEmpty()) {
139.108 + return;
139.109 + }
139.110 + Map<PythonTree, List<String>> maps = new HashMap<>();
139.111 + for (ImportEntry entry : unusedImports) {
139.112 + maps.put(entry.node, new ArrayList<String>());
139.113 + }
139.114 + for (ImportEntry entry : unusedImports) {
139.115 + if (entry.isFromImport) {
139.116 + String name = entry.asName != null ? entry.asName : entry.symbol;
139.117 + maps.get(entry.node).add(name);
139.118 + } else {
139.119 + String name = entry.asName != null ? entry.asName : entry.module;
139.120 + maps.get(entry.node).add(name);
139.121 + }
139.122 + }
139.123 + for (Map.Entry<PythonTree, List<String>> entry : maps.entrySet()) {
139.124 + PythonTree node = entry.getKey();
139.125 + List<String> list = entry.getValue();
139.126 + if (node instanceof Import) {
139.127 + Import imp = (Import)node;
139.128 + List<alias> names = imp.getInternalNames();
139.129 + if (names != null && names.size() == list.size()) {
139.130 + list.clear();
139.131 + }
139.132 + } else {
139.133 + assert node instanceof ImportFrom;
139.134 + ImportFrom imp = (ImportFrom)node;
139.135 + List<alias> names = imp.getInternalNames();
139.136 + if (names != null && names.size() == list.size()) {
139.137 + list.clear();
139.138 + }
139.139 + }
139.140 + }
139.141 +
139.142 + for (Map.Entry<PythonTree, List<String>> entry : maps.entrySet()) {
139.143 + PythonTree node = entry.getKey();
139.144 + List<String> list = entry.getValue();
139.145 + if (list.size() == 0) {
139.146 + list = null;
139.147 + }
139.148 + if (unused != null) {
139.149 + unused.put(node, list);
139.150 + } else {
139.151 + addError(detector, context, node, list, result);
139.152 + }
139.153 + }
139.154 + }
139.155 +
139.156 + private static void addError(UnusedImports detector, PythonRuleContext context, PythonTree node, List<String> symbols, List<Hint> result) {
139.157 + PythonParserResult info = (PythonParserResult) context.parserResult;
139.158 + OffsetRange range = PythonAstUtils.getNameRange(info, node);
139.159 + range = PythonLexerUtils.getLexerOffsets(info, range);
139.160 + if (range != OffsetRange.NONE) {
139.161 + List<HintFix> fixList = new ArrayList<>(3);
139.162 + fixList.add(new UnusedFix(detector, context, node, symbols, false));
139.163 + fixList.add(new UnusedFix(detector, context, null, null, false)); // Remove All
139.164 + fixList.add(new UnusedFix(detector, context, null, null, true)); // Organize
139.165 + String message;
139.166 + if (symbols != null) {
139.167 + message = NbBundle.getMessage(NameRule.class, "UnusedImportSymbols", symbols);
139.168 + } else {
139.169 + message = NbBundle.getMessage(NameRule.class, "UnusedImport");
139.170 + }
139.171 + Hint desc = new Hint(detector, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2500);
139.172 + result.add(desc);
139.173 + }
139.174 + }
139.175 +
139.176 + @Override
139.177 + public String getId() {
139.178 + return "UnusedImports"; // NOI18N
139.179 + }
139.180 +
139.181 + @Override
139.182 + public String getDisplayName() {
139.183 + return NbBundle.getMessage(NameRule.class, "UnusedImports");
139.184 + }
139.185 +
139.186 + @Override
139.187 + public String getDescription() {
139.188 + return NbBundle.getMessage(NameRule.class, "UnusedImportsDesc");
139.189 + }
139.190 +
139.191 + @Override
139.192 + public boolean getDefaultEnabled() {
139.193 + return true;
139.194 + }
139.195 +
139.196 + @Override
139.197 + public boolean showInTasklist() {
139.198 + return false; // ? or maybe yes?
139.199 + }
139.200 +
139.201 + @Override
139.202 + public HintSeverity getDefaultSeverity() {
139.203 + return HintSeverity.WARNING;
139.204 + }
139.205 +
139.206 + @Override
139.207 + public JComponent getCustomizer(Preferences node) {
139.208 + return null;
139.209 + }
139.210 +
139.211 + /**
139.212 + * Fix to insert self argument or rename first argument to self
139.213 + */
139.214 + private static class UnusedFix implements /*PreviewableFix*/ HintFix { // Preview not particularly helpful and clutters menu
139.215 + private final UnusedImports detector;
139.216 + private final PythonRuleContext context;
139.217 + private final PythonTree node;
139.218 + private final List<String> symbols;
139.219 + private final boolean organizeOnly;
139.220 +
139.221 + private UnusedFix(UnusedImports detector, PythonRuleContext context, PythonTree node, List<String> symbols, boolean organizeOnly) {
139.222 + this.detector = detector;
139.223 + this.context = context;
139.224 + this.node = node;
139.225 + this.symbols = symbols;
139.226 + this.organizeOnly = organizeOnly;
139.227 + }
139.228 +
139.229 + @Override
139.230 + public String getDescription() {
139.231 + if (node == null) {
139.232 + if (organizeOnly) {
139.233 + return NbBundle.getMessage(CreateDocString.class, "OrganizeImports");
139.234 + } else {
139.235 + return NbBundle.getMessage(CreateDocString.class, "DeleteAllUnused");
139.236 + }
139.237 + } else if (symbols != null) {
139.238 + return NbBundle.getMessage(CreateDocString.class, "UnusedFixSymbols", symbols);
139.239 + } else {
139.240 + return NbBundle.getMessage(CreateDocString.class, "UnusedFix");
139.241 + }
139.242 + }
139.243 +
139.244 + public boolean canPreview() {
139.245 + return true;
139.246 + }
139.247 +
139.248 + public EditList getEditList() throws Exception {
139.249 + BaseDocument doc = context.doc;
139.250 + EditList edits = new EditList(doc);
139.251 +
139.252 + ImportManager importManager = new ImportManager((PythonParserResult) context.parserResult);
139.253 +
139.254 + if (node == null) {
139.255 + if (organizeOnly) {
139.256 + importManager.cleanup(edits, 0, doc.getLength(), true);
139.257 + } else {
139.258 + Map<PythonTree, List<String>> onlyNames = new HashMap<>();
139.259 + computeUnusedImports(detector, context, null, onlyNames);
139.260 + Set<PythonTree> candidates = onlyNames.keySet();
139.261 + importManager.removeImports(edits, candidates, false, onlyNames);
139.262 + }
139.263 + } else {
139.264 + Set<PythonTree> candidates = Collections.singleton(node);
139.265 + Map<PythonTree, List<String>> onlyNames = new HashMap<>();
139.266 + onlyNames.put(node, symbols);
139.267 + importManager.removeImports(edits, candidates, false, onlyNames);
139.268 + }
139.269 +
139.270 + return edits;
139.271 + }
139.272 +
139.273 + @Override
139.274 + public void implement() throws Exception {
139.275 + EditList edits = getEditList();
139.276 + edits.apply();
139.277 + }
139.278 +
139.279 + @Override
139.280 + public boolean isSafe() {
139.281 + return true;
139.282 + }
139.283 +
139.284 + @Override
139.285 + public boolean isInteractive() {
139.286 + return false;
139.287 + }
139.288 + }
139.289 +}
140.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
140.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/layer.xml Mon Sep 21 13:01:16 2015 +0200
140.3 @@ -0,0 +1,61 @@
140.4 +<?xml version="1.0" encoding="UTF-8"?>
140.5 +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
140.6 +<filesystem>
140.7 +
140.8 + <folder name="csl-hints">
140.9 + <folder name="text">
140.10 + <folder name="x-python">
140.11 + <folder name="hints">
140.12 + <folder name="general">
140.13 + <attr name="position" intvalue="100"/>
140.14 + <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.python.editor.hints.Bundle"/>
140.15 + <file name="org-netbeans-modules-python-hints-NameRule.instance"/>
140.16 + <file name="org-netbeans-modules-python-hints-CreateDocString.instance"/>
140.17 + <file name="org-netbeans-modules-python-hints-AssignToVariable.instance"/>
140.18 + <file name="org-netbeans-modules-python-hints-SplitImports.instance"/>
140.19 + <file name="org-netbeans-modules-python-hints-RelativeImports.instance"/>
140.20 + <file name="org-netbeans-modules-python-hints-Deprecations.instance"/>
140.21 + <file name="org-netbeans-modules-python-hints-UnusedImports.instance"/>
140.22 + <file name="org-netbeans-modules-python-hints-UnusedDetector.instance"/>
140.23 + <file name="org-netbeans-modules-python-hints-UnresolvedDetector.instance"/>
140.24 + <file name="org-netbeans-modules-python-hints-UnresolvedClassComponents.instance"/>
140.25 + <file name="org-netbeans-modules-python-hints-AllAssignExists.instance"/>
140.26 + <file name="org-netbeans-modules-python-hints-AccessToProtected.instance"/>
140.27 + <file name="org-netbeans-modules-python-hints-AttributeDefinedOutsideInit.instance"/>
140.28 + <file name="org-netbeans-modules-python-hints-ClassCircularRedundancy.instance"/>
140.29 + </folder>
140.30 + </folder>
140.31 + <folder name="selection">
140.32 + <file name="org-netbeans-modules-python-editor-hints-SurroundWith.instance"/>
140.33 + <file name="org-netbeans-modules-python-editor-hints-ExtractCode.instance"/>
140.34 + </folder>
140.35 + </folder>
140.36 + </folder>
140.37 + </folder>
140.38 +
140.39 + <folder name="CslPlugins">
140.40 + <folder name="text">
140.41 + <folder name="x-python">
140.42 + <file name="hints.instance">
140.43 + <attr name="instanceClass" stringvalue="org.netbeans.modules.python.hints.PythonHintsProvider"/>
140.44 + </file>
140.45 + </folder>
140.46 + </folder>
140.47 + </folder>
140.48 +
140.49 + <folder name="OptionsDialog">
140.50 + <folder name="Editor">
140.51 + <folder name="Hints">
140.52 + <attr name="position" intvalue="0"/>
140.53 + <folder name="text">
140.54 + <folder name="x-python">
140.55 + <file name="PythonHints.instance">
140.56 + <attr name="instanceOf" stringvalue="org.netbeans.spi.options.OptionsPanelController"/>
140.57 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.hints.PythonHintOptions.createStatic"/>
140.58 + </file>
140.59 + </folder>
140.60 + </folder>
140.61 + </folder>
140.62 + </folder>
140.63 + </folder>
140.64 +</filesystem>
141.1 --- a/python.project/src/org/netbeans/modules/python/project/GotoTest.java Fri Sep 18 16:20:24 2015 -0500
141.2 +++ b/python.project/src/org/netbeans/modules/python/project/GotoTest.java Mon Sep 21 13:01:16 2015 +0200
141.3 @@ -48,7 +48,7 @@
141.4 import java.util.regex.Pattern;
141.5
141.6
141.7 -import org.netbeans.modules.python.editor.PythonUtils;
141.8 +import org.netbeans.modules.python.source.PythonUtils;
141.9 import org.netbeans.spi.gototest.TestLocator;
141.10 import org.netbeans.spi.gototest.TestLocator.LocationResult;
141.11 import org.openide.filesystems.FileObject;
142.1 --- a/python.project/src/org/netbeans/modules/python/project/PythonLogicalView.java Fri Sep 18 16:20:24 2015 -0500
142.2 +++ b/python.project/src/org/netbeans/modules/python/project/PythonLogicalView.java Mon Sep 21 13:01:16 2015 +0200
142.3 @@ -85,7 +85,8 @@
142.4
142.5 public PythonProjectNode() {
142.6 super(NodeFactorySupport.createCompositeChildren(project, "Projects/org-netbeans-modules-python-project/Nodes"),
142.7 - Lookups.singleton(project));
142.8 + project.sourceRoots.getRoots().length > 0 ? Lookups.fixed(project, project.sourceRoots.getRoots()[0]) :
142.9 + Lookups.singleton(project));
142.10 setIconBaseWithExtension("org/netbeans/modules/python/project/resources/py_25_16.png");
142.11 super.setName(ProjectUtils.getInformation(project).getDisplayName());
142.12 }
143.1 --- a/python.project2/src/org/netbeans/modules/python/project2/PythonProject2.java Fri Sep 18 16:20:24 2015 -0500
143.2 +++ b/python.project2/src/org/netbeans/modules/python/project2/PythonProject2.java Mon Sep 21 13:01:16 2015 +0200
143.3 @@ -24,7 +24,9 @@
143.4 import org.netbeans.spi.project.AuxiliaryConfiguration;
143.5 import org.netbeans.spi.project.ProjectState;
143.6 import org.netbeans.spi.project.ui.LogicalViewProvider;
143.7 +import org.netbeans.spi.project.ui.PrivilegedTemplates;
143.8 import org.netbeans.spi.project.ui.ProjectOpenedHook;
143.9 +import org.netbeans.spi.project.ui.RecommendedTemplates;
143.10 import org.openide.filesystems.FileAttributeEvent;
143.11 import org.openide.filesystems.FileChangeListener;
143.12 import org.openide.filesystems.FileEvent;
143.13 @@ -114,10 +116,11 @@
143.14 // new PythonPlatformProvider(getEvaluator()),
143.15 new PythonCoverageProvider(this),
143.16 new PythonProjectSourceLevelQuery(this),
143.17 + new RecommendedTemplatesImpl(),
143.18 state
143.19 });
143.20 }
143.21 -
143.22 +
143.23 public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
143.24 support.addPropertyChangeListener(propertyChangeListener);
143.25 }
143.26 @@ -379,4 +382,32 @@
143.27 // }
143.28 }
143.29 }
143.30 +
143.31 + private static final class RecommendedTemplatesImpl implements RecommendedTemplates, PrivilegedTemplates {
143.32 +
143.33 + // List of primarily supported templates
143.34 + private static final String[] APPLICATION_TYPES = new String[]{
143.35 + "python", // NOI18N
143.36 + "XML", // NOI18N
143.37 + "simple-files" // NOI18N
143.38 + };
143.39 +
143.40 + private static final String[] PRIVILEGED_NAMES = new String[]{
143.41 + "Templates/Python/_package", // NOI18N
143.42 + "Templates/Python/_module.py", //NOI18N
143.43 + "Templates/Python/_main.py", // NOI18N
143.44 + "Templates/Python/_empty_module.py", // NOI18N
143.45 + "Templates/Python/_test.py", // NOI18N
143.46 + };
143.47 +
143.48 + @Override
143.49 + public String[] getRecommendedTypes() {
143.50 + return APPLICATION_TYPES;
143.51 + }
143.52 +
143.53 + @Override
143.54 + public String[] getPrivilegedTemplates() {
143.55 + return PRIVILEGED_NAMES;
143.56 + }
143.57 + }
143.58 }
144.1 --- a/python.source/manifest.mf Fri Sep 18 16:20:24 2015 -0500
144.2 +++ b/python.source/manifest.mf Mon Sep 21 13:01:16 2015 +0200
144.3 @@ -1,5 +1,6 @@
144.4 Manifest-Version: 1.0
144.5 OpenIDE-Module: org.netbeans.modules.python.source
144.6 +OpenIDE-Module-Layer: org/netbeans/modules/python/source/layer.xml
144.7 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/python/source/Bundle.properties
144.8 -OpenIDE-Module-Specification-Version: 1.0
144.9 +OpenIDE-Module-Specification-Version: 1.1
144.10 AutoUpdate-Show-In-Client: false
145.1 --- a/python.source/nbproject/project.xml Fri Sep 18 16:20:24 2015 -0500
145.2 +++ b/python.source/nbproject/project.xml Mon Sep 21 13:01:16 2015 +0200
145.3 @@ -7,6 +7,15 @@
145.4 <!--<suite-component/>-->
145.5 <module-dependencies>
145.6 <dependency>
145.7 + <code-name-base>org.jython</code-name-base>
145.8 + <build-prerequisite/>
145.9 + <compile-dependency/>
145.10 + <run-dependency>
145.11 + <release-version>2</release-version>
145.12 + <specification-version>2.12</specification-version>
145.13 + </run-dependency>
145.14 + </dependency>
145.15 + <dependency>
145.16 <code-name-base>org.netbeans.api.annotations.common</code-name-base>
145.17 <build-prerequisite/>
145.18 <compile-dependency/>
145.19 @@ -16,6 +25,103 @@
145.20 </run-dependency>
145.21 </dependency>
145.22 <dependency>
145.23 + <code-name-base>org.netbeans.modules.csl.api</code-name-base>
145.24 + <build-prerequisite/>
145.25 + <compile-dependency/>
145.26 + <run-dependency>
145.27 + <release-version>2</release-version>
145.28 + <specification-version>2.51</specification-version>
145.29 + </run-dependency>
145.30 + </dependency>
145.31 + <dependency>
145.32 + <code-name-base>org.netbeans.modules.editor.document</code-name-base>
145.33 + <build-prerequisite/>
145.34 + <compile-dependency/>
145.35 + <run-dependency>
145.36 + <specification-version>1.5</specification-version>
145.37 + </run-dependency>
145.38 + </dependency>
145.39 + <dependency>
145.40 + <code-name-base>org.netbeans.modules.editor.indent</code-name-base>
145.41 + <build-prerequisite/>
145.42 + <compile-dependency/>
145.43 + <run-dependency>
145.44 + <release-version>2</release-version>
145.45 + <specification-version>1.42</specification-version>
145.46 + </run-dependency>
145.47 + </dependency>
145.48 + <dependency>
145.49 + <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
145.50 + <build-prerequisite/>
145.51 + <compile-dependency/>
145.52 + <run-dependency>
145.53 + <release-version>3</release-version>
145.54 + <specification-version>4.3</specification-version>
145.55 + </run-dependency>
145.56 + </dependency>
145.57 + <dependency>
145.58 + <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
145.59 + <build-prerequisite/>
145.60 + <compile-dependency/>
145.61 + <run-dependency>
145.62 + <release-version>1</release-version>
145.63 + <specification-version>2.3</specification-version>
145.64 + </run-dependency>
145.65 + </dependency>
145.66 + <dependency>
145.67 + <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
145.68 + <build-prerequisite/>
145.69 + <compile-dependency/>
145.70 + <run-dependency>
145.71 + <release-version>1</release-version>
145.72 + <specification-version>1.39</specification-version>
145.73 + </run-dependency>
145.74 + </dependency>
145.75 + <dependency>
145.76 + <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
145.77 + <build-prerequisite/>
145.78 + <compile-dependency/>
145.79 + <run-dependency>
145.80 + <release-version>1</release-version>
145.81 + <specification-version>1.55</specification-version>
145.82 + </run-dependency>
145.83 + </dependency>
145.84 + <dependency>
145.85 + <code-name-base>org.netbeans.modules.lexer</code-name-base>
145.86 + <build-prerequisite/>
145.87 + <compile-dependency/>
145.88 + <run-dependency>
145.89 + <release-version>2</release-version>
145.90 + <specification-version>1.62</specification-version>
145.91 + </run-dependency>
145.92 + </dependency>
145.93 + <dependency>
145.94 + <code-name-base>org.netbeans.modules.options.editor</code-name-base>
145.95 + <build-prerequisite/>
145.96 + <compile-dependency/>
145.97 + <run-dependency>
145.98 + <release-version>1</release-version>
145.99 + <specification-version>1.55</specification-version>
145.100 + </run-dependency>
145.101 + </dependency>
145.102 + <dependency>
145.103 + <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
145.104 + <build-prerequisite/>
145.105 + <compile-dependency/>
145.106 + <run-dependency>
145.107 + <release-version>1</release-version>
145.108 + <specification-version>9.5</specification-version>
145.109 + </run-dependency>
145.110 + </dependency>
145.111 + <dependency>
145.112 + <code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
145.113 + <build-prerequisite/>
145.114 + <compile-dependency/>
145.115 + <run-dependency>
145.116 + <specification-version>9.7</specification-version>
145.117 + </run-dependency>
145.118 + </dependency>
145.119 + <dependency>
145.120 <code-name-base>org.netbeans.modules.projectapi</code-name-base>
145.121 <build-prerequisite/>
145.122 <compile-dependency/>
145.123 @@ -25,6 +131,31 @@
145.124 </run-dependency>
145.125 </dependency>
145.126 <dependency>
145.127 + <code-name-base>org.netbeans.modules.python.core</code-name-base>
145.128 + <build-prerequisite/>
145.129 + <compile-dependency/>
145.130 + <run-dependency>
145.131 + <specification-version>1.4</specification-version>
145.132 + </run-dependency>
145.133 + </dependency>
145.134 + <dependency>
145.135 + <code-name-base>org.netbeans.modules.queries</code-name-base>
145.136 + <build-prerequisite/>
145.137 + <compile-dependency/>
145.138 + <run-dependency>
145.139 + <release-version>1</release-version>
145.140 + <specification-version>1.42</specification-version>
145.141 + </run-dependency>
145.142 + </dependency>
145.143 + <dependency>
145.144 + <code-name-base>org.openide.awt</code-name-base>
145.145 + <build-prerequisite/>
145.146 + <compile-dependency/>
145.147 + <run-dependency>
145.148 + <specification-version>7.65</specification-version>
145.149 + </run-dependency>
145.150 + </dependency>
145.151 + <dependency>
145.152 <code-name-base>org.openide.filesystems</code-name-base>
145.153 <build-prerequisite/>
145.154 <compile-dependency/>
145.155 @@ -49,6 +180,38 @@
145.156 </run-dependency>
145.157 </dependency>
145.158 <dependency>
145.159 + <code-name-base>org.openide.loaders</code-name-base>
145.160 + <build-prerequisite/>
145.161 + <compile-dependency/>
145.162 + <run-dependency>
145.163 + <specification-version>7.63</specification-version>
145.164 + </run-dependency>
145.165 + </dependency>
145.166 + <dependency>
145.167 + <code-name-base>org.openide.modules</code-name-base>
145.168 + <build-prerequisite/>
145.169 + <compile-dependency/>
145.170 + <run-dependency>
145.171 + <specification-version>7.47</specification-version>
145.172 + </run-dependency>
145.173 + </dependency>
145.174 + <dependency>
145.175 + <code-name-base>org.openide.nodes</code-name-base>
145.176 + <build-prerequisite/>
145.177 + <compile-dependency/>
145.178 + <run-dependency>
145.179 + <specification-version>7.42</specification-version>
145.180 + </run-dependency>
145.181 + </dependency>
145.182 + <dependency>
145.183 + <code-name-base>org.openide.text</code-name-base>
145.184 + <build-prerequisite/>
145.185 + <compile-dependency/>
145.186 + <run-dependency>
145.187 + <specification-version>6.66</specification-version>
145.188 + </run-dependency>
145.189 + </dependency>
145.190 + <dependency>
145.191 <code-name-base>org.openide.util</code-name-base>
145.192 <build-prerequisite/>
145.193 <compile-dependency/>
145.194 @@ -72,9 +235,21 @@
145.195 <specification-version>9.3</specification-version>
145.196 </run-dependency>
145.197 </dependency>
145.198 + <dependency>
145.199 + <code-name-base>org.openide.windows</code-name-base>
145.200 + <build-prerequisite/>
145.201 + <compile-dependency/>
145.202 + <run-dependency>
145.203 + <specification-version>6.74</specification-version>
145.204 + </run-dependency>
145.205 + </dependency>
145.206 </module-dependencies>
145.207 <public-packages>
145.208 + <package>org.netbeans.modules.python.source</package>
145.209 + <package>org.netbeans.modules.python.source.elements</package>
145.210 + <package>org.netbeans.modules.python.source.lexer</package>
145.211 <package>org.netbeans.modules.python.source.queries</package>
145.212 + <package>org.netbeans.modules.python.source.scopes</package>
145.213 </public-packages>
145.214 </data>
145.215 </configuration>
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
146.2 +++ b/python.source/src/org/netbeans/modules/python/source/AstPath.java Mon Sep 21 13:01:16 2015 +0200
146.3 @@ -0,0 +1,436 @@
146.4 +/*
146.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
146.6 + *
146.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
146.8 + *
146.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
146.10 + * Other names may be trademarks of their respective owners.
146.11 + *
146.12 + * The contents of this file are subject to the terms of either the GNU
146.13 + * General Public License Version 2 only ("GPL") or the Common
146.14 + * Development and Distribution License("CDDL") (collectively, the
146.15 + * "License"). You may not use this file except in compliance with the
146.16 + * License. You can obtain a copy of the License at
146.17 + * http://www.netbeans.org/cddl-gplv2.html
146.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
146.19 + * specific language governing permissions and limitations under the
146.20 + * License. When distributing the software, include this License Header
146.21 + * Notice in each file and include the License file at
146.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
146.23 + * particular file as subject to the "Classpath" exception as provided
146.24 + * by Oracle in the GPL Version 2 section of the License file that
146.25 + * accompanied this code. If applicable, add the following below the
146.26 + * License Header, with the fields enclosed by brackets [] replaced by
146.27 + * your own identifying information:
146.28 + * "Portions Copyrighted [year] [name of copyright owner]"
146.29 + *
146.30 + * Contributor(s):
146.31 + *
146.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
146.33 + */
146.34 +package org.netbeans.modules.python.source;
146.35 +
146.36 +import java.util.ArrayList;
146.37 +import java.util.Iterator;
146.38 +import java.util.ListIterator;
146.39 +import org.openide.util.Exceptions;
146.40 +import org.python.antlr.PythonTree;
146.41 +import org.python.antlr.Visitor;
146.42 +
146.43 +/**
146.44 + * AstPath represents a path from a root node to a particular node in the AST.
146.45 + * This is necessary because the parent node pointers in the nodes aren't always
146.46 + * non null, so we can't just pass a node as a reference to a traversable path
146.47 + * from the root to a node.
146.48 + *
146.49 + * @author Tor Norbye
146.50 + */
146.51 +public class AstPath implements Iterable<PythonTree> {
146.52 + private ArrayList<PythonTree> path = new ArrayList<>(30);
146.53 +
146.54 + public AstPath() {
146.55 + }
146.56 +
146.57 + public AstPath(AstPath other) {
146.58 + path.addAll(other.path);
146.59 + }
146.60 +
146.61 + public AstPath(ArrayList<PythonTree> path) {
146.62 + this.path = path;
146.63 + }
146.64 +
146.65 +// /**
146.66 +// * Initialize a node path to the given caretOffset
146.67 +// */
146.68 +// public AstPath(PythonTree root, int caretOffset) {
146.69 +// findPathTo(root, caretOffset);
146.70 +// }
146.71 +//
146.72 +// /**
146.73 +// * Find the path to the given node in the AST
146.74 +// */
146.75 +// @SuppressWarnings("unchecked")
146.76 +// public AstPath(PythonTree node, PythonTree target) {
146.77 +// if (!find(node, target)) {
146.78 +// path.clear();
146.79 +// } else {
146.80 +// // Reverse the list such that node is on top
146.81 +// // When I get time rewrite the find method to build the list that way in the first place
146.82 +// Collections.reverse(path);
146.83 +// }
146.84 +// }
146.85 + public void descend(PythonTree node) {
146.86 + path.add(node);
146.87 + }
146.88 +
146.89 + public void ascend() {
146.90 + path.remove(path.size() - 1);
146.91 + }
146.92 +
146.93 + /**
146.94 + * Return the closest ancestor of the leaf that is of the given type
146.95 + */
146.96 + public PythonTree getTypedAncestor(Class clz) {
146.97 + return getTypedAncestor(clz, null);
146.98 + }
146.99 +
146.100 + /**
146.101 + * Return the closest ancestor of the given node that is of the given type
146.102 + */
146.103 + public PythonTree getTypedAncestor(Class clz, PythonTree from) {
146.104 + int i = path.size() - 1;
146.105 +
146.106 + // First find the given starting point
146.107 + if (from != null) {
146.108 + for (; i >= 0; i--) {
146.109 + PythonTree node = path.get(i);
146.110 +
146.111 + if (node == from) {
146.112 + break;
146.113 + }
146.114 + }
146.115 + }
146.116 +
146.117 + for (; i >= 0; i--) {
146.118 + PythonTree node = path.get(i);
146.119 +
146.120 + if (clz.isInstance(node)) {
146.121 + return node;
146.122 + }
146.123 + }
146.124 +
146.125 + return null; // not found
146.126 + }
146.127 +
146.128 + /**
146.129 + * Return true iff this path contains a node of the given node type
146.130 + *
146.131 + * @param nodeType The nodeType to check
146.132 + * @return true if the given nodeType is found in the path
146.133 + */
146.134 + public boolean contains(Class clz) {
146.135 + return getTypedAncestor(clz) != null;
146.136 + }
146.137 +
146.138 +// /**
146.139 +// * Find the position closest to the given offset in the AST. Place the path from the leaf up to the path in the
146.140 +// * passed in path list.
146.141 +// */
146.142 +// @SuppressWarnings("unchecked")
146.143 +// public PythonTree findPathTo(PythonTree node, int offset) {
146.144 +// PythonTree result = find(node, offset);
146.145 +// path.add(node);
146.146 +//
146.147 +// // Reverse the list such that node is on top
146.148 +// // When I get time rewrite the find method to build the list that way in the first place
146.149 +// Collections.reverse(path);
146.150 +//
146.151 +// return result;
146.152 +// }
146.153 +//
146.154 +// @SuppressWarnings("unchecked")
146.155 +// private PythonTree find(PythonTree node, int offset) {
146.156 +// int begin = node.getSourceStart();
146.157 +// int end = node.getSourceEnd();
146.158 +//
146.159 +// if ((offset >= begin) && (offset <= end)) {
146.160 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
146.161 +// PythonTree found = find(child, offset);
146.162 +//
146.163 +// if (found != null) {
146.164 +// path.add(child);
146.165 +//
146.166 +// return found;
146.167 +// }
146.168 +// }
146.169 +//
146.170 +// return node;
146.171 +// } else {
146.172 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
146.173 +// PythonTree found = find(child, offset);
146.174 +//
146.175 +// if (found != null) {
146.176 +// path.add(child);
146.177 +//
146.178 +// return found;
146.179 +// }
146.180 +// }
146.181 +//
146.182 +// return null;
146.183 +// }
146.184 +// }
146.185 +//
146.186 +// /**
146.187 +// * Find the path to the given node in the AST
146.188 +// */
146.189 +// @SuppressWarnings("unchecked")
146.190 +// public boolean find(PythonTree node, PythonTree target) {
146.191 +// if (node == target) {
146.192 +// return true;
146.193 +// }
146.194 +//
146.195 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
146.196 +// boolean found = find(child, target);
146.197 +//
146.198 +// if (found) {
146.199 +// path.add(child);
146.200 +//
146.201 +// return found;
146.202 +// }
146.203 +// }
146.204 +//
146.205 +// return false;
146.206 +// }
146.207 + @Override
146.208 + public String toString() {
146.209 + StringBuilder sb = new StringBuilder();
146.210 + sb.append("Path(");
146.211 + sb.append(path.size());
146.212 + sb.append(")=[");
146.213 +
146.214 + for (PythonTree n : path) {
146.215 + String name = n.toString();
146.216 + name = name.substring(name.lastIndexOf('.') + 1);
146.217 + sb.append(name);
146.218 + sb.append(":");
146.219 + }
146.220 +
146.221 + sb.append("]");
146.222 +
146.223 + return sb.toString();
146.224 + }
146.225 +
146.226 + public PythonTree leaf() {
146.227 + if (path.size() == 0) {
146.228 + return null;
146.229 + } else {
146.230 + return path.get(path.size() - 1);
146.231 + }
146.232 + }
146.233 +
146.234 + public PythonTree leafParent() {
146.235 + if (path.size() < 2) {
146.236 + return null;
146.237 + } else {
146.238 + return path.get(path.size() - 2);
146.239 + }
146.240 + }
146.241 +
146.242 + public PythonTree leafGrandParent() {
146.243 + if (path.size() < 3) {
146.244 + return null;
146.245 + } else {
146.246 + return path.get(path.size() - 3);
146.247 + }
146.248 + }
146.249 +
146.250 + /**
146.251 + * Return the top/module level node -- this is not the module node
146.252 + * itself but the first node below it.
146.253 + */
146.254 + public PythonTree topModuleLevel() {
146.255 + if (path.size() >= 2) {
146.256 + return path.get(1);
146.257 + } else {
146.258 + return null;
146.259 + }
146.260 + }
146.261 +
146.262 + public PythonTree root() {
146.263 + if (path.size() == 0) {
146.264 + return null;
146.265 + } else {
146.266 + return path.get(0);
146.267 + }
146.268 + }
146.269 +
146.270 + /** Return an iterator that returns the elements from the leaf back up to the root */
146.271 + @Override
146.272 + public Iterator<PythonTree> iterator() {
146.273 + return new LeafToRootIterator(path);
146.274 + }
146.275 +
146.276 + /** REturn an iterator that starts at the root and walks down to the leaf */
146.277 + public ListIterator<PythonTree> rootToLeaf() {
146.278 + return path.listIterator();
146.279 + }
146.280 +
146.281 + /** Return an iterator that walks from the leaf back up to the root */
146.282 + public ListIterator<PythonTree> leafToRoot() {
146.283 + return new LeafToRootIterator(path);
146.284 + }
146.285 +
146.286 + private static class LeafToRootIterator implements ListIterator<PythonTree> {
146.287 + private final ListIterator<PythonTree> it;
146.288 +
146.289 + private LeafToRootIterator(ArrayList<PythonTree> path) {
146.290 + it = path.listIterator(path.size());
146.291 + }
146.292 +
146.293 + @Override
146.294 + public boolean hasNext() {
146.295 + return it.hasPrevious();
146.296 + }
146.297 +
146.298 + @Override
146.299 + public PythonTree next() {
146.300 + return it.previous();
146.301 + }
146.302 +
146.303 + @Override
146.304 + public boolean hasPrevious() {
146.305 + return it.hasNext();
146.306 + }
146.307 +
146.308 + @Override
146.309 + public PythonTree previous() {
146.310 + return it.next();
146.311 + }
146.312 +
146.313 + @Override
146.314 + public int nextIndex() {
146.315 + return it.previousIndex();
146.316 + }
146.317 +
146.318 + @Override
146.319 + public int previousIndex() {
146.320 + return it.nextIndex();
146.321 + }
146.322 +
146.323 + @Override
146.324 + public void remove() {
146.325 + throw new UnsupportedOperationException("Not supported yet.");
146.326 + }
146.327 +
146.328 + @Override
146.329 + public void set(PythonTree arg0) {
146.330 + throw new UnsupportedOperationException("Not supported yet.");
146.331 + }
146.332 +
146.333 + @Override
146.334 + public void add(PythonTree arg0) {
146.335 + throw new UnsupportedOperationException("Not supported yet.");
146.336 + }
146.337 + }
146.338 +
146.339 + private static class FindByOffsetVisitor extends Visitor {
146.340 + private int targetOffset;
146.341 + private ArrayList<PythonTree> path = new ArrayList<>();
146.342 +
146.343 + private FindByOffsetVisitor(int targetOffset) {
146.344 + this.targetOffset = targetOffset;
146.345 + }
146.346 +
146.347 + @Override
146.348 + public void traverse(PythonTree node) throws Exception {
146.349 + if (targetOffset >= node.getCharStartIndex() && targetOffset <= node.getCharStopIndex()) {
146.350 +// if (targetOffset == node.getCharStopIndex() && node.getClass() == FunctionDef.class) {
146.351 +// // For functions, don't include the last offset, since we can end up with
146.352 +// // functions that overlap - caret at the start position will add BOTH functions
146.353 +// // which we don't want
146.354 +// } else {
146.355 + path.add(node);
146.356 +// }
146.357 + super.traverse(node);
146.358 + }
146.359 + }
146.360 +
146.361 + AstPath getPath() {
146.362 + return new AstPath(path);
146.363 + }
146.364 + }
146.365 +
146.366 + public static AstPath get(PythonTree root, int offset) {
146.367 + FindByOffsetVisitor finder = new FindByOffsetVisitor(offset);
146.368 + try {
146.369 + finder.visit(root);
146.370 + AstPath path = finder.getPath();
146.371 + if (path.path.size() == 0) {
146.372 + path.path.add(root);
146.373 + }
146.374 +
146.375 + return path;
146.376 + } catch (Exception ex) {
146.377 + Exceptions.printStackTrace(ex);
146.378 + }
146.379 +
146.380 + return null;
146.381 + }
146.382 +
146.383 + private static class FindByNodeVisitor extends Visitor {
146.384 + private PythonTree target;
146.385 + private int startOffset;
146.386 + private int endOffset;
146.387 + private ArrayList<PythonTree> path = new ArrayList<>();
146.388 + private boolean found;
146.389 +
146.390 + private FindByNodeVisitor(PythonTree target) {
146.391 + this.target = target;
146.392 + this.startOffset = target.getCharStartIndex();
146.393 + this.endOffset = target.getCharStopIndex();
146.394 + }
146.395 +
146.396 + @Override
146.397 + public void traverse(PythonTree node) throws Exception {
146.398 + if (found) {
146.399 + return;
146.400 + }
146.401 + if (node == target) {
146.402 + path.add(node);
146.403 + found = true;
146.404 + return;
146.405 + }
146.406 + if (startOffset >= node.getCharStartIndex() && endOffset <= node.getCharStopIndex()) {
146.407 + path.add(node);
146.408 + node.traverse(this);
146.409 + if (found) {
146.410 + return;
146.411 + }
146.412 + path.remove(path.size() - 1);
146.413 + }
146.414 + }
146.415 +
146.416 + AstPath getPath() {
146.417 + return new AstPath(path);
146.418 + }
146.419 + }
146.420 +
146.421 + /**
146.422 + * Find the path to the given node in the AST
146.423 + */
146.424 + public static AstPath get(PythonTree root, PythonTree target) {
146.425 + FindByNodeVisitor finder = new FindByNodeVisitor(target);
146.426 + try {
146.427 + finder.visit(root);
146.428 + AstPath path = finder.getPath();
146.429 + if (path.path.size() == 0) {
146.430 + path.path.add(root);
146.431 + }
146.432 +
146.433 + return path;
146.434 + } catch (Exception ex) {
146.435 + Exceptions.printStackTrace(ex);
146.436 + return null;
146.437 + }
146.438 + }
146.439 +}
147.1 --- a/python.source/src/org/netbeans/modules/python/source/Bundle.properties Fri Sep 18 16:20:24 2015 -0500
147.2 +++ b/python.source/src/org/netbeans/modules/python/source/Bundle.properties Mon Sep 21 13:01:16 2015 +0200
147.3 @@ -1,1 +1,3 @@
147.4 OpenIDE-Module-Name=Python Source
147.5 +
147.6 +NoPreference=No Preference
148.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
148.2 +++ b/python.source/src/org/netbeans/modules/python/source/CodeStyle.java Mon Sep 21 13:01:16 2015 +0200
148.3 @@ -0,0 +1,738 @@
148.4 +/*
148.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
148.6 + *
148.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
148.8 + *
148.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
148.10 + * Other names may be trademarks of their respective owners.
148.11 + *
148.12 + * The contents of this file are subject to the terms of either the GNU
148.13 + * General Public License Version 2 only ("GPL") or the Common
148.14 + * Development and Distribution License("CDDL") (collectively, the
148.15 + * "License"). You may not use this file except in compliance with the
148.16 + * License. You can obtain a copy of the License at
148.17 + * http://www.netbeans.org/cddl-gplv2.html
148.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
148.19 + * specific language governing permissions and limitations under the
148.20 + * License. When distributing the software, include this License Header
148.21 + * Notice in each file and include the License file at
148.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
148.23 + * particular file as subject to the "Classpath" exception as provided
148.24 + * by Oracle in the GPL Version 2 section of the License file that
148.25 + * accompanied this code. If applicable, add the following below the
148.26 + * License Header, with the fields enclosed by brackets [] replaced by
148.27 + * your own identifying information:
148.28 + * "Portions Copyrighted [year] [name of copyright owner]"
148.29 + *
148.30 + * Contributor(s):
148.31 + *
148.32 + * The Original Software is NetBeans. The Initial Developer of the Original
148.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
148.34 + * Microsystems, Inc. All Rights Reserved.
148.35 + *
148.36 + * If you wish your version of this file to be governed by only the CDDL
148.37 + * or only the GPL Version 2, indicate your decision by adding
148.38 + * "[Contributor] elects to include this software in this distribution
148.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
148.40 + * single choice of license, a recipient has the option to distribute
148.41 + * your version of this file under either the CDDL, the GPL Version 2 or
148.42 + * to extend the choice of license to its licensees as provided above.
148.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
148.44 + * Version 2 license, then the option applies only if the new code is
148.45 + * made subject to such option by the copyright holder.
148.46 + */
148.47 +package org.netbeans.modules.python.source;
148.48 +
148.49 +import java.util.prefs.Preferences;
148.50 +import javax.swing.text.Document;
148.51 +import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
148.52 +import org.netbeans.modules.python.source.ui.FmtOptions;
148.53 +
148.54 +import org.openide.filesystems.FileObject;
148.55 +import static org.netbeans.modules.python.source.ui.FmtOptions.*;
148.56 +
148.57 +/**
148.58 + * XXX make sure the getters get the defaults from somewhere
148.59 + * XXX add support for profiles
148.60 + * XXX get the preferences node from somewhere else in odrer to be able not to
148.61 + * use the getters and to be able to write to it.
148.62 + *
148.63 + * @author Dusan Balek
148.64 + */
148.65 +public final class CodeStyle {
148.66 + static {
148.67 + FmtOptions.codeStyleProducer = new Producer();
148.68 + }
148.69 + private Preferences preferences;
148.70 +
148.71 + private CodeStyle(Preferences preferences) {
148.72 + this.preferences = preferences;
148.73 + }
148.74 +
148.75 +// /**
148.76 +// * Gets <code>CodeStyle</code> for files in the given project.
148.77 +// *
148.78 +// * <p>Please see the other two <code>getDefault</code> methods as they are
148.79 +// * the preferred way of getting <code>CodeStyle</code>.
148.80 +// *
148.81 +// * @param project The project to get the <code>CodeStyle</code> for.
148.82 +// * @return The current code style that would be used by documents opened
148.83 +// * from files belonging to the <code>project</code>.
148.84 +// *
148.85 +// * @deprecated Please use {@link #getDefault(javax.swing.text.Document)}
148.86 +// * or {@link #getDefault(org.openide.filesystems.FileObject)} respectively.
148.87 +// */
148.88 +// @Deprecated
148.89 +// public static CodeStyle getDefault(Project project) {
148.90 +// return getDefault(project.getProjectDirectory());
148.91 +// }
148.92 + /**
148.93 + * Gets <code>CodeStyle</code> for the given file. If you have a document
148.94 + * instance you should use the {@link #getDefault(javax.swing.text.Document)}
148.95 + * method.
148.96 + *
148.97 + * @param file The file to get the <code>CodeStyle</code> for.
148.98 + * @return The current code style that would be used by a document if the
148.99 + * <code>file</code> were opened in the editor.
148.100 + *
148.101 + * @since 0.39
148.102 + */
148.103 + public synchronized static CodeStyle getDefault(FileObject file) {
148.104 + Preferences prefs = CodeStylePreferences.get(file).getPreferences();
148.105 + return FmtOptions.codeStyleProducer.create(prefs);
148.106 + }
148.107 +
148.108 + /**
148.109 + * Gets <code>CodeStyle</code> for the given document. This is the preferred
148.110 + * method of getting <code>CodeStyle</code>. If you don't have a document
148.111 + * you can use {@link #getDefault(org.openide.filesystems.FileObject)} method instead.
148.112 + *
148.113 + * @param doc The document to get the <code>CodeStyle</code> for.
148.114 + * @return The current code style used by a document. This is the code style that
148.115 + * will be used when formatting the document or generating new code.
148.116 + *
148.117 + * @since 0.39
148.118 + */
148.119 + public synchronized static CodeStyle getDefault(Document doc) {
148.120 + Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
148.121 + return FmtOptions.codeStyleProducer.create(prefs);
148.122 + }
148.123 +
148.124 + // General tabs and indents ------------------------------------------------
148.125 + public boolean expandTabToSpaces() {
148.126 +// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
148.127 + return preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
148.128 + }
148.129 +
148.130 + public int getTabSize() {
148.131 +// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
148.132 + return preferences.getInt(tabSize, getDefaultAsInt(tabSize));
148.133 + }
148.134 +
148.135 + public int getIndentSize() {
148.136 +// System.out.println("~~~ indent-shift-width=" + preferences.get(SimpleValueNames.INDENT_SHIFT_WIDTH, null));
148.137 + int indentLevel = preferences.getInt(indentSize, getDefaultAsInt(indentSize));
148.138 +
148.139 + if (indentLevel <= 0) {
148.140 +// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
148.141 + boolean expandTabs = preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
148.142 + if (expandTabs) {
148.143 +// System.out.println("~~~ spaces-per-tab=" + preferences.get(SimpleValueNames.SPACES_PER_TAB, null));
148.144 + indentLevel = preferences.getInt(spacesPerTab, getDefaultAsInt(spacesPerTab));
148.145 + } else {
148.146 +// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
148.147 + indentLevel = preferences.getInt(tabSize, getDefaultAsInt(tabSize));
148.148 + }
148.149 + }
148.150 +
148.151 + return indentLevel;
148.152 + }
148.153 +
148.154 + public int getContinuationIndentSize() {
148.155 + return preferences.getInt(continuationIndentSize, getDefaultAsInt(continuationIndentSize));
148.156 + }
148.157 +
148.158 + public int getLabelIndent() {
148.159 + return preferences.getInt(labelIndent, getDefaultAsInt(labelIndent));
148.160 + }
148.161 +
148.162 + public boolean absoluteLabelIndent() {
148.163 + return preferences.getBoolean(absoluteLabelIndent, getDefaultAsBoolean(absoluteLabelIndent));
148.164 + }
148.165 +
148.166 + public boolean indentTopLevelClassMembers() {
148.167 + return preferences.getBoolean(indentTopLevelClassMembers, getDefaultAsBoolean(indentTopLevelClassMembers));
148.168 + }
148.169 +
148.170 + public boolean indentCasesFromSwitch() {
148.171 + return preferences.getBoolean(indentCasesFromSwitch, getDefaultAsBoolean(indentCasesFromSwitch));
148.172 + }
148.173 +
148.174 + public int getRightMargin() {
148.175 + return preferences.getInt(rightMargin, getDefaultAsInt(rightMargin));
148.176 + }
148.177 +
148.178 + /*
148.179 + public boolean addLeadingStarInComment() {
148.180 + return preferences.getBoolean(addLeadingStarInComment, getDefaultAsBoolean(addLeadingStarInComment));
148.181 + }
148.182 +
148.183 + // Code generation ---------------------------------------------------------
148.184 +
148.185 + public boolean preferLongerNames() {
148.186 + return preferences.getBoolean(preferLongerNames, getDefaultAsBoolean(preferLongerNames));
148.187 + }
148.188 +
148.189 + public String getFieldNamePrefix() {
148.190 + return preferences.get(fieldNamePrefix, getDefaultAsString(fieldNamePrefix));
148.191 + }
148.192 +
148.193 + public String getFieldNameSuffix() {
148.194 + return preferences.get(fieldNameSuffix, getDefaultAsString(fieldNameSuffix));
148.195 + }
148.196 +
148.197 + public String getStaticFieldNamePrefix() {
148.198 + return preferences.get(staticFieldNamePrefix, getDefaultAsString(staticFieldNamePrefix));
148.199 + }
148.200 +
148.201 + public String getStaticFieldNameSuffix() {
148.202 + return preferences.get(staticFieldNameSuffix, getDefaultAsString(staticFieldNameSuffix));
148.203 + }
148.204 +
148.205 + public String getParameterNamePrefix() {
148.206 + return preferences.get(parameterNamePrefix, getDefaultAsString(parameterNamePrefix));
148.207 + }
148.208 +
148.209 + public String getParameterNameSuffix() {
148.210 + return preferences.get(parameterNameSuffix, getDefaultAsString(parameterNameSuffix));
148.211 + }
148.212 +
148.213 + public String getLocalVarNamePrefix() {
148.214 + return preferences.get(localVarNamePrefix, getDefaultAsString(localVarNamePrefix));
148.215 + }
148.216 +
148.217 + public String getLocalVarNameSuffix() {
148.218 + return preferences.get(localVarNameSuffix, getDefaultAsString(localVarNameSuffix));
148.219 + }
148.220 +
148.221 + public boolean qualifyFieldAccess() {
148.222 + return preferences.getBoolean(qualifyFieldAccess, getDefaultAsBoolean(qualifyFieldAccess));
148.223 + }
148.224 +
148.225 + public boolean useIsForBooleanGetters() {
148.226 + return preferences.getBoolean(useIsForBooleanGetters, getDefaultAsBoolean(useIsForBooleanGetters));
148.227 + }
148.228 +
148.229 + public boolean addOverrideAnnotation() {
148.230 + return preferences.getBoolean(addOverrideAnnotation, getDefaultAsBoolean(addOverrideAnnotation));
148.231 + }
148.232 +
148.233 + public boolean makeLocalVarsFinal() {
148.234 + return preferences.getBoolean(makeLocalVarsFinal, getDefaultAsBoolean(makeLocalVarsFinal));
148.235 + }
148.236 +
148.237 + // Alignment ----------------------------------------------------
148.238 +
148.239 + public boolean alignMultilineMethodParams() {
148.240 + return preferences.getBoolean(alignMultilineMethodParams, getDefaultAsBoolean(alignMultilineMethodParams));
148.241 + }
148.242 +
148.243 + public boolean alignMultilineCallArgs() {
148.244 + return preferences.getBoolean(alignMultilineCallArgs, getDefaultAsBoolean(alignMultilineCallArgs));
148.245 + }
148.246 +
148.247 + public boolean alignMultilineAnnotationArgs() {
148.248 + return preferences.getBoolean(alignMultilineAnnotationArgs, getDefaultAsBoolean(alignMultilineAnnotationArgs));
148.249 + }
148.250 +
148.251 + public boolean alignMultilineImplements() {
148.252 + return preferences.getBoolean(alignMultilineImplements, getDefaultAsBoolean(alignMultilineImplements));
148.253 + }
148.254 +
148.255 + public boolean alignMultilineThrows() {
148.256 + return preferences.getBoolean(alignMultilineThrows, getDefaultAsBoolean(alignMultilineThrows));
148.257 + }
148.258 +
148.259 + public boolean alignMultilineParenthesized() {
148.260 + return preferences.getBoolean(alignMultilineParenthesized, getDefaultAsBoolean(alignMultilineParenthesized));
148.261 + }
148.262 +
148.263 + public boolean alignMultilineBinaryOp() {
148.264 + return preferences.getBoolean(alignMultilineBinaryOp, getDefaultAsBoolean(alignMultilineBinaryOp));
148.265 + }
148.266 +
148.267 + public boolean alignMultilineTernaryOp() {
148.268 + return preferences.getBoolean(alignMultilineTernaryOp, getDefaultAsBoolean(alignMultilineTernaryOp));
148.269 + }
148.270 +
148.271 + public boolean alignMultilineAssignment() {
148.272 + return preferences.getBoolean(alignMultilineAssignment, getDefaultAsBoolean(alignMultilineAssignment));
148.273 + }
148.274 +
148.275 + public boolean alignMultilineFor() {
148.276 + return preferences.getBoolean(alignMultilineFor, getDefaultAsBoolean(alignMultilineFor));
148.277 + }
148.278 +
148.279 + public boolean alignMultilineArrayInit() {
148.280 + return preferences.getBoolean(alignMultilineArrayInit, getDefaultAsBoolean(alignMultilineArrayInit));
148.281 + }
148.282 +
148.283 + public boolean placeElseOnNewLine() {
148.284 + return preferences.getBoolean(placeElseOnNewLine, getDefaultAsBoolean(placeElseOnNewLine));
148.285 + }
148.286 +
148.287 + public boolean placeWhileOnNewLine() {
148.288 + return preferences.getBoolean(placeWhileOnNewLine, getDefaultAsBoolean(placeWhileOnNewLine));
148.289 + }
148.290 +
148.291 + public boolean placeCatchOnNewLine() {
148.292 + return preferences.getBoolean(placeCatchOnNewLine, getDefaultAsBoolean(placeCatchOnNewLine));
148.293 + }
148.294 +
148.295 + public boolean placeFinallyOnNewLine() {
148.296 + return preferences.getBoolean(placeFinallyOnNewLine, getDefaultAsBoolean(placeFinallyOnNewLine));
148.297 + }
148.298 +
148.299 + public boolean placeNewLineAfterModifiers() {
148.300 + return preferences.getBoolean(placeNewLineAfterModifiers, getDefaultAsBoolean(placeNewLineAfterModifiers));
148.301 + }
148.302 +
148.303 + // Wrapping ----------------------------------------------------------------
148.304 +
148.305 + public WrapStyle wrapExtendsImplementsKeyword() {
148.306 + String wrap = preferences.get(wrapExtendsImplementsKeyword, getDefaultAsString(wrapExtendsImplementsKeyword));
148.307 + return WrapStyle.valueOf(wrap);
148.308 + }
148.309 +
148.310 + public WrapStyle wrapExtendsImplementsList() {
148.311 + String wrap = preferences.get(wrapExtendsImplementsList, getDefaultAsString(wrapExtendsImplementsList));
148.312 + return WrapStyle.valueOf(wrap);
148.313 + }
148.314 +
148.315 + public WrapStyle wrapMethodParams() {
148.316 + String wrap = preferences.get(wrapMethodParams, getDefaultAsString(wrapMethodParams));
148.317 + return WrapStyle.valueOf(wrap);
148.318 + }
148.319 +
148.320 + public WrapStyle wrapThrowsKeyword() {
148.321 + String wrap = preferences.get(wrapThrowsKeyword, getDefaultAsString(wrapThrowsKeyword));
148.322 + return WrapStyle.valueOf(wrap);
148.323 + }
148.324 +
148.325 + public WrapStyle wrapThrowsList() {
148.326 + String wrap = preferences.get(wrapThrowsList, getDefaultAsString(wrapThrowsList));
148.327 + return WrapStyle.valueOf(wrap);
148.328 + }
148.329 +
148.330 + public WrapStyle wrapMethodCallArgs() {
148.331 + String wrap = preferences.get(wrapMethodCallArgs, getDefaultAsString(wrapMethodCallArgs));
148.332 + return WrapStyle.valueOf(wrap);
148.333 + }
148.334 +
148.335 + public WrapStyle wrapAnnotationArgs() {
148.336 + String wrap = preferences.get(wrapAnnotationArgs, getDefaultAsString(wrapAnnotationArgs));
148.337 + return WrapStyle.valueOf(wrap);
148.338 + }
148.339 +
148.340 + public WrapStyle wrapChainedMethodCalls() {
148.341 + String wrap = preferences.get(wrapChainedMethodCalls, getDefaultAsString(wrapChainedMethodCalls));
148.342 + return WrapStyle.valueOf(wrap);
148.343 + }
148.344 +
148.345 + public WrapStyle wrapArrayInit() {
148.346 + String wrap = preferences.get(wrapArrayInit, getDefaultAsString(wrapArrayInit));
148.347 + return WrapStyle.valueOf(wrap);
148.348 + }
148.349 +
148.350 + public WrapStyle wrapFor() {
148.351 + String wrap = preferences.get(wrapFor, getDefaultAsString(wrapFor));
148.352 + return WrapStyle.valueOf(wrap);
148.353 + }
148.354 +
148.355 + public WrapStyle wrapForStatement() {
148.356 + String wrap = preferences.get(wrapForStatement, getDefaultAsString(wrapForStatement));
148.357 + return WrapStyle.valueOf(wrap);
148.358 + }
148.359 +
148.360 + public WrapStyle wrapIfStatement() {
148.361 + String wrap = preferences.get(wrapIfStatement, getDefaultAsString(wrapIfStatement));
148.362 + return WrapStyle.valueOf(wrap);
148.363 + }
148.364 +
148.365 + public WrapStyle wrapWhileStatement() {
148.366 + String wrap = preferences.get(wrapWhileStatement, getDefaultAsString(wrapWhileStatement));
148.367 + return WrapStyle.valueOf(wrap);
148.368 + }
148.369 +
148.370 + public WrapStyle wrapDoWhileStatement() {
148.371 + String wrap = preferences.get(wrapDoWhileStatement, getDefaultAsString(wrapDoWhileStatement));
148.372 + return WrapStyle.valueOf(wrap);
148.373 + }
148.374 +
148.375 + public WrapStyle wrapAssert() {
148.376 + String wrap = preferences.get(wrapAssert, getDefaultAsString(wrapAssert));
148.377 + return WrapStyle.valueOf(wrap);
148.378 + }
148.379 +
148.380 + public WrapStyle wrapEnumConstants() {
148.381 + String wrap = preferences.get(wrapEnumConstants, getDefaultAsString(wrapEnumConstants));
148.382 + return WrapStyle.valueOf(wrap);
148.383 + }
148.384 +
148.385 + public WrapStyle wrapAnnotations() {
148.386 + String wrap = preferences.get(wrapAnnotations, getDefaultAsString(wrapAnnotations));
148.387 + return WrapStyle.valueOf(wrap);
148.388 + }
148.389 +
148.390 + public WrapStyle wrapBinaryOps() {
148.391 + String wrap = preferences.get(wrapBinaryOps, getDefaultAsString(wrapBinaryOps));
148.392 + return WrapStyle.valueOf(wrap);
148.393 + }
148.394 +
148.395 + public WrapStyle wrapTernaryOps() {
148.396 + String wrap = preferences.get(wrapTernaryOps, getDefaultAsString(wrapTernaryOps));
148.397 + return WrapStyle.valueOf(wrap);
148.398 + }
148.399 +
148.400 + public WrapStyle wrapAssignOps() {
148.401 + String wrap = preferences.get(wrapAssignOps, getDefaultAsString(wrapAssignOps));
148.402 + return WrapStyle.valueOf(wrap);
148.403 + }
148.404 +
148.405 + // Blank lines -------------------------------------------------------------
148.406 +
148.407 + public int getBlankLinesBeforePackage() {
148.408 + return preferences.getInt(blankLinesBeforePackage, getDefaultAsInt(blankLinesBeforePackage));
148.409 + }
148.410 +
148.411 + public int getBlankLinesAfterPackage() {
148.412 + return preferences.getInt(blankLinesAfterPackage, getDefaultAsInt(blankLinesAfterPackage));
148.413 + }
148.414 +
148.415 + public int getBlankLinesBeforeImports() {
148.416 + return preferences.getInt(blankLinesBeforeImports, getDefaultAsInt(blankLinesBeforeImports));
148.417 + }
148.418 +
148.419 + public int getBlankLinesAfterImports() {
148.420 + return preferences.getInt(blankLinesAfterImports, getDefaultAsInt(blankLinesAfterImports));
148.421 + }
148.422 +
148.423 + public int getBlankLinesBeforeClass() {
148.424 + return preferences.getInt(blankLinesBeforeClass, getDefaultAsInt(blankLinesBeforeClass));
148.425 + }
148.426 +
148.427 + public int getBlankLinesAfterClass() {
148.428 + return preferences.getInt(blankLinesAfterClass, getDefaultAsInt(blankLinesAfterClass));
148.429 + }
148.430 +
148.431 + public int getBlankLinesAfterClassHeader() {
148.432 + return preferences.getInt(blankLinesAfterClassHeader, getDefaultAsInt(blankLinesAfterClassHeader));
148.433 + }
148.434 +
148.435 + public int getBlankLinesBeforeFields() {
148.436 + return preferences.getInt(blankLinesBeforeFields, getDefaultAsInt(blankLinesBeforeFields));
148.437 + }
148.438 +
148.439 + public int getBlankLinesAfterFields() {
148.440 + return preferences.getInt(blankLinesAfterFields, getDefaultAsInt(blankLinesAfterFields));
148.441 + }
148.442 +
148.443 + public int getBlankLinesBeforeMethods() {
148.444 + return preferences.getInt(blankLinesBeforeMethods, getDefaultAsInt(blankLinesBeforeMethods));
148.445 + }
148.446 +
148.447 + public int getBlankLinesAfterMethods() {
148.448 + return preferences.getInt(blankLinesAfterMethods, getDefaultAsInt(blankLinesAfterMethods));
148.449 + }
148.450 +
148.451 + // Spaces ------------------------------------------------------------------
148.452 +
148.453 + public boolean spaceBeforeWhile() {
148.454 + return preferences.getBoolean(spaceBeforeWhile, getDefaultAsBoolean(spaceBeforeWhile));
148.455 + }
148.456 +
148.457 + public boolean spaceBeforeElse() {
148.458 + return preferences.getBoolean(spaceBeforeElse, getDefaultAsBoolean(spaceBeforeElse));
148.459 + }
148.460 +
148.461 + public boolean spaceBeforeCatch() {
148.462 + return preferences.getBoolean(spaceBeforeCatch, getDefaultAsBoolean(spaceBeforeCatch));
148.463 + }
148.464 +
148.465 + public boolean spaceBeforeFinally() {
148.466 + return preferences.getBoolean(spaceBeforeFinally, getDefaultAsBoolean(spaceBeforeFinally));
148.467 + }
148.468 +
148.469 + public boolean spaceBeforeMethodDeclParen() {
148.470 + return preferences.getBoolean(spaceBeforeMethodDeclParen, getDefaultAsBoolean(spaceBeforeMethodDeclParen));
148.471 + }
148.472 +
148.473 + public boolean spaceBeforeMethodCallParen() {
148.474 + return preferences.getBoolean(spaceBeforeMethodCallParen, getDefaultAsBoolean(spaceBeforeMethodCallParen));
148.475 + }
148.476 +
148.477 + public boolean spaceBeforeIfParen() {
148.478 + return preferences.getBoolean(spaceBeforeIfParen, getDefaultAsBoolean(spaceBeforeIfParen));
148.479 + }
148.480 +
148.481 + public boolean spaceBeforeForParen() {
148.482 + return preferences.getBoolean(spaceBeforeForParen, getDefaultAsBoolean(spaceBeforeForParen));
148.483 + }
148.484 +
148.485 + public boolean spaceBeforeWhileParen() {
148.486 + return preferences.getBoolean(spaceBeforeWhileParen, getDefaultAsBoolean(spaceBeforeWhileParen));
148.487 + }
148.488 +
148.489 + public boolean spaceBeforeCatchParen() {
148.490 + return preferences.getBoolean(spaceBeforeCatchParen, getDefaultAsBoolean(spaceBeforeCatchParen));
148.491 + }
148.492 +
148.493 + public boolean spaceBeforeSwitchParen() {
148.494 + return preferences.getBoolean(spaceBeforeSwitchParen, getDefaultAsBoolean(spaceBeforeSwitchParen));
148.495 + }
148.496 +
148.497 + public boolean spaceBeforeSynchronizedParen() {
148.498 + return preferences.getBoolean(spaceBeforeSynchronizedParen, getDefaultAsBoolean(spaceBeforeSynchronizedParen));
148.499 + }
148.500 +
148.501 + public boolean spaceBeforeAnnotationParen() {
148.502 + return preferences.getBoolean(spaceBeforeAnnotationParen, getDefaultAsBoolean(spaceBeforeAnnotationParen));
148.503 + }
148.504 +
148.505 + public boolean spaceAroundUnaryOps() {
148.506 + return preferences.getBoolean(spaceAroundUnaryOps, getDefaultAsBoolean(spaceAroundUnaryOps));
148.507 + }
148.508 +
148.509 + public boolean spaceAroundBinaryOps() {
148.510 + return preferences.getBoolean(spaceAroundBinaryOps, getDefaultAsBoolean(spaceAroundBinaryOps));
148.511 + }
148.512 +
148.513 + public boolean spaceAroundTernaryOps() {
148.514 + return preferences.getBoolean(spaceAroundTernaryOps, getDefaultAsBoolean(spaceAroundTernaryOps));
148.515 + }
148.516 +
148.517 + public boolean spaceAroundAssignOps() {
148.518 + return preferences.getBoolean(spaceAroundAssignOps, getDefaultAsBoolean(spaceAroundAssignOps));
148.519 + }
148.520 +
148.521 + public boolean spaceBeforeClassDeclLeftBrace() {
148.522 + return preferences.getBoolean(spaceBeforeClassDeclLeftBrace, getDefaultAsBoolean(spaceBeforeClassDeclLeftBrace));
148.523 + }
148.524 +
148.525 + public boolean spaceBeforeMethodDeclLeftBrace() {
148.526 + return preferences.getBoolean(spaceBeforeMethodDeclLeftBrace, getDefaultAsBoolean(spaceBeforeMethodDeclLeftBrace));
148.527 + }
148.528 +
148.529 + public boolean spaceBeforeIfLeftBrace() {
148.530 + return preferences.getBoolean(spaceBeforeIfLeftBrace, getDefaultAsBoolean(spaceBeforeIfLeftBrace));
148.531 + }
148.532 +
148.533 + public boolean spaceBeforeElseLeftBrace() {
148.534 + return preferences.getBoolean(spaceBeforeElseLeftBrace, getDefaultAsBoolean(spaceBeforeElseLeftBrace));
148.535 + }
148.536 +
148.537 + public boolean spaceBeforeWhileLeftBrace() {
148.538 + return preferences.getBoolean(spaceBeforeWhileLeftBrace, getDefaultAsBoolean(spaceBeforeWhileLeftBrace));
148.539 + }
148.540 +
148.541 + public boolean spaceBeforeForLeftBrace() {
148.542 + return preferences.getBoolean(spaceBeforeForLeftBrace, getDefaultAsBoolean(spaceBeforeForLeftBrace));
148.543 + }
148.544 +
148.545 + public boolean spaceBeforeDoLeftBrace() {
148.546 + return preferences.getBoolean(spaceBeforeDoLeftBrace, getDefaultAsBoolean(spaceBeforeDoLeftBrace));
148.547 + }
148.548 +
148.549 + public boolean spaceBeforeSwitchLeftBrace() {
148.550 + return preferences.getBoolean(spaceBeforeSwitchLeftBrace, getDefaultAsBoolean(spaceBeforeSwitchLeftBrace));
148.551 + }
148.552 +
148.553 + public boolean spaceBeforeTryLeftBrace() {
148.554 + return preferences.getBoolean(spaceBeforeTryLeftBrace, getDefaultAsBoolean(spaceBeforeTryLeftBrace));
148.555 + }
148.556 +
148.557 + public boolean spaceBeforeCatchLeftBrace() {
148.558 + return preferences.getBoolean(spaceBeforeCatchLeftBrace, getDefaultAsBoolean(spaceBeforeCatchLeftBrace));
148.559 + }
148.560 +
148.561 + public boolean spaceBeforeFinallyLeftBrace() {
148.562 + return preferences.getBoolean(spaceBeforeFinallyLeftBrace, getDefaultAsBoolean(spaceBeforeFinallyLeftBrace));
148.563 + }
148.564 +
148.565 + public boolean spaceBeforeSynchronizedLeftBrace() {
148.566 + return preferences.getBoolean(spaceBeforeSynchronizedLeftBrace, getDefaultAsBoolean(spaceBeforeSynchronizedLeftBrace));
148.567 + }
148.568 +
148.569 + public boolean spaceBeforeStaticInitLeftBrace() {
148.570 + return preferences.getBoolean(spaceBeforeStaticInitLeftBrace, getDefaultAsBoolean(spaceBeforeStaticInitLeftBrace));
148.571 + }
148.572 +
148.573 + public boolean spaceBeforeArrayInitLeftBrace() {
148.574 + return preferences.getBoolean(spaceBeforeArrayInitLeftBrace, getDefaultAsBoolean(spaceBeforeArrayInitLeftBrace));
148.575 + }
148.576 +
148.577 + public boolean spaceWithinParens() {
148.578 + return preferences.getBoolean(spaceWithinParens, getDefaultAsBoolean(spaceWithinParens));
148.579 + }
148.580 +
148.581 + public boolean spaceWithinMethodDeclParens() {
148.582 + return preferences.getBoolean(spaceWithinMethodDeclParens, getDefaultAsBoolean(spaceWithinMethodDeclParens));
148.583 + }
148.584 +
148.585 + public boolean spaceWithinMethodCallParens() {
148.586 + return preferences.getBoolean(spaceWithinMethodCallParens, getDefaultAsBoolean(spaceWithinMethodCallParens));
148.587 + }
148.588 +
148.589 + public boolean spaceWithinIfParens() {
148.590 + return preferences.getBoolean(spaceWithinIfParens, getDefaultAsBoolean(spaceWithinIfParens));
148.591 + }
148.592 +
148.593 + public boolean spaceWithinForParens() {
148.594 + return preferences.getBoolean(spaceWithinForParens, getDefaultAsBoolean(spaceWithinForParens));
148.595 + }
148.596 +
148.597 + public boolean spaceWithinWhileParens() {
148.598 + return preferences.getBoolean(spaceWithinWhileParens, getDefaultAsBoolean(spaceWithinWhileParens));
148.599 + }
148.600 +
148.601 + public boolean spaceWithinSwitchParens() {
148.602 + return preferences.getBoolean(spaceWithinSwitchParens, getDefaultAsBoolean(spaceWithinSwitchParens));
148.603 + }
148.604 +
148.605 + public boolean spaceWithinCatchParens() {
148.606 + return preferences.getBoolean(spaceWithinCatchParens, getDefaultAsBoolean(spaceWithinCatchParens));
148.607 + }
148.608 +
148.609 + public boolean spaceWithinSynchronizedParens() {
148.610 + return preferences.getBoolean(spaceWithinSynchronizedParens, getDefaultAsBoolean(spaceWithinSynchronizedParens));
148.611 + }
148.612 +
148.613 + public boolean spaceWithinTypeCastParens() {
148.614 + return preferences.getBoolean(spaceWithinTypeCastParens, getDefaultAsBoolean(spaceWithinTypeCastParens));
148.615 + }
148.616 +
148.617 + public boolean spaceWithinAnnotationParens() {
148.618 + return preferences.getBoolean(spaceWithinAnnotationParens, getDefaultAsBoolean(spaceWithinAnnotationParens));
148.619 + }
148.620 +
148.621 + public boolean spaceWithinBraces() {
148.622 + return preferences.getBoolean(spaceWithinBraces, getDefaultAsBoolean(spaceWithinBraces));
148.623 + }
148.624 +
148.625 + public boolean spaceWithinArrayInitBrackets() {
148.626 + return preferences.getBoolean(spaceWithinArrayInitBrackets, getDefaultAsBoolean(spaceWithinArrayInitBrackets));
148.627 + }
148.628 +
148.629 + public boolean spaceBeforeComma() {
148.630 + return preferences.getBoolean(spaceBeforeComma, getDefaultAsBoolean(spaceBeforeComma));
148.631 + }
148.632 +
148.633 + public boolean spaceAfterComma() {
148.634 + return preferences.getBoolean(spaceAfterComma, getDefaultAsBoolean(spaceAfterComma));
148.635 + }
148.636 +
148.637 + public boolean spaceBeforeSemi() {
148.638 + return preferences.getBoolean(spaceBeforeSemi, getDefaultAsBoolean(spaceBeforeSemi));
148.639 + }
148.640 +
148.641 + public boolean spaceAfterSemi() {
148.642 + return preferences.getBoolean(spaceAfterSemi, getDefaultAsBoolean(spaceAfterSemi));
148.643 + }
148.644 +
148.645 + public boolean spaceBeforeColon() {
148.646 + return preferences.getBoolean(spaceBeforeColon, getDefaultAsBoolean(spaceBeforeColon));
148.647 + }
148.648 +
148.649 + public boolean spaceAfterColon() {
148.650 + return preferences.getBoolean(spaceAfterColon, getDefaultAsBoolean(spaceAfterColon));
148.651 + }
148.652 +
148.653 + public boolean spaceAfterTypeCast() {
148.654 + return preferences.getBoolean(spaceAfterTypeCast, getDefaultAsBoolean(spaceAfterTypeCast));
148.655 + }
148.656 +
148.657 + */
148.658 + // Spaces -----------------------------------------------------------------
148.659 + public boolean addSpaceAroundOperators() {
148.660 + return preferences.getBoolean(addSpaceAroundOperators, getDefaultAsBoolean(addSpaceAroundOperators));
148.661 + }
148.662 +
148.663 + public boolean removeSpaceInsideParens() {
148.664 + return preferences.getBoolean(removeSpaceInParens, getDefaultAsBoolean(removeSpaceInParens));
148.665 + }
148.666 +
148.667 + public boolean addSpaceAfterComma() {
148.668 + return preferences.getBoolean(addSpaceAfterComma, getDefaultAsBoolean(addSpaceAfterComma));
148.669 + }
148.670 +
148.671 + public boolean removeSpaceBeforeSep() {
148.672 + return preferences.getBoolean(removeSpaceBeforeSep, getDefaultAsBoolean(removeSpaceBeforeSep));
148.673 + }
148.674 +
148.675 + public boolean removeSpaceInParamAssign() {
148.676 + return preferences.getBoolean(removeSpaceInParamAssign, getDefaultAsBoolean(removeSpaceInParamAssign));
148.677 + }
148.678 +
148.679 + public boolean collapseSpaces() {
148.680 + return preferences.getBoolean(collapseSpaces, getDefaultAsBoolean(collapseSpaces));
148.681 + }
148.682 +
148.683 + // Imports -----------------------------------------------------------------
148.684 + public boolean formatImports() {
148.685 + return preferences.getBoolean(formatImports, getDefaultAsBoolean(formatImports));
148.686 + }
148.687 +
148.688 + public boolean oneImportPerLine() {
148.689 + return preferences.getBoolean(oneImportPerLine, getDefaultAsBoolean(oneImportPerLine));
148.690 + }
148.691 +
148.692 + public boolean removeDuplicates() {
148.693 + return preferences.getBoolean(removeDuplicates, getDefaultAsBoolean(removeDuplicates));
148.694 + }
148.695 +
148.696 + public boolean systemLibsFirst() {
148.697 + return preferences.getBoolean(systemLibsFirst, getDefaultAsBoolean(systemLibsFirst));
148.698 + }
148.699 +
148.700 + public boolean preferSymbolImports() {
148.701 + return preferences.getBoolean(preferSymbolImports, getDefaultAsBoolean(preferSymbolImports));
148.702 + }
148.703 +
148.704 + public boolean sortImports() {
148.705 + return preferences.getBoolean(sortImports, getDefaultAsBoolean(sortImports));
148.706 + }
148.707 +
148.708 + public boolean separateFromImps() {
148.709 + return preferences.getBoolean(separateFromImps, getDefaultAsBoolean(separateFromImps));
148.710 + }
148.711 +
148.712 + public ImportCleanupStyle cleanupImports() {
148.713 + String cleanup = preferences.get(cleanupUnusedImports, getDefaultAsString(cleanupUnusedImports));
148.714 + return ImportCleanupStyle.valueOf(cleanup);
148.715 + }
148.716 +
148.717 + public String[] getPackagesForStarImport() {
148.718 + return null;
148.719 + }
148.720 +
148.721 + // Nested classes ----------------------------------------------------------
148.722 + public enum WrapStyle {
148.723 + WRAP_ALWAYS,
148.724 + WRAP_IF_LONG,
148.725 + WRAP_NEVER
148.726 + }
148.727 +
148.728 + public enum ImportCleanupStyle {
148.729 + LEAVE_ALONE,
148.730 + COMMENT_OUT,
148.731 + DELETE
148.732 + }
148.733 +
148.734 + // Communication with non public packages ----------------------------------
148.735 + private static class Producer implements FmtOptions.CodeStyleProducer {
148.736 + @Override
148.737 + public CodeStyle create(Preferences preferences) {
148.738 + return new CodeStyle(preferences);
148.739 + }
148.740 + }
148.741 +}
149.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
149.2 +++ b/python.source/src/org/netbeans/modules/python/source/ImportEntry.java Mon Sep 21 13:01:16 2015 +0200
149.3 @@ -0,0 +1,171 @@
149.4 +/*
149.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
149.6 + *
149.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
149.8 + *
149.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
149.10 + * Other names may be trademarks of their respective owners.
149.11 + *
149.12 + * The contents of this file are subject to the terms of either the GNU
149.13 + * General Public License Version 2 only ("GPL") or the Common
149.14 + * Development and Distribution License("CDDL") (collectively, the
149.15 + * "License"). You may not use this file except in compliance with the
149.16 + * License. You can obtain a copy of the License at
149.17 + * http://www.netbeans.org/cddl-gplv2.html
149.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
149.19 + * specific language governing permissions and limitations under the
149.20 + * License. When distributing the software, include this License Header
149.21 + * Notice in each file and include the License file at
149.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
149.23 + * particular file as subject to the "Classpath" exception as provided
149.24 + * by Oracle in the GPL Version 2 section of the License file that
149.25 + * accompanied this code. If applicable, add the following below the
149.26 + * License Header, with the fields enclosed by brackets [] replaced by
149.27 + * your own identifying information:
149.28 + * "Portions Copyrighted [year] [name of copyright owner]"
149.29 + *
149.30 + * Contributor(s):
149.31 + *
149.32 + * The Original Software is NetBeans. The Initial Developer of the Original
149.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
149.34 + * Microsystems, Inc. All Rights Reserved.
149.35 + *
149.36 + * If you wish your version of this file to be governed by only the CDDL
149.37 + * or only the GPL Version 2, indicate your decision by adding
149.38 + * "[Contributor] elects to include this software in this distribution
149.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
149.40 + * single choice of license, a recipient has the option to distribute
149.41 + * your version of this file under either the CDDL, the GPL Version 2 or
149.42 + * to extend the choice of license to its licensees as provided above.
149.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
149.44 + * Version 2 license, then the option applies only if the new code is
149.45 + * made subject to such option by the copyright holder.
149.46 + */
149.47 +package org.netbeans.modules.python.source;
149.48 +
149.49 +import org.python.antlr.PythonTree;
149.50 +
149.51 +/**
149.52 + * State about a single atomic import. (A single import statement in Python
149.53 + * can correspond to many atomic imports: one for each symbol or module
149.54 + * imported)
149.55 + *
149.56 + * @author Tor Norbye
149.57 + */
149.58 +public class ImportEntry implements Comparable<ImportEntry> {
149.59 + public final String module;
149.60 + public final String asName;
149.61 + public final String symbol;
149.62 + public final boolean isSystem;
149.63 + public final boolean isFromImport;
149.64 + /**
149.65 + * Natural order of import statements (in the source). This will be non zero if
149.66 + * we want to preserve the original order rather than the alphabetical order.
149.67 + */
149.68 + public int ordinal;
149.69 + /**
149.70 + * Corresponding import statement node. This will be non null if we want to consider
149.71 + * duplicate import statements as different
149.72 + */
149.73 + public PythonTree node;
149.74 + /**
149.75 + * Whether we have a symbol import AND we're sorting by symbol imports.
149.76 + * Will be false even for symbol imports when we're not sorting by symbols.
149.77 + */
149.78 + public boolean sortedFrom;
149.79 +
149.80 + public ImportEntry(String module, String symbol, String asName, boolean isSystem, PythonTree node, int ordinal) {
149.81 + super();
149.82 + this.module = module;
149.83 + this.symbol = symbol;
149.84 + this.asName = asName;
149.85 + this.isSystem = isSystem;
149.86 + this.isFromImport = symbol != null;
149.87 + this.node = node;
149.88 + this.ordinal = ordinal;
149.89 +
149.90 + this.sortedFrom = symbol != null;
149.91 + }
149.92 +
149.93 + public ImportEntry(String module, String asName, boolean isSystem, PythonTree node, int ordinal) {
149.94 + this(module, null, asName, isSystem, node, ordinal);
149.95 + }
149.96 +
149.97 + @Override
149.98 + public boolean equals(Object obj) {
149.99 + if (obj == null) {
149.100 + return false;
149.101 + }
149.102 + if (getClass() != obj.getClass()) {
149.103 + return false;
149.104 + }
149.105 + final ImportEntry other = (ImportEntry)obj;
149.106 + if (this.node != other.node) {
149.107 + return false;
149.108 + }
149.109 + if ((this.module == null) ? (other.module != null) : !this.module.equals(other.module)) {
149.110 + return false;
149.111 + }
149.112 + if ((this.asName == null) ? (other.asName != null) : !this.asName.equals(other.asName)) {
149.113 + return false;
149.114 + }
149.115 + if ((this.symbol == null) ? (other.symbol != null) : !this.symbol.equals(other.symbol)) {
149.116 + return false;
149.117 + }
149.118 + return true;
149.119 + }
149.120 +
149.121 + @Override
149.122 + public int hashCode() {
149.123 + int hash = 7;
149.124 + hash = 29 * hash + (this.module != null ? this.module.hashCode() : 0);
149.125 + return hash;
149.126 + }
149.127 +
149.128 + @Override
149.129 + public int compareTo(ImportEntry other) {
149.130 + boolean thisIsFuture = "__future__".equals(module); // NOI18N
149.131 + boolean otherIsFuture = "__future__".equals(other.module); // NOI18N
149.132 + if (thisIsFuture != otherIsFuture) {
149.133 + return thisIsFuture ? -1 : 1;
149.134 + }
149.135 + if (isSystem != other.isSystem) {
149.136 + return isSystem ? -1 : 1;
149.137 + }
149.138 + if (sortedFrom != other.sortedFrom) {
149.139 + return sortedFrom ? 1 : -1;
149.140 + }
149.141 + if (ordinal != other.ordinal) {
149.142 + return ordinal - other.ordinal;
149.143 + }
149.144 + // Then we sort by module name
149.145 + int result = module.compareTo(other.module);
149.146 + if (result != 0) {
149.147 + return result;
149.148 + }
149.149 + // And then, for each module, first the imports, then the from imports
149.150 + if (isFromImport != other.isFromImport) {
149.151 + return isFromImport ? 1 : -1;
149.152 + }
149.153 + if (symbol != null) {
149.154 + assert other.symbol != null;
149.155 + // since isFromImport==
149.156 + result = symbol.compareTo(other.symbol);
149.157 + if (result != 0) {
149.158 + return result;
149.159 + }
149.160 + }
149.161 + if (asName == null) {
149.162 + return (other.asName == null) ? 0 : 1;
149.163 + }
149.164 + if (other.asName == null) {
149.165 + return -1;
149.166 + }
149.167 + return asName.compareTo(other.asName);
149.168 + }
149.169 +
149.170 + @Override
149.171 + public String toString() {
149.172 + return "ImportEntry(" + module + ", " + symbol + ", " + asName + ")"; // NOI18N
149.173 + }
149.174 +}
150.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150.2 +++ b/python.source/src/org/netbeans/modules/python/source/ImportManager.java Mon Sep 21 13:01:16 2015 +0200
150.3 @@ -0,0 +1,1048 @@
150.4 +/*
150.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
150.6 + *
150.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
150.8 + *
150.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
150.10 + * Other names may be trademarks of their respective owners.
150.11 + *
150.12 + * The contents of this file are subject to the terms of either the GNU
150.13 + * General Public License Version 2 only ("GPL") or the Common
150.14 + * Development and Distribution License("CDDL") (collectively, the
150.15 + * "License"). You may not use this file except in compliance with the
150.16 + * License. You can obtain a copy of the License at
150.17 + * http://www.netbeans.org/cddl-gplv2.html
150.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
150.19 + * specific language governing permissions and limitations under the
150.20 + * License. When distributing the software, include this License Header
150.21 + * Notice in each file and include the License file at
150.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
150.23 + * particular file as subject to the "Classpath" exception as provided
150.24 + * by Oracle in the GPL Version 2 section of the License file that
150.25 + * accompanied this code. If applicable, add the following below the
150.26 + * License Header, with the fields enclosed by brackets [] replaced by
150.27 + * your own identifying information:
150.28 + * "Portions Copyrighted [year] [name of copyright owner]"
150.29 + *
150.30 + * If you wish your version of this file to be governed by only the CDDL
150.31 + * or only the GPL Version 2, indicate your decision by adding
150.32 + * "[Contributor] elects to include this software in this distribution
150.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
150.34 + * single choice of license, a recipient has the option to distribute
150.35 + * your version of this file under either the CDDL, the GPL Version 2 or
150.36 + * to extend the choice of license to its licensees as provided above.
150.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
150.38 + * Version 2 license, then the option applies only if the new code is
150.39 + * made subject to such option by the copyright holder.
150.40 + *
150.41 + * Contributor(s):
150.42 + *
150.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
150.44 + */
150.45 +package org.netbeans.modules.python.source;
150.46 +
150.47 +import java.awt.Toolkit;
150.48 +import java.util.ArrayList;
150.49 +import java.util.Collection;
150.50 +import java.util.Collections;
150.51 +import java.util.HashMap;
150.52 +import java.util.HashSet;
150.53 +import java.util.List;
150.54 +import java.util.Map;
150.55 +import java.util.Set;
150.56 +import javax.swing.text.BadLocationException;
150.57 +import org.netbeans.api.editor.EditorRegistry;
150.58 +import org.netbeans.editor.BaseDocument;
150.59 +import org.netbeans.editor.Utilities;
150.60 +import org.netbeans.modules.csl.api.EditList;
150.61 +import org.netbeans.modules.csl.api.OffsetRange;
150.62 +import org.netbeans.modules.csl.spi.GsfUtilities;
150.63 +import org.netbeans.modules.editor.indent.api.IndentUtils;
150.64 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
150.65 +import org.netbeans.modules.python.source.ImportEntry;
150.66 +import org.netbeans.modules.python.source.PythonAstUtils;
150.67 +import org.netbeans.modules.python.source.PythonIndex;
150.68 +import org.netbeans.modules.python.source.PythonParserResult;
150.69 +import org.netbeans.modules.python.source.elements.IndexedElement;
150.70 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
150.71 +import org.netbeans.modules.python.source.CodeStyle;
150.72 +import org.netbeans.modules.python.source.CodeStyle.ImportCleanupStyle;
150.73 +import org.netbeans.modules.python.source.scopes.SymbolTable;
150.74 +import org.netbeans.modules.python.source.scopes.SymInfo;
150.75 +import org.openide.util.Exceptions;
150.76 +import org.openide.util.NbBundle;
150.77 +import org.python.antlr.PythonTree;
150.78 +import org.python.antlr.ast.Import;
150.79 +import org.python.antlr.ast.ImportFrom;
150.80 +import org.python.antlr.ast.Str;
150.81 +import org.python.antlr.ast.alias;
150.82 +
150.83 +/**
150.84 + * Computations regarding module imports.
150.85 + *
150.86 + * @todo Handle commenting out portions of imports
150.87 + * @todo If I can make this fast, consider highlighting unused imports.
150.88 + * @todo On code completion I should import the corresponding package+class (make the
150.89 + * class part optional)
150.90 + * @todo Watch out for commented out imports getting wiped out in organize imports
150.91 + * because it's between imports. These need to be moved to the end!!!
150.92 + * @todo Offer to group imports
150.93 + * @todo Don't import functions
150.94 + *
150.95 + * @author Tor Norbye
150.96 + */
150.97 +public final class ImportManager {
150.98 +
150.99 + private PythonParserResult info;
150.100 + private List<Import> imports;
150.101 + private List<ImportFrom> importsFrom;
150.102 + private PythonTree root;
150.103 + private BaseDocument doc;
150.104 + private List<PythonTree> mainImports;
150.105 + private Set<PythonTree> topLevelImports;
150.106 +
150.107 + // Settings
150.108 + private boolean systemLibsFirst = true;
150.109 + private boolean splitImports = true;
150.110 + private boolean sortImports = true;
150.111 + private boolean separateFromImps = false;
150.112 + private ImportCleanupStyle cleanup = ImportCleanupStyle.COMMENT_OUT;
150.113 + private boolean removeDuplicates;
150.114 + private int rightMargin;
150.115 +
150.116 + public ImportManager(PythonParserResult info) {
150.117 + this(info, GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false), null);
150.118 + }
150.119 +
150.120 + public ImportManager(PythonParserResult info, BaseDocument doc) {
150.121 + this(info, doc, null);
150.122 + }
150.123 +
150.124 + public ImportManager(PythonParserResult info, BaseDocument doc, CodeStyle codeStyle) {
150.125 + this.info = info;
150.126 +
150.127 + root = PythonAstUtils.getRoot(info);
150.128 +
150.129 + SymbolTable symbolTable = PythonAstUtils.getParseResult(info).getSymbolTable();
150.130 + imports = symbolTable.getImports();
150.131 + importsFrom = symbolTable.getImportsFrom();
150.132 + topLevelImports = symbolTable.getTopLevelImports();
150.133 + mainImports = symbolTable.getMainImports();
150.134 +
150.135 + this.doc = doc;
150.136 +
150.137 + if (codeStyle == null) {
150.138 + codeStyle = CodeStyle.getDefault(doc);
150.139 + }
150.140 + systemLibsFirst = codeStyle.systemLibsFirst();
150.141 + splitImports = codeStyle.oneImportPerLine();
150.142 + cleanup = codeStyle.cleanupImports();
150.143 + sortImports = codeStyle.sortImports();
150.144 + separateFromImps = codeStyle.separateFromImps();
150.145 + if (separateFromImps) {
150.146 + sortImports = true;
150.147 + }
150.148 + removeDuplicates = codeStyle.removeDuplicates();
150.149 + rightMargin = codeStyle.getRightMargin();
150.150 +
150.151 + }
150.152 +
150.153 + public static boolean isFutureImport(ImportFrom fromStatement) {
150.154 + return "__future__".equals(fromStatement.getInternalModule()); // NOI18N
150.155 + }
150.156 +
150.157 + public void setCleanup(ImportCleanupStyle cleanup) {
150.158 + this.cleanup = cleanup;
150.159 + }
150.160 +
150.161 + public void cleanup(EditList edits, int startOffset, int endOffset, boolean force) {
150.162 + OffsetRange lexRange = getMainImportsRange();
150.163 + if (lexRange == OffsetRange.NONE ||
150.164 + !(new OffsetRange(startOffset, endOffset).overlaps(lexRange))) {
150.165 + // Not touching imports
150.166 + return;
150.167 + }
150.168 +
150.169 + if (cleanup != ImportCleanupStyle.LEAVE_ALONE) {
150.170 + List<String> ambiguousSymbols = new ArrayList<>();
150.171 + Map<String, String> defaultLists = new HashMap<>();
150.172 + Map<String, List<String>> alternatives = new HashMap<>();
150.173 + Set<ImportEntry> unused = new HashSet<>();
150.174 + Set<ImportEntry> duplicates = new HashSet<>();
150.175 +
150.176 + computeImports(ambiguousSymbols, defaultLists, alternatives, unused, duplicates);
150.177 + if (ambiguousSymbols.size() == 0 || force) {
150.178 + apply(edits, new String[0], unused, duplicates);
150.179 + return;
150.180 + }
150.181 + } else if (removeDuplicates) {
150.182 + Set<ImportEntry> duplicates = findDuplicates();
150.183 + apply(edits, new String[0], Collections.<ImportEntry>emptySet(), duplicates);
150.184 + return;
150.185 + }
150.186 +
150.187 + apply(edits, new String[0], Collections.<ImportEntry>emptySet(), Collections.<ImportEntry>emptySet());
150.188 + }
150.189 +
150.190 + public List<Import> getImports() {
150.191 + return imports;
150.192 + }
150.193 +
150.194 + public List<ImportFrom> getImportsFrom() {
150.195 + return importsFrom;
150.196 + }
150.197 +
150.198 + private Set<ImportEntry> findDuplicates() {
150.199 + Set<ImportEntry> duplicates = new HashSet<>();
150.200 + // TODO!
150.201 +
150.202 + return duplicates;
150.203 + }
150.204 +
150.205 + public boolean computeImports(
150.206 + List<String> ambiguousSymbols,
150.207 + Map<String, String> defaults,
150.208 + Map<String, List<String>> alternatives, Set<ImportEntry> unused, Set<ImportEntry> duplicates) {
150.209 +
150.210 + boolean ambiguous = false;
150.211 +
150.212 + SymbolTable symbolTable = new SymbolTable(PythonAstUtils.getRoot(info), info.getSnapshot().getSource().getFileObject());
150.213 + Map<String, SymInfo> unresolved = symbolTable.getUnresolvedNames(info);
150.214 +
150.215 + if (unresolved.size() > 0) {
150.216 + ambiguousSymbols.addAll(unresolved.keySet());
150.217 + Collections.sort(ambiguousSymbols);
150.218 +
150.219 + // Try to compute suggestions.
150.220 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
150.221 + Set<IndexedElement> modules = index.getModules("", QuerySupport.Kind.PREFIX);
150.222 + for (IndexedElement module : modules) {
150.223 + String name = module.getName();
150.224 + if (unresolved.containsKey(name)) {
150.225 + List<String> list = new ArrayList<>(4);
150.226 + list.add(name);
150.227 + defaults.put(name, name);
150.228 + alternatives.put(name, list);
150.229 + }
150.230 + }
150.231 +
150.232 + List<String> unresolvedList = new ArrayList<>(unresolved.keySet());
150.233 + Collections.sort(unresolvedList);
150.234 + for (String symbol : unresolvedList) {
150.235 + // TODO - determine if it's a call or variable
150.236 + // TODO - track import usages too!
150.237 + Collection<String> importsFor = index.getImportsFor(symbol, true);
150.238 + // TODO - insert symbols + " (whole module)"
150.239 + if (importsFor.size() > 0) {
150.240 + if (importsFor.size() > 1) {
150.241 + List<String> l = new ArrayList<>(importsFor);
150.242 + Collections.sort(l);
150.243 + importsFor = l;
150.244 + }
150.245 + List<String> list = alternatives.get(symbol);
150.246 + if (list == null) {
150.247 + list = new ArrayList<>();
150.248 + alternatives.put(symbol, list);
150.249 + }
150.250 + for (String s : importsFor) {
150.251 + if (!list.contains(s)) {
150.252 + list.add(s);
150.253 + }
150.254 + }
150.255 + if (list.size() > 1) {
150.256 + ambiguous = true;
150.257 + }
150.258 +
150.259 + // TODO - if it's a call, try to match functions instead of imported symbols
150.260 + } else {
150.261 + ambiguous = true;
150.262 + }
150.263 + }
150.264 +
150.265 + // TODO - look up -functions- and -data- defined across all modules
150.266 + // that might define these guys
150.267 +
150.268 + }
150.269 +
150.270 + List<String> unambiguousNames = new ArrayList<>();
150.271 + for (Map.Entry<String, List<String>> entry : alternatives.entrySet()) {
150.272 + List<String> list = entry.getValue();
150.273 + if (list == null || list.size() == 0) {
150.274 + ambiguous = true;
150.275 + } else if (list.size() == 1) {
150.276 + String key = entry.getKey();
150.277 + unambiguousNames.add(key);
150.278 + }
150.279 + }
150.280 +
150.281 + // If we've had to choose certain libraries (e.g. because they're the
150.282 + // only choice available in some cases) then make those libraries default
150.283 + // for all the ambiguous cases as well
150.284 + if (!unambiguousNames.isEmpty()) {
150.285 + for (String name : alternatives.keySet()) {
150.286 + List<String> list = alternatives.get(name);
150.287 + for (String choice : list) {
150.288 + if (unambiguousNames.contains(choice)) {
150.289 + defaults.put(name, choice);
150.290 + }
150.291 + }
150.292 + }
150.293 + }
150.294 +
150.295 + unused.addAll(symbolTable.getUnusedImports());
150.296 +
150.297 +// During development
150.298 +//ambiguous = true;
150.299 +
150.300 + return ambiguous;
150.301 + }
150.302 +
150.303 + public void apply(EditList edits, String[] selections, Set<ImportEntry> removeEntries, Set<ImportEntry> duplicates) {
150.304 + // Update the imports
150.305 + // Sort the imports
150.306 + // Delete the unused imports
150.307 + boolean apply = false;
150.308 + if (edits == null) {
150.309 + edits = new EditList(doc);
150.310 + apply = true;
150.311 + }
150.312 +
150.313 + Set<PythonTree> removedAlready = new HashSet<>();
150.314 +
150.315 + Set<PythonTree> mainImport;
150.316 + //if (sortImports) {
150.317 + mainImport = new HashSet<>(mainImports);
150.318 + //} else {
150.319 + // mainImport = Collections.<PythonTree>emptySet();
150.320 + //}
150.321 + Set<PythonTree> topLevel = topLevelImports;
150.322 +
150.323 +//
150.324 +// // Remove duplicates. Note - these are always removed, not just commented out.
150.325 +// if (duplicates.size() > 0 && cleanup != ImportCleanupStyle.LEAVE_ALONE) {
150.326 +// Set<PythonTree> candidates = new HashSet<PythonTree>();
150.327 +// // Map from import node to list of names that should be removed, if only some are duplicates
150.328 +// Map<PythonTree,List<String>> names = new HashMap<PythonTree,List<String>>();
150.329 +// // Find the corresponding import
150.330 +// //List<PythonTree> candidates = new ArrayList<PythonTree>();
150.331 +// boolean foundFirst = false;
150.332 +// for (Import imp : imports) {
150.333 +// if (imp.names != null) {
150.334 +// boolean all = true;
150.335 +// boolean some = false;
150.336 +// for (alias at : imp.getInternalNames()) {
150.337 +// if (duplicates.contains(at.getInternalName())) {
150.338 +// if (!foundFirst) {
150.339 +// foundFirst = true;
150.340 +// } else {
150.341 +// some = true;
150.342 +// List<String> nameList = names.get(imp);
150.343 +// if (nameList == null) {
150.344 +// nameList = new ArrayList<String>();
150.345 +// names.put(imp, nameList);
150.346 +// }
150.347 +// nameList.add(at.getInternalName());
150.348 +// }
150.349 +// break;
150.350 +// } else {
150.351 +// all = false;
150.352 +// }
150.353 +// }
150.354 +// if (some) {
150.355 +// candidates.add(imp);
150.356 +// if (all) {
150.357 +// // No need to limit deletion to just one
150.358 +// names.put(imp, null);
150.359 +// }
150.360 +// }
150.361 +// }
150.362 +// }
150.363 +//
150.364 +// for (ImportFrom from : importsFrom) {
150.365 +// if (from.names != null) {
150.366 +// boolean all = true;
150.367 +// boolean some = false;
150.368 +// for (alias at : from.names) {
150.369 +// assert at.getInternalName() != null;
150.370 +// String value;
150.371 +// if (at.getInternalAsname() != null) {
150.372 +// value = from.module + ":" + at.getInternalName() + ":" + at.getInternalAsname();
150.373 +// } else {
150.374 +// value = from.module + ":" + at.getInternalName();
150.375 +// }
150.376 +// if (duplicates.contains(value)) {
150.377 +// if (!foundFirst) {
150.378 +// foundFirst = true;
150.379 +// } else {
150.380 +// some = true;
150.381 +// List<String> nameList = names.get(from);
150.382 +// if (nameList == null) {
150.383 +// nameList = new ArrayList<String>();
150.384 +// names.put(from, nameList);
150.385 +// }
150.386 +// nameList.add(at.getInternalName());
150.387 +// }
150.388 +// } else {
150.389 +// all = false;
150.390 +// }
150.391 +// }
150.392 +// if (some) {
150.393 +// candidates.add(from);
150.394 +// if (all) {
150.395 +// // No need to limit deletion to just one
150.396 +// names.put(from, null);
150.397 +// }
150.398 +// }
150.399 +// }
150.400 +// }
150.401 +//
150.402 +// Set<PythonTree> filtered = new HashSet<PythonTree>();
150.403 +// for (PythonTree node : candidates) {
150.404 +// if (!mainImport.contains(node) && topLevel.contains(node)) {
150.405 +// filtered.add(node);
150.406 +// }
150.407 +// }
150.408 +//
150.409 +// removedAlready.addAll(filtered);
150.410 +//
150.411 +// // Note - we always REMOVE duplicate imports rather than just commenting
150.412 +// // them out. We may sometimes be wrong about unused imports, so we let
150.413 +// // users leave them commented out when we clean up to make it easier
150.414 +// // to backtrack if we were wrong. However, duplicate imports is something
150.415 +// // we can accurately detect and leaving them commented out isn't something
150.416 +// // users will probably want.
150.417 +// removeImports(edits, filtered, /*commentOut*/false, names);
150.418 +// }
150.419 +
150.420 + if (cleanup == ImportCleanupStyle.LEAVE_ALONE) {
150.421 + removeEntries.clear();
150.422 + } else {
150.423 + Set<ImportEntry> newSet = new HashSet<>();
150.424 + Set<PythonTree> filtered = new HashSet<>();
150.425 + for (ImportEntry entry : removeEntries) {
150.426 + PythonTree node = entry.node;
150.427 + if (!mainImport.contains(node) && topLevel.contains(node)) {
150.428 + filtered.add(node);
150.429 + } else {
150.430 + if (removeDuplicates) {
150.431 + entry.node = null;
150.432 + }
150.433 + if (sortImports) {
150.434 + entry.ordinal = 0;
150.435 + }
150.436 + if (!separateFromImps) {
150.437 + entry.sortedFrom = false;
150.438 + }
150.439 + }
150.440 +
150.441 + newSet.add(entry);
150.442 + }
150.443 + removeEntries = newSet;
150.444 +// int ordinal = 0;
150.445 +// if (unused.size() > 0 && cleanup != ImportCleanupStyle.LEAVE_ALONE) {
150.446 +// Set<PythonTree> candidates = new HashSet<PythonTree>();
150.447 +// Map<PythonTree,List<String>> names = new HashMap<PythonTree,List<String>>();
150.448 +// // Find the corresponding import
150.449 +// //List<PythonTree> candidates = new ArrayList<PythonTree>();
150.450 +// for (Import imp : imports) {
150.451 +// if (imp.names != null) {
150.452 +// boolean all = true;
150.453 +// boolean some = false;
150.454 +// for (alias at : imp.getInternalNames()) {
150.455 +// if (unused.contains(at.getInternalName())) {
150.456 +// some = true;
150.457 +// List<String> nameList = names.get(imp);
150.458 +// if (nameList == null) {
150.459 +// nameList = new ArrayList<String>();
150.460 +// names.put(imp, nameList);
150.461 +// }
150.462 +// nameList.add(at.getInternalName());
150.463 +//
150.464 +// boolean isSystem = false; // Don't care what it is for deletion
150.465 +// removeEntries.add(new ImportEntry(at.getInternalName(), at.getInternalAsname(), isSystem,
150.466 +// removeDuplicates ? null : imp,
150.467 +// sortImports ? 0 : ordinal++));
150.468 +// break;
150.469 +// } else {
150.470 +// all = false;
150.471 +// }
150.472 +// }
150.473 +//
150.474 +// if (some) {
150.475 +// candidates.add(imp);
150.476 +// if (all) {
150.477 +// // No need to limit deletion to just one
150.478 +// names.put(imp, null);
150.479 +// }
150.480 +// }
150.481 +// }
150.482 +// }
150.483 +//
150.484 +// for (ImportFrom from : importsFrom) {
150.485 +// if (from.names != null) {
150.486 +// boolean all = true;
150.487 +// boolean some = false;
150.488 +// for (alias at : from.names) {
150.489 +// boolean isSystem = false; // Don't care what it is for deletion
150.490 +//
150.491 +// assert at.getInternalName() != null;
150.492 +// String value;
150.493 +// if (at.getInternalAsname() != null) {
150.494 +// value = from.module + ":" + at.getInternalName() + ":" + at.getInternalAsname();
150.495 +// } else {
150.496 +// value = from.module + ":" + at.getInternalName();
150.497 +// }
150.498 +// if (unused.contains(value)) {
150.499 +// removeEntries.add(new ImportEntry(from.module, at.getInternalName(), at.getInternalAsname(), isSystem,
150.500 +// removeDuplicates ? null : from,
150.501 +// sortImports ? 0 : ordinal++));
150.502 +// some = true;
150.503 +// List<String> nameList = names.get(from);
150.504 +// if (nameList == null) {
150.505 +// nameList = new ArrayList<String>();
150.506 +// names.put(from, nameList);
150.507 +// }
150.508 +// nameList.add(at.getInternalName());
150.509 +// } else {
150.510 +// all = false;
150.511 +// }
150.512 +// }
150.513 +// if (some) {
150.514 +// candidates.add(from);
150.515 +// if (all) {
150.516 +// // No need to limit deletion to just one
150.517 +// names.put(from, null);
150.518 +// }
150.519 +// }
150.520 +// }
150.521 +// }
150.522 +//
150.523 +// // Don't try to delete nodes we've already deleted or commented out
150.524 +// // because they are unused
150.525 +//
150.526 +// candidates.removeAll(removedAlready);
150.527 +//
150.528 +// Set<PythonTree> filtered = new HashSet<PythonTree>();
150.529 +// for (PythonTree node : candidates) {
150.530 +// if (!mainImport.contains(node) && topLevel.contains(node)) {
150.531 +// filtered.add(node);
150.532 +// }
150.533 +// }
150.534 +
150.535 + removeImports(edits, filtered, cleanup == ImportCleanupStyle.COMMENT_OUT, null);
150.536 + }
150.537 +
150.538 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
150.539 +
150.540 + Collection<ImportEntry> newEntries = new ArrayList<>();
150.541 + if (selections != null) {
150.542 + for (String module : selections) {
150.543 + if (module.startsWith("<html>")) { // NOI18N
150.544 + // Skip cannot resolve stuff
150.545 + continue;
150.546 + }
150.547 + int colon = module.indexOf(':');
150.548 + if (colon != -1) {
150.549 + int end = module.indexOf('(', colon + 1);
150.550 + if (end == -1) {
150.551 + end = module.indexOf(';', colon + 1);
150.552 + if (end == -1) {
150.553 + end = module.length();
150.554 + }
150.555 + }
150.556 + String symbol = module.substring(colon + 1, end).trim();
150.557 + module = module.substring(0, colon).trim();
150.558 + boolean isSystem = systemLibsFirst && index.isSystemModule(module);
150.559 + ImportEntry importEntry = new ImportEntry(module, symbol, null, isSystem, null, 0);
150.560 + if (!separateFromImps) {
150.561 + importEntry.sortedFrom = false;
150.562 + }
150.563 + newEntries.add(importEntry);
150.564 + } else {
150.565 + boolean isSystem = systemLibsFirst && index.isSystemModule(module);
150.566 + ImportEntry importEntry = new ImportEntry(module, null, null, isSystem, null, 0);
150.567 + if (!separateFromImps) {
150.568 + importEntry.sortedFrom = false;
150.569 + }
150.570 + newEntries.add(importEntry);
150.571 + }
150.572 + }
150.573 + }
150.574 +
150.575 + rewriteMainImports(edits, newEntries, removeEntries);
150.576 +
150.577 + if (apply) {
150.578 + edits.apply();
150.579 + }
150.580 + }
150.581 +
150.582 + public boolean isTopLevel(PythonTree node) {
150.583 + return topLevelImports.contains(node);
150.584 + }
150.585 +
150.586 + /**
150.587 + * Remove or comment out the given import statements (Import or ImportFrom).
150.588 + * @param edits The edit list to add edits for comment or removal
150.589 + * @param candidates The set of Import or ImportFrom nodes
150.590 + * @param commentOut If true, comment out the import, or else, delete it
150.591 + * @param onlyNames A map from nodes to lists where if the list is null,
150.592 + * remove or comment out the entire import, otherwise comment
150.593 + * or delete only the specified name portions.
150.594 + */
150.595 + public void removeImports(EditList edits, Set<PythonTree> candidates, boolean commentOut, Map<PythonTree, List<String>> onlyNames) {
150.596 + for (PythonTree node : candidates) {
150.597 + // Don't touch imports that aren't top level!!!
150.598 + // These can be inside If blocks and such so we don't
150.599 + // have enough knowledge to mess with them
150.600 + if (!isTopLevel(node)) {
150.601 + continue;
150.602 + }
150.603 +
150.604 + OffsetRange astRange = PythonAstUtils.getRange(node);
150.605 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
150.606 + if (lexRange == OffsetRange.NONE) {
150.607 + continue;
150.608 + }
150.609 +
150.610 + List<String> names = onlyNames.get(node);
150.611 + if (names != null) {
150.612 +
150.613 + // TODO Handle commenting out portions of a line! An idea which
150.614 + // might work is to replace the whole import with a new import
150.615 + // that moves the commented out portions to the end!!
150.616 +
150.617 + // Only delete/comment out a portion of the line
150.618 +// if (commentOut) {
150.619 +// TODO
150.620 +// } else {
150.621 + // Determine offsets within the line
150.622 + List<OffsetRange> ranges = new ArrayList<>();
150.623 + try {
150.624 + int start = lexRange.getStart();
150.625 + int end = lexRange.getEnd();
150.626 + if (end > doc.getLength()) {
150.627 + end = doc.getLength();
150.628 + if (start > doc.getLength()) {
150.629 + start = doc.getLength();
150.630 + }
150.631 + }
150.632 + String line = doc.getText(start, end - start);
150.633 + for (String name : names) {
150.634 + int index = line.indexOf(name);
150.635 + if (index != -1) {
150.636 + int nameEnd = index + name.length();
150.637 + boolean removedComma = false;
150.638 + for (int i = nameEnd; i < line.length(); i++) {
150.639 + char c = line.charAt(i);
150.640 + if (c == ',') {
150.641 + removedComma = true;
150.642 + nameEnd = i + 1;
150.643 + if (nameEnd < line.length() && line.charAt(nameEnd) == ' ') {
150.644 + // Include space after comma in deletion
150.645 + nameEnd++;
150.646 + }
150.647 + break;
150.648 + } else if (c == ' ' || c == '\t') {
150.649 + continue;
150.650 + } else {
150.651 + break;
150.652 + }
150.653 + }
150.654 + if (!removedComma) {
150.655 + // If I removed the last name on the line there is no
150.656 + // comma at the end, so I should try removing one -before-
150.657 + // the name instead
150.658 + for (int i = index - 1; i >= 0; i--) {
150.659 + char c = line.charAt(i);
150.660 + if (c == ',') {
150.661 + index = i;
150.662 + break;
150.663 + } else if (c == ' ' || c == '\t') {
150.664 + continue;
150.665 + } else {
150.666 + break;
150.667 + }
150.668 + }
150.669 + }
150.670 + OffsetRange remove = new OffsetRange(start + index, start + nameEnd);
150.671 +
150.672 + // Prevent overlaps
150.673 + for (OffsetRange range : ranges) {
150.674 + if (range.overlaps(remove)) {
150.675 + if (range.getStart() < remove.getStart()) {
150.676 + remove = new OffsetRange(range.getEnd(), Math.max(remove.getEnd(), range.getEnd()));
150.677 + } else {
150.678 + remove = new OffsetRange(Math.min(remove.getStart(), range.getStart()), range.getStart());
150.679 + }
150.680 + }
150.681 + }
150.682 +
150.683 + ranges.add(remove);
150.684 + }
150.685 + }
150.686 + int prio = 0;
150.687 + for (OffsetRange range : ranges) {
150.688 + edits.replace(range.getStart(), range.getLength(), null, false, prio++);
150.689 + }
150.690 + } catch (BadLocationException ex) {
150.691 + Exceptions.printStackTrace(ex);
150.692 + }
150.693 +// }
150.694 + } else {
150.695 + int start = lexRange.getStart();
150.696 + if (commentOut) {
150.697 + edits.replace(start, 0, "#", false, 0); // NOI18N
150.698 + } else {
150.699 + int length = lexRange.getLength();
150.700 + // See if this leaves an empty line and if so remove it
150.701 + int endPos = lexRange.getEnd();
150.702 + if (endPos < doc.getLength()) {
150.703 + try {
150.704 + char c = doc.getText(endPos, 1).charAt(0);
150.705 + if (c == '\n') {
150.706 + length++;
150.707 + }
150.708 + } catch (BadLocationException ex) {
150.709 + Exceptions.printStackTrace(ex);
150.710 + }
150.711 + }
150.712 + edits.replace(start, length, null, false, 0);
150.713 + }
150.714 + }
150.715 + }
150.716 + }
150.717 +
150.718 + private OffsetRange getMainImportsRange() {
150.719 + // Compute editor range required
150.720 + int begin = Integer.MAX_VALUE;
150.721 + int end = Integer.MIN_VALUE;
150.722 + OffsetRange lexRange;
150.723 + if (mainImports.size() == 0) {
150.724 + if (mainImports.size() == 1) {
150.725 + OffsetRange astRange = PythonAstUtils.getRange(mainImports.get(0));
150.726 + lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
150.727 + } else {
150.728 + assert mainImports.size() == 0;
150.729 + begin = getImportsLexOffset(null);
150.730 + end = begin;
150.731 + lexRange = new OffsetRange(begin, end);
150.732 + }
150.733 + } else {
150.734 + for (PythonTree node : mainImports) {
150.735 + OffsetRange range = PythonAstUtils.getRange(node);
150.736 + if (range.getStart() < begin) {
150.737 + begin = range.getStart();
150.738 + }
150.739 + if (range.getEnd() > end) {
150.740 + end = range.getEnd();
150.741 + }
150.742 + }
150.743 + OffsetRange astReplace = new OffsetRange(begin, end);
150.744 + lexRange = PythonLexerUtils.getLexerOffsets(info, astReplace);
150.745 + }
150.746 +
150.747 + return lexRange;
150.748 + }
150.749 +
150.750 + public void rewriteMainImports(EditList edits, Collection<ImportEntry> newEntries, Set<ImportEntry> remove) {
150.751 + // Items to be deleted should be deleted after this
150.752 +
150.753 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
150.754 +
150.755 + // TODO:
150.756 + // Look for comments to preserve
150.757 + // Replace the entire editor block
150.758 + Set<ImportEntry> entries = new HashSet<>();
150.759 + int ordinal = 0;
150.760 + for (PythonTree node : mainImports) {
150.761 + if (node instanceof Import) {
150.762 + Import imp = (Import)node;
150.763 + // TODO - look up for at.getInternalName()!
150.764 + List<alias> names = imp.getInternalNames();
150.765 + if (names != null) {
150.766 + for (alias at : names) {
150.767 + ImportEntry importEntry = new ImportEntry(at.getInternalName(), at.getInternalAsname(), systemLibsFirst && index.isSystemModule(at.getInternalName()),
150.768 + removeDuplicates ? null : imp, sortImports ? 0 : ordinal++);
150.769 + if (!separateFromImps) {
150.770 + importEntry.sortedFrom = false;
150.771 + }
150.772 + entries.add(importEntry);
150.773 + }
150.774 + }
150.775 + } else {
150.776 + assert node instanceof ImportFrom;
150.777 + ImportFrom imp = (ImportFrom)node;
150.778 + List<alias> names = imp.getInternalNames();
150.779 + if (names != null && names.size() > 0) {
150.780 + // TODO - look up for imp.getInternalModule()!
150.781 + boolean isSystemLibrary = systemLibsFirst && index.isSystemModule(imp.getInternalModule());
150.782 + for (alias at : names) {
150.783 + ImportEntry importEntry = new ImportEntry(imp.getInternalModule(), at.getInternalName(), at.getInternalAsname(), isSystemLibrary,
150.784 + removeDuplicates ? null : imp, sortImports ? 0 : ordinal++);
150.785 + if (!separateFromImps) {
150.786 + importEntry.sortedFrom = false;
150.787 + }
150.788 + entries.add(importEntry);
150.789 + }
150.790 + }
150.791 + }
150.792 + }
150.793 +
150.794 + // Add in entries discovered as needed by the import manager
150.795 + if (newEntries.size() > 0) {
150.796 + entries.addAll(newEntries);
150.797 + }
150.798 +
150.799 + // Remove any items that needs to be removed
150.800 + if (remove.size() > 0) {
150.801 + entries.removeAll(remove);
150.802 + }
150.803 +
150.804 + // Sort imports -- first by system/nonsystem, then alphabetically
150.805 + List<ImportEntry> sortedEntries = new ArrayList<>(entries);
150.806 + Collections.sort(sortedEntries);
150.807 +
150.808 + // Write out existing imports
150.809 + StringBuilder sb = new StringBuilder();
150.810 + int size = sortedEntries.size();
150.811 + if (size > 0) {
150.812 + boolean prevSystem = sortedEntries.get(0).isSystem;
150.813 +
150.814 + for (int i = 0; i < size; i++) {
150.815 + ImportEntry entry = sortedEntries.get(i);
150.816 + if (systemLibsFirst && entry.isSystem != prevSystem) {
150.817 + prevSystem = entry.isSystem;
150.818 + sb.append("\n"); // NOI18N Separate system and regular libs
150.819 + }
150.820 +
150.821 + if (entry.isFromImport) {
150.822 + int start = sb.length();
150.823 + sb.append("from "); // NOI18N
150.824 + sb.append(entry.module);
150.825 + sb.append(" import "); // NOI18N
150.826 + sb.append(entry.symbol);
150.827 + if (entry.asName != null) {
150.828 + sb.append(" as "); // NOI18N
150.829 + sb.append(entry.asName);
150.830 + }
150.831 +
150.832 + if (!splitImports) {
150.833 + // Look ahead and combine subsequent entries
150.834 + int lookahead = i + 1;
150.835 + for (; lookahead < size; lookahead++) {
150.836 + ImportEntry next = sortedEntries.get(lookahead);
150.837 + if (next.isFromImport != entry.isFromImport ||
150.838 + !next.module.equals(entry.module)) {
150.839 + break;
150.840 + }
150.841 + sb.append(", "); // NOI18N
150.842 +
150.843 + if (sb.length() - start > rightMargin && (rightMargin > 30)) {
150.844 + sb.append("\\\n");
150.845 + start = sb.length();
150.846 + sb.append(IndentUtils.createIndentString(doc, IndentUtils.indentLevelSize(doc)));
150.847 + }
150.848 +
150.849 + sb.append(next.symbol);
150.850 + if (next.asName != null) {
150.851 + sb.append(" as ");
150.852 + sb.append(next.asName);
150.853 + }
150.854 + }
150.855 + i = lookahead - 1;
150.856 + }
150.857 + sb.append("\n"); // NOI18N
150.858 + } else {
150.859 + // Plain import
150.860 + // We never combine imports
150.861 + sb.append("import "); // NOI18N
150.862 + sb.append(entry.module);
150.863 + if (entry.asName != null) {
150.864 + sb.append(" as "); // NOI18N
150.865 + sb.append(entry.asName);
150.866 + }
150.867 + sb.append("\n"); // NOI18N
150.868 + }
150.869 + }
150.870 + }
150.871 +
150.872 + // Write commented out deleted entries as well
150.873 + if (remove.size() > 0 && cleanup == ImportCleanupStyle.COMMENT_OUT) {
150.874 + size = remove.size();
150.875 + List<ImportEntry> sortedRemove = new ArrayList<>();
150.876 + sortedRemove.addAll(remove);
150.877 + Collections.sort(sortedRemove);
150.878 + for (ImportEntry entry : sortedRemove) {
150.879 + if (entry.isFromImport) {
150.880 + sb.append("#from "); // NOI18N
150.881 + sb.append(entry.module);
150.882 + sb.append(" import "); // NOI18N
150.883 + sb.append(entry.symbol);
150.884 + if (entry.asName != null) {
150.885 + sb.append(" as "); // NOI18N
150.886 + sb.append(entry.asName);
150.887 + }
150.888 + sb.append("\n"); // NOI18N
150.889 + } else {
150.890 + sb.append("#import "); // NOI18N
150.891 + sb.append(entry.module);
150.892 + if (entry.asName != null) {
150.893 + sb.append(" as "); // NOI18N
150.894 + sb.append(entry.asName);
150.895 + }
150.896 + sb.append("\n"); // NOI18N
150.897 + }
150.898 + }
150.899 + }
150.900 +
150.901 + // Compute editor range required
150.902 + OffsetRange lexRange = getMainImportsRange();
150.903 +
150.904 + // Replace final newline if it's there so we don't grow whitespace around the imports
150.905 + int lastNewlineDelta = 0;
150.906 + try {
150.907 + if (lexRange.getEnd() < doc.getLength() && doc.getText(lexRange.getEnd(), 1).charAt(0) == '\n') {
150.908 + lastNewlineDelta++;
150.909 + }
150.910 + } catch (BadLocationException ex) {
150.911 + Exceptions.printStackTrace(ex);
150.912 + }
150.913 +
150.914 + edits.replace(lexRange.getStart(), lexRange.getLength() + lastNewlineDelta, sb.toString(), false, 0);
150.915 + }
150.916 +
150.917 + /** Compute the location where the main import block should be located */
150.918 + public int getImportsLexOffset(String module) {
150.919 + int begin = 0;
150.920 +
150.921 + // First try computing a position in the standard imports
150.922 + if (module != null) {
150.923 + PythonTree last = null;
150.924 + for (PythonTree node : mainImports) {
150.925 + boolean stop = false;
150.926 + if (node instanceof Import) {
150.927 + Import imp = (Import)node;
150.928 + List<alias> names = imp.getInternalNames();
150.929 + if (names != null && names.size() > 0 &&
150.930 + names.get(0).getInternalName().compareTo(module) >= 0) {
150.931 + stop = true;
150.932 + }
150.933 + } else {
150.934 + assert node instanceof ImportFrom;
150.935 + ImportFrom imp = (ImportFrom)node;
150.936 + if (imp.getInternalModule().compareTo(module) >= 0) {
150.937 + stop = true;
150.938 + }
150.939 + }
150.940 +
150.941 + if (stop) {
150.942 + return PythonLexerUtils.getLexerOffsets(info,
150.943 + PythonAstUtils.getRange(node)).getStart();
150.944 + }
150.945 +
150.946 + last = node;
150.947 + }
150.948 +
150.949 + if (last != null) {
150.950 + return PythonLexerUtils.getLexerOffsets(info,
150.951 + PythonAstUtils.getRange(last)).getStart();
150.952 + }
150.953 + }
150.954 +
150.955 + Str documentationNode = PythonAstUtils.getDocumentationNode(root);
150.956 + if (documentationNode != null) {
150.957 + int astEnd = documentationNode.getCharStopIndex();
150.958 + begin = PythonLexerUtils.getLexerOffset(info, astEnd);
150.959 + if (begin == -1) {
150.960 + begin = 0;
150.961 + } else {
150.962 + begin = Math.min(doc.getLength(), begin);
150.963 + try {
150.964 + begin = Utilities.getRowEnd(doc, begin) + 1;
150.965 + begin = Math.min(begin, doc.getLength());
150.966 + } catch (BadLocationException ex) {
150.967 + Exceptions.printStackTrace(ex);
150.968 + begin = 0;
150.969 + }
150.970 + }
150.971 + }
150.972 +
150.973 + // TODO - I should even do a lexical lookup for this in case we're in an embedded scenario!
150.974 + return begin;
150.975 + }
150.976 +
150.977 + /** Determine if the given module is imported (for the given symbol) */
150.978 + public boolean isImported(String module, String ident) {
150.979 + for (Import imp : imports) {
150.980 + List<alias> names = imp.getInternalNames();
150.981 + if (names != null) {
150.982 + for (alias at : names) {
150.983 + if (module.equals(at.getInternalName()) && (ident == null || (ident.equals(module) || ident.equals(at.getInternalAsname())))) {
150.984 + return true;
150.985 + }
150.986 + }
150.987 + }
150.988 + }
150.989 +
150.990 + for (ImportFrom from : importsFrom) {
150.991 + if (module.equals(from.getInternalModule())) {
150.992 + // Make sure -this- symbol hasn't been imported!
150.993 + if (ident != null) {
150.994 + List<alias> names = from.getInternalNames();
150.995 + if (names != null) {
150.996 + for (alias at : names) {
150.997 + if (at.getInternalAsname() == null) {
150.998 + // If you have "from module1 import Class1 as Class2", then
150.999 + // "Class1" is not already imported, and "Class2" is.
150.1000 + if (ident.equals(at.getInternalName())) {
150.1001 + return true;
150.1002 + }
150.1003 + } else if (ident.equals(at.getInternalAsname())) {
150.1004 + return true;
150.1005 + }
150.1006 + }
150.1007 + }
150.1008 + }
150.1009 + }
150.1010 + }
150.1011 +
150.1012 + return false;
150.1013 + }
150.1014 +
150.1015 + public void ensureImported(String name, String ident, boolean packageImport, boolean useFqn, boolean warnIfExists) {
150.1016 + // TODO - look up the splitImports setting and add to existing import if possible...
150.1017 +
150.1018 + if (PythonIndex.isBuiltinModule(name)) {
150.1019 + return;
150.1020 + }
150.1021 +
150.1022 + // Test whether already imported
150.1023 + if (isImported(name, ident)) {
150.1024 + if (warnIfExists) {
150.1025 + Utilities.setStatusText(EditorRegistry.lastFocusedComponent(),
150.1026 + NbBundle.getMessage(
150.1027 + ImportManager.class,
150.1028 + packageImport ? "MSG_PackageAlreadyImported" : "MSG_ClassAlreadyImported",
150.1029 + name, ident));
150.1030 + Toolkit.getDefaultToolkit().beep();
150.1031 + }
150.1032 + return;
150.1033 + }
150.1034 +
150.1035 + int begin = getImportsLexOffset(ident);
150.1036 + try {
150.1037 + // TODO - warp to the new import and let you edit the "AS" part??
150.1038 +
150.1039 + if (useFqn || ident == null) {
150.1040 + doc.insertString(begin, "import " + name + "\n", null); // NOI18N
150.1041 + } else if (packageImport) {
150.1042 + //doc.insertString(begin, "import " + name + "\n", null); // NOI18N
150.1043 + doc.insertString(begin, "from " + name + " import *\n", null); // NOI18N
150.1044 + } else {
150.1045 + doc.insertString(begin, "from " + name + " import " + ident + "\n", null); // NOI18N
150.1046 + }
150.1047 + } catch (BadLocationException ble) {
150.1048 + Exceptions.printStackTrace(ble);
150.1049 + }
150.1050 + }
150.1051 +}
151.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151.2 +++ b/python.source/src/org/netbeans/modules/python/source/NameStyle.java Mon Sep 21 13:01:16 2015 +0200
151.3 @@ -0,0 +1,198 @@
151.4 +/*
151.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
151.6 + *
151.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
151.8 + *
151.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
151.10 + * Other names may be trademarks of their respective owners.
151.11 + *
151.12 + * The contents of this file are subject to the terms of either the GNU
151.13 + * General Public License Version 2 only ("GPL") or the Common
151.14 + * Development and Distribution License("CDDL") (collectively, the
151.15 + * "License"). You may not use this file except in compliance with the
151.16 + * License. You can obtain a copy of the License at
151.17 + * http://www.netbeans.org/cddl-gplv2.html
151.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
151.19 + * specific language governing permissions and limitations under the
151.20 + * License. When distributing the software, include this License Header
151.21 + * Notice in each file and include the License file at
151.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
151.23 + * particular file as subject to the "Classpath" exception as provided
151.24 + * by Oracle in the GPL Version 2 section of the License file that
151.25 + * accompanied this code. If applicable, add the following below the
151.26 + * License Header, with the fields enclosed by brackets [] replaced by
151.27 + * your own identifying information:
151.28 + * "Portions Copyrighted [year] [name of copyright owner]"
151.29 + *
151.30 + * If you wish your version of this file to be governed by only the CDDL
151.31 + * or only the GPL Version 2, indicate your decision by adding
151.32 + * "[Contributor] elects to include this software in this distribution
151.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
151.34 + * single choice of license, a recipient has the option to distribute
151.35 + * your version of this file under either the CDDL, the GPL Version 2 or
151.36 + * to extend the choice of license to its licensees as provided above.
151.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
151.38 + * Version 2 license, then the option applies only if the new code is
151.39 + * made subject to such option by the copyright holder.
151.40 + *
151.41 + * Contributor(s):
151.42 + *
151.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
151.44 + */
151.45 +
151.46 +package org.netbeans.modules.python.source;
151.47 +
151.48 +import org.openide.util.NbBundle;
151.49 +
151.50 +/**
151.51 + *
151.52 + * @author Tor Norbye
151.53 + */
151.54 +public enum NameStyle {
151.55 + NO_PREFERENCE(NbBundle.getMessage(NameStyle.class, "NoPreference")),
151.56 + LOWERCASE("lowercase"),
151.57 + LOWERCASE_WITH_UNDERSCORES("lowercase_with_underscores"),
151.58 + UPPERCASE("UPPERCASE"),
151.59 + UPPERCASE_WITH_UNDERSCORES("UPPERCASE_WITH_UNDERSCORES"),
151.60 + CAPITALIZED_WORDS("CapitalizedWords"),
151.61 + MIXED_CASE("mixedCase"),
151.62 + CAPITALIZED_WITH_UNDERSCORES("Capitalized_With_Underscores");
151.63 +
151.64 + private String displayName;
151.65 +
151.66 + NameStyle(String displayName) {
151.67 + this.displayName = displayName;
151.68 + }
151.69 +
151.70 + public String getDisplayName() {
151.71 + return displayName;
151.72 + }
151.73 +
151.74 + public boolean complies(String name) {
151.75 + if (name.length() == 0) {
151.76 + return true;
151.77 + }
151.78 +
151.79 + // Always allow one or two "_" at the beginning and end of the name since
151.80 + // these are used to indicate private, builtin, etc.
151.81 + int start = 0;
151.82 + int end = name.length();
151.83 + if (name.startsWith("__")) { // NOI18N
151.84 + start = 2;
151.85 + } else if (name.startsWith("_")) { // NOI18N
151.86 + start = 1;
151.87 + }
151.88 +
151.89 + if (name.endsWith("__")) { // NOI18N
151.90 + end -= 2;
151.91 + } else if (name.endsWith("_")) { // NOI18N
151.92 + end -= 1;
151.93 + }
151.94 +
151.95 + if (start >= end) {
151.96 + return false;
151.97 + }
151.98 +
151.99 + switch (this) {
151.100 + case NO_PREFERENCE:
151.101 + return true;
151.102 +
151.103 + case LOWERCASE_WITH_UNDERSCORES:
151.104 + case LOWERCASE:
151.105 + for (int i = start; i < end; i++) {
151.106 + char c = name.charAt(i);
151.107 + if (c == '_') {
151.108 + if (this != LOWERCASE_WITH_UNDERSCORES) {
151.109 + return false;
151.110 + }
151.111 + } else if (Character.isDigit(c)) {
151.112 + } else if (!Character.isLowerCase(c)) {
151.113 + return false;
151.114 + }
151.115 + }
151.116 +
151.117 + return true;
151.118 +
151.119 +
151.120 + case UPPERCASE:
151.121 + case UPPERCASE_WITH_UNDERSCORES:
151.122 + for (int i = start; i < end; i++) {
151.123 + char c = name.charAt(i);
151.124 + if (c == '_') {
151.125 + if (this != UPPERCASE_WITH_UNDERSCORES) {
151.126 + return false;
151.127 + }
151.128 + } else if (Character.isDigit(c)) {
151.129 + } else if (!Character.isUpperCase(c)) {
151.130 + return false;
151.131 + }
151.132 + }
151.133 +
151.134 + return true;
151.135 +
151.136 + case MIXED_CASE:
151.137 + // TODO - require that characters after _ are capitalized?
151.138 + case CAPITALIZED_WORDS:
151.139 + case CAPITALIZED_WITH_UNDERSCORES:
151.140 + if (this == MIXED_CASE) {
151.141 + // Must begin with lowercase
151.142 + if (!Character.isLowerCase(name.charAt(start))) {
151.143 + return false;
151.144 + }
151.145 + } else if (this == CAPITALIZED_WORDS || this == CAPITALIZED_WITH_UNDERSCORES) {
151.146 + // Must begin with uppercase
151.147 + if (!Character.isUpperCase(name.charAt(start))) {
151.148 + return false;
151.149 + }
151.150 + }
151.151 + for (int i = start+1; i < end; i++) {
151.152 + char c = name.charAt(i);
151.153 + if (c == '_') {
151.154 + if (this != CAPITALIZED_WITH_UNDERSCORES) {
151.155 + return false;
151.156 + }
151.157 + } else if (Character.isDigit(c)) {
151.158 + } else if (!Character.isUpperCase(c) && !Character.isLowerCase(c)) {
151.159 + return false;
151.160 + }
151.161 +
151.162 + // What about digits?
151.163 + }
151.164 +
151.165 + return true;
151.166 + default:
151.167 + assert false : this;
151.168 + }
151.169 +
151.170 + return true;
151.171 + }
151.172 +
151.173 + public static boolean isProtectedName(String name) {
151.174 + // Protected variable starts with a single _
151.175 + // this is a convention only
151.176 + if (!name.startsWith("__")) {
151.177 + // NOI18N
151.178 + if (name.startsWith("_")) {
151.179 + // NOI18N
151.180 + return true;
151.181 + }
151.182 + }
151.183 + return false;
151.184 + }
151.185 +
151.186 + public static boolean isPrivateName(String name) {
151.187 + // Private variables: start with __ but doesn't end with __
151.188 + // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
151.189 + if (name != null && name.startsWith("__") && !name.endsWith("__")) {
151.190 + // NOI18N
151.191 + return true;
151.192 + } else if (name != null && name.startsWith("_") && !name.endsWith("_")) {
151.193 + // NOI18N
151.194 + // From PEP8: Single_leading_underscore: weak "internal use" indicator
151.195 + // (e.g. "from M import *" does not import objects whose name
151.196 + // starts with an underscore).
151.197 + return true;
151.198 + }
151.199 + return false;
151.200 + }
151.201 +}
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
152.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonAstUtils.java Mon Sep 21 13:01:16 2015 +0200
152.3 @@ -0,0 +1,1007 @@
152.4 +/*
152.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
152.6 + *
152.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
152.8 + *
152.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
152.10 + * Other names may be trademarks of their respective owners.
152.11 + *
152.12 + * The contents of this file are subject to the terms of either the GNU
152.13 + * General Public License Version 2 only ("GPL") or the Common
152.14 + * Development and Distribution License("CDDL") (collectively, the
152.15 + * "License"). You may not use this file except in compliance with the
152.16 + * License. You can obtain a copy of the License at
152.17 + * http://www.netbeans.org/cddl-gplv2.html
152.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
152.19 + * specific language governing permissions and limitations under the
152.20 + * License. When distributing the software, include this License Header
152.21 + * Notice in each file and include the License file at
152.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
152.23 + * particular file as subject to the "Classpath" exception as provided
152.24 + * by Oracle in the GPL Version 2 section of the License file that
152.25 + * accompanied this code. If applicable, add the following below the
152.26 + * License Header, with the fields enclosed by brackets [] replaced by
152.27 + * your own identifying information:
152.28 + * "Portions Copyrighted [year] [name of copyright owner]"
152.29 + *
152.30 + * Contributor(s):
152.31 + *
152.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
152.33 + */
152.34 +package org.netbeans.modules.python.source;
152.35 +
152.36 +import java.util.ArrayList;
152.37 +import java.util.Collections;
152.38 +import java.util.HashSet;
152.39 +import java.util.Iterator;
152.40 +import java.util.List;
152.41 +import java.util.Set;
152.42 +import java.util.logging.Level;
152.43 +import java.util.logging.Logger;
152.44 +import javax.swing.text.BadLocationException;
152.45 +import javax.swing.text.Document;
152.46 +import org.netbeans.api.lexer.LanguagePath;
152.47 +import org.netbeans.api.lexer.TokenHierarchy;
152.48 +import org.netbeans.api.lexer.TokenSequence;
152.49 +import org.netbeans.api.lexer.TokenUtilities;
152.50 +import org.netbeans.editor.BaseDocument;
152.51 +import org.netbeans.editor.Finder;
152.52 +import org.netbeans.editor.FinderFactory;
152.53 +import org.netbeans.modules.csl.api.ElementKind;
152.54 +import org.netbeans.modules.csl.api.OffsetRange;
152.55 +import org.netbeans.modules.csl.api.StructureItem;
152.56 +import org.netbeans.modules.csl.spi.GsfUtilities;
152.57 +import org.netbeans.modules.csl.spi.ParserResult;
152.58 +import org.netbeans.modules.parsing.api.ParserManager;
152.59 +import org.netbeans.modules.parsing.api.ResultIterator;
152.60 +import org.netbeans.modules.parsing.api.Source;
152.61 +import org.netbeans.modules.parsing.api.UserTask;
152.62 +import org.netbeans.modules.parsing.spi.ParseException;
152.63 +import org.netbeans.modules.python.source.elements.IndexedElement;
152.64 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
152.65 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
152.66 +import org.netbeans.modules.python.source.lexer.PythonCommentTokenId;
152.67 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
152.68 +import org.netbeans.modules.python.source.scopes.SymbolTable;
152.69 +import org.netbeans.modules.python.source.scopes.SymInfo;
152.70 +import org.openide.filesystems.FileObject;
152.71 +import org.openide.util.Exceptions;
152.72 +import org.python.antlr.PythonTree;
152.73 +import org.python.antlr.Visitor;
152.74 +import org.python.antlr.ast.Assign;
152.75 +import org.python.antlr.ast.Attribute;
152.76 +import org.python.antlr.ast.Call;
152.77 +import org.python.antlr.ast.ClassDef;
152.78 +import org.python.antlr.ast.Expr;
152.79 +import org.python.antlr.ast.FunctionDef;
152.80 +import org.python.antlr.ast.Import;
152.81 +import org.python.antlr.ast.ImportFrom;
152.82 +import org.python.antlr.ast.Module;
152.83 +import org.python.antlr.ast.Name;
152.84 +import org.python.antlr.ast.Str;
152.85 +import org.python.antlr.ast.arguments;
152.86 +import org.python.antlr.base.expr;
152.87 +import org.python.antlr.base.stmt;
152.88 +
152.89 +/**
152.90 + * Utility functions for dealing with the Jython AST
152.91 + *
152.92 + * @author Tor Norbye
152.93 + */
152.94 +public class PythonAstUtils {
152.95 + private PythonAstUtils() {
152.96 + // This is just a utility class, no instances expected so private constructor
152.97 + }
152.98 +
152.99 + public static int getAstOffset(ParserResult result, int lexOffset) {
152.100 + if (result != null) {
152.101 + return result.getSnapshot().getEmbeddedOffset(lexOffset);
152.102 + }
152.103 +
152.104 + return lexOffset;
152.105 + }
152.106 +
152.107 + public static OffsetRange getAstOffsets(ParserResult result, OffsetRange lexicalRange) {
152.108 + if (result != null) {
152.109 + int rangeStart = lexicalRange.getStart();
152.110 + int start = result.getSnapshot().getEmbeddedOffset(rangeStart);
152.111 + if (start == rangeStart) {
152.112 + return lexicalRange;
152.113 + } else if (start == -1) {
152.114 + return OffsetRange.NONE;
152.115 + } else {
152.116 + // Assumes the translated range maintains size
152.117 + return new OffsetRange(start, start + lexicalRange.getLength());
152.118 + }
152.119 + }
152.120 + return lexicalRange;
152.121 + }
152.122 +
152.123 + public static PythonParserResult getParseResult(ParserResult result) {
152.124 + if(result == null || !(result instanceof PythonParserResult)) {
152.125 + return null;
152.126 + } else {
152.127 + return ((PythonParserResult)result);
152.128 + }
152.129 + }
152.130 +
152.131 + public static PythonTree getRoot(ParserResult r) {
152.132 + assert r instanceof PythonParserResult;
152.133 +
152.134 + PythonParserResult result = (PythonParserResult)r;
152.135 +
152.136 + return result.getRoot();
152.137 + }
152.138 +
152.139 + /**
152.140 + * Return a range that matches the given node's source buffer range
152.141 + */
152.142 + @SuppressWarnings("unchecked")
152.143 + public static OffsetRange getNameRange(PythonParserResult info, PythonTree node) {
152.144 +// final int type = node.getType();
152.145 +// switch (type) {
152.146 +// case Token.FUNCTION: {
152.147 +// if (node.hasChildren()) {
152.148 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
152.149 +// if (child.getType() == Token.FUNCNAME) {
152.150 +// return getNameRange(child);
152.151 +// }
152.152 +// }
152.153 +// }
152.154 +//
152.155 +// return getRange(node);
152.156 +// }
152.157 +// case Token.NAME:
152.158 +// case Token.BINDNAME:
152.159 +// case Token.FUNCNAME:
152.160 +// case Token.PARAMETER:
152.161 +// case Token.OBJLITNAME:
152.162 +// int start = node.getSourceStart();
152.163 +// String name = node.getString();
152.164 +// return new OffsetRange(start, start+name.length());
152.165 +// case Token.CALL:
152.166 +// PythonTree namePythonTree = findCallNamePythonTree(node);
152.167 +// if (namePythonTree != null) {
152.168 +// return getNameRange(namePythonTree);
152.169 +// }
152.170 +// }
152.171 +
152.172 + // XXX Is there a faster way to determine if it's a function,
152.173 + // e.g. some kind of "kind" or "id" or "type" enum attribute on the tree node
152.174 + if (node instanceof FunctionDef) {
152.175 + FunctionDef def = (FunctionDef)node;
152.176 + //node.getType();
152.177 +
152.178 + int defStart = def.getCharStartIndex();
152.179 +
152.180 + // Turns out that when you have decorators, the function start offset
152.181 + // -includes- the decorators which precede the "def" keyword, thus we
152.182 + // have to scan forwards to find the true beginning.
152.183 + List<expr> decorators = def.getInternalDecorator_list();
152.184 + if (decorators != null && decorators.size() > 0) {
152.185 + int maxEnd = 0;
152.186 + for (expr expr : decorators) {
152.187 + int exprEnd = expr.getCharStopIndex();
152.188 + if (exprEnd > maxEnd) {
152.189 + maxEnd = exprEnd;
152.190 + }
152.191 + }
152.192 + if (decorators.size() > 1) {
152.193 + maxEnd++;
152.194 + }
152.195 + defStart = maxEnd;
152.196 +
152.197 + // At first I was justlooking for the largest end offset of the decorators,
152.198 + // but if you have additional comments etc. that won't work right, so
152.199 + // in this case, go and look at the actual document
152.200 + if (info != null) {
152.201 + BaseDocument doc = GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false);
152.202 + if (doc != null) {
152.203 + int lexOffset = PythonLexerUtils.getLexerOffset(info, defStart);
152.204 + int limitOffset = PythonLexerUtils.getLexerOffset(info, def.getCharStopIndex());
152.205 + if (lexOffset != -1 && limitOffset != -1) {
152.206 + Finder finder = new FinderFactory.StringFwdFinder("def ", true);
152.207 + try {
152.208 + int foundOffset = doc.find(finder, lexOffset, limitOffset);
152.209 + if (foundOffset != -1) {
152.210 + defStart = foundOffset;
152.211 + }
152.212 + } catch (BadLocationException ex) {
152.213 + Exceptions.printStackTrace(ex);
152.214 + }
152.215 + }
152.216 + }
152.217 + }
152.218 + }
152.219 +
152.220 + // HACK: There's no separate node for the name offset itself, so I need
152.221 + // to figure it out. For now assume that it's exactly 4 characters away
152.222 + // from the beginning of "def" - def plus space. If there are multiple spaces
152.223 + // this won't work. I ought to look in the document and ensure that the character
152.224 + // there in fact is the start of the name, and if not, search forwards for it.
152.225 + int DELTA = 4; // HACK:
152.226 + int start = defStart + DELTA;
152.227 + int end = start + def.getInternalName().length();
152.228 +
152.229 + // TODO - look up offset
152.230 +
152.231 + return new OffsetRange(start, end);
152.232 + } else if (node instanceof ClassDef) {
152.233 + ClassDef def = (ClassDef)node;
152.234 + //node.getType();
152.235 +
152.236 + // HACK: There's no separate node for the name offset itself, so I need
152.237 + // to figure it out. For now assume that it's exactly 6 characters away
152.238 + // from the beginning of "class" - class plus space. If there are multiple spaces
152.239 + // this won't work. I ought to look in the document and ensure that the character
152.240 + // there in fact is the start of the name, and if not, search forwards for it.
152.241 + int DELTA = 6; // HACK:
152.242 + int start = def.getCharStartIndex() + DELTA;
152.243 + int end = start + def.getInternalName().length();
152.244 +
152.245 + // TODO - look up offset
152.246 +
152.247 + return new OffsetRange(start, end);
152.248 + } else if (node instanceof Attribute) {
152.249 + Attribute attr = (Attribute)node;
152.250 + return getNameRange(info, attr.getInternalValue());
152.251 + } else if (node instanceof Call) {
152.252 + Call call = (Call)node;
152.253 + if (call.getInternalFunc() instanceof Name) {
152.254 + return getNameRange(info, call.getInternalFunc());
152.255 + } else if (call.getInternalFunc() instanceof Attribute) {
152.256 + // The call name is in the value part of the name.value part
152.257 + Attribute attr = (Attribute)call.getInternalFunc();
152.258 + int start = attr.getInternalValue().getCharStopIndex() + 1; // +1: Skip .
152.259 + String name = attr.getInternalAttr();
152.260 + return new OffsetRange(start, start + name.length());
152.261 + } else {
152.262 + String name = getCallName(call);
152.263 + if (name != null) {
152.264 + int start = call.getCharStartIndex();
152.265 + return new OffsetRange(start, start + name.length());
152.266 + }
152.267 + }
152.268 + }
152.269 +
152.270 + return getRange(node);
152.271 + }
152.272 +
152.273 + /**
152.274 + * Return a range that matches the given node's source buffer range
152.275 + */
152.276 + @SuppressWarnings("unchecked")
152.277 + public static OffsetRange getRange(PythonTree node) {
152.278 + final int start = node.getCharStartIndex();
152.279 + final int end = node.getCharStopIndex();
152.280 +
152.281 +// assert end >= start : "Invalid offsets for " + node + ": start=" + start + " and end=" + end;
152.282 + if (end < start) {
152.283 + Logger logger = Logger.getLogger(PythonAstUtils.class.getName());
152.284 + logger.log(Level.WARNING, "Invalid offsets for " + node + ": start=" + start + " and end=" + end);
152.285 + return new OffsetRange(start, start);
152.286 + }
152.287 +
152.288 + return new OffsetRange(start, end);
152.289 + }
152.290 +
152.291 + public static boolean isNameNode(PythonTree node) {
152.292 + if (node instanceof Name) {
152.293 + return true;
152.294 + }
152.295 +
152.296 + return false;
152.297 + }
152.298 +
152.299 + /** Return if a function is a staticmethod **/
152.300 + public static boolean isStaticMethod(PythonTree node) {
152.301 + if (node instanceof FunctionDef) {
152.302 + FunctionDef def = (FunctionDef)node;
152.303 + List<expr> decorators = def.getInternalDecorator_list();
152.304 + if (decorators != null && decorators.size() > 0) {
152.305 + for (expr decorator : decorators) {
152.306 + if (decorator instanceof Name) {
152.307 + String decoratorName = ((Name)decorator).getText();
152.308 + if (decoratorName.equals("staticmethod")) { // NOI18N
152.309 + return true;
152.310 + }
152.311 + }
152.312 + }
152.313 + }
152.314 + }
152.315 +
152.316 + return false;
152.317 + }
152.318 +
152.319 + /** Compute the module/class name for the given node path */
152.320 + public static String getFqnName(AstPath path) {
152.321 + StringBuilder sb = new StringBuilder();
152.322 +
152.323 + Iterator<PythonTree> it = path.rootToLeaf();
152.324 +
152.325 + while (it.hasNext()) {
152.326 + PythonTree node = it.next();
152.327 +
152.328 + if (node instanceof ClassDef) {
152.329 + if (sb.length() > 0) {
152.330 + sb.append('.'); // NOI18N
152.331 + }
152.332 + ClassDef cls = (ClassDef)node;
152.333 + sb.append(cls.getInternalName());
152.334 + }
152.335 + }
152.336 +
152.337 + return sb.toString();
152.338 + }
152.339 +
152.340 + /** Return the node for the local scope containing the given node */
152.341 + public static PythonTree getLocalScope(AstPath path) {
152.342 + for (PythonTree node : path) {
152.343 + if (node instanceof FunctionDef) {
152.344 + return node;
152.345 + }
152.346 + }
152.347 +
152.348 + return path.root();
152.349 + }
152.350 +
152.351 + public static PythonTree getClassScope(AstPath path) {
152.352 + for (PythonTree node : path) {
152.353 + if (node instanceof ClassDef) {
152.354 + return node;
152.355 + }
152.356 + }
152.357 +
152.358 + return path.root();
152.359 + }
152.360 +
152.361 + public static ClassDef getClassDef(AstPath path) {
152.362 + for (PythonTree node : path) {
152.363 + if (node instanceof ClassDef) {
152.364 + return (ClassDef)node;
152.365 + }
152.366 + }
152.367 +
152.368 + return null;
152.369 + }
152.370 +
152.371 + public static boolean isClassMethod(AstPath path, FunctionDef def) {
152.372 + // Check to see if (a) the function is inside a class, and (b) it's
152.373 + // not nested in a function
152.374 + for (PythonTree node : path) {
152.375 + if (node instanceof ClassDef) {
152.376 + return true;
152.377 + }
152.378 + // Nested method private to this one?
152.379 + if (node instanceof FunctionDef && node != def) {
152.380 + return false;
152.381 + }
152.382 + }
152.383 +
152.384 + return false;
152.385 + }
152.386 +
152.387 + public static FunctionDef getFuncDef(AstPath path) {
152.388 + for (PythonTree node : path) {
152.389 + if (node instanceof FunctionDef) {
152.390 + return (FunctionDef)node;
152.391 + }
152.392 + }
152.393 +
152.394 + return null;
152.395 + }
152.396 +
152.397 + /**
152.398 + * Return true iff this call looks like a "getter". If we're not sure,
152.399 + * return the default value passed into this method, unknownDefault.
152.400 + */
152.401 + public static boolean isGetter(Call call, boolean unknownDefault) {
152.402 + String name = PythonAstUtils.getCallName(call);
152.403 + if (name == null) {
152.404 + return unknownDefault;
152.405 + }
152.406 +
152.407 + return name.startsWith("get") || name.startsWith("_get"); // NOI18N
152.408 + }
152.409 +
152.410 + public static String getCallName(Call call) {
152.411 + expr func = call.getInternalFunc();
152.412 +
152.413 + return getExprName(func);
152.414 + }
152.415 +
152.416 + public static String getExprName(expr type) {
152.417 + if (type instanceof Attribute) {
152.418 + Attribute attr = (Attribute)type;
152.419 + return attr.getInternalAttr();
152.420 + } else if (type instanceof Name) {
152.421 + return ((Name)type).getInternalId();
152.422 + } else if (type instanceof Call) {
152.423 + Call call = (Call)type;
152.424 + return getExprName(call.getInternalFunc());
152.425 + //} else if (type instanceof Str) {
152.426 + // return ((Str)type).getText();
152.427 + } else {
152.428 + return null;
152.429 + }
152.430 + }
152.431 +
152.432 + public static String getName(PythonTree node) {
152.433 + if (node instanceof Name) {
152.434 + return ((Name)node).getInternalId();
152.435 + }
152.436 + if (node instanceof Attribute) {
152.437 + Attribute attrib = (Attribute)node;
152.438 + String prefix = getName(attrib.getInternalValue());
152.439 + return (prefix + '.' + attrib.getInternalAttr());
152.440 + }
152.441 + NameVisitor visitor = new NameVisitor();
152.442 + try {
152.443 + Object result = visitor.visit(node);
152.444 + if (result instanceof String) {
152.445 + return (String)result;
152.446 + } else {
152.447 + // TODO HANDLE THIS!
152.448 + }
152.449 + } catch (Exception ex) {
152.450 + Exceptions.printStackTrace(ex);
152.451 + }
152.452 +
152.453 + return null;
152.454 + }
152.455 +
152.456 + public static List<String> getParameters(FunctionDef def) {
152.457 + arguments args = def.getInternalArgs();
152.458 + List<String> params = new ArrayList<>();
152.459 +
152.460 + NameVisitor visitor = new NameVisitor();
152.461 +
152.462 + for (expr e : args.getInternalArgs()) {
152.463 + try {
152.464 + Object result = visitor.visit(e);
152.465 + if (result instanceof String) {
152.466 + params.add((String)result);
152.467 + } else {
152.468 + // TODO HANDLE THIS!
152.469 + }
152.470 + } catch (Exception ex) {
152.471 + Exceptions.printStackTrace(ex);
152.472 + }
152.473 + }
152.474 +
152.475 + String vararg = args.getInternalVararg();
152.476 + if (vararg != null) {
152.477 + params.add(vararg);
152.478 + }
152.479 + String kwarg = args.getInternalKwarg();
152.480 + if (kwarg != null) {
152.481 + params.add(kwarg);
152.482 + }
152.483 +
152.484 + return params;
152.485 + }
152.486 +
152.487 + private static Str searchForDocNode(stmt stmt) {
152.488 + if (stmt instanceof Expr) {
152.489 + Expr expr = (Expr)stmt;
152.490 + expr value = expr.getInternalValue();
152.491 + if (value instanceof Str) {
152.492 + return (Str)value;
152.493 + }
152.494 + }
152.495 +
152.496 + return null;
152.497 + }
152.498 +
152.499 + public static Str getDocumentationNode(PythonTree node) {
152.500 + // DocString processing.
152.501 + // See http://www.python.org/dev/peps/pep-0257/
152.502 +
152.503 + // For modules, it's the first Str in the document.
152.504 + // For classes and methods, it's the first Str in the object.
152.505 + // For others, nothing.
152.506 +
152.507 + if (node instanceof FunctionDef) {
152.508 + // Function
152.509 + FunctionDef def = (FunctionDef)node;
152.510 + List<stmt> body = def.getInternalBody();
152.511 + if (body != null && body.size() > 0) {
152.512 + return searchForDocNode(body.get(0));
152.513 + }
152.514 + } else if (node instanceof ClassDef) {
152.515 + // Class
152.516 + ClassDef def = (ClassDef)node;
152.517 + List<stmt> body = def.getInternalBody();
152.518 + if (body != null && body.size() > 0) {
152.519 + return searchForDocNode(body.get(0));
152.520 + }
152.521 + } else if (node instanceof Module) {
152.522 + // Module
152.523 + Module module = (Module)node;
152.524 + List<stmt> body = module.getInternalBody();
152.525 + if (body != null && body.size() > 0) {
152.526 + return searchForDocNode(body.get(0));
152.527 + }
152.528 + }
152.529 + // TODO: As per http://www.python.org/dev/peps/pep-0257/ I should
152.530 + // also look for "additional docstrings" (Str node following a Str node)
152.531 + // and Assign str nodes
152.532 +
152.533 + return null;
152.534 + }
152.535 +
152.536 + public static String getStrContent(Str str) {
152.537 + String doc = str.getText();
152.538 +
152.539 + // Strip quotes
152.540 + // and U and/or R for unicode/raw string. U must always preceede r if present.
152.541 + if (doc.startsWith("ur") || doc.startsWith("UR") || // NOI18N
152.542 + doc.startsWith("Ur") || doc.startsWith("uR")) { // NOI18N
152.543 + doc = doc.substring(2);
152.544 + } else if (doc.startsWith("r") || doc.startsWith("u") || // NOI18N
152.545 + doc.startsWith("R") || doc.startsWith("U")) { // NOI18N
152.546 + doc = doc.substring(1);
152.547 + }
152.548 +
152.549 + if (doc.startsWith("\"\"\"") && doc.endsWith("\"\"\"")) { // NOI18N
152.550 + doc = doc.substring(3, doc.length() - 3);
152.551 + } else if (doc.startsWith("r\"\"\"") && doc.endsWith("\"\"\"")) { // NOI18N
152.552 + doc = doc.substring(4, doc.length() - 3);
152.553 + } else if (doc.startsWith("'''") && doc.endsWith("'''")) { // NOI18N
152.554 + doc = doc.substring(3, doc.length() - 3);
152.555 + } else if (doc.startsWith("r'''") && doc.endsWith("'''")) { // NOI18N
152.556 + doc = doc.substring(4, doc.length() - 3);
152.557 + } else if (doc.startsWith("\"") && doc.endsWith("\"")) { // NOI18N
152.558 + doc = doc.substring(1, doc.length() - 1);
152.559 + } else if (doc.startsWith("'") && doc.endsWith("'")) { // NOI18N
152.560 + doc = doc.substring(1, doc.length() - 1);
152.561 + }
152.562 +
152.563 + return doc;
152.564 + }
152.565 +
152.566 + public static String getDocumentation(PythonTree node) {
152.567 + Str str = getDocumentationNode(node);
152.568 + if (str != null) {
152.569 + return getStrContent(str);
152.570 + }
152.571 +
152.572 + return null;
152.573 + }
152.574 +
152.575 + public static PythonTree getForeignNode(final IndexedElement o, PythonParserResult[] parserResultRet) {
152.576 + FileObject fo = o.getFileObject();
152.577 +
152.578 + if (fo == null) {
152.579 + return null;
152.580 + }
152.581 +
152.582 + Source source = Source.create(fo);
152.583 + if(source == null) {
152.584 + return null;
152.585 + }
152.586 + final PythonParserResult[] resultHolder = new PythonParserResult[1];
152.587 + try {
152.588 + ParserManager.parse(Collections.singleton(source), new UserTask() {
152.589 +
152.590 + @Override
152.591 + public void run(ResultIterator resultIterator) throws Exception {
152.592 + resultHolder[0] = (PythonParserResult) resultIterator.getParserResult();
152.593 + }
152.594 + });
152.595 + } catch (ParseException ex) {
152.596 + Exceptions.printStackTrace(ex);
152.597 + }
152.598 +
152.599 + PythonParserResult info = resultHolder[0];
152.600 + if (parserResultRet != null) {
152.601 + parserResultRet[0] = info;
152.602 + }
152.603 + PythonParserResult result = getParseResult(info);
152.604 + if (result == null) {
152.605 + return null;
152.606 + }
152.607 +
152.608 + PythonTree root = getRoot(result);
152.609 + if (root == null) {
152.610 + return null;
152.611 + }
152.612 +
152.613 + if (o.getKind() == ElementKind.MODULE && root instanceof Module) {
152.614 + return root;
152.615 + }
152.616 +
152.617 + String signature = o.getSignature();
152.618 +
152.619 + if (signature == null) {
152.620 + return null;
152.621 + }
152.622 +
152.623 + SymbolTable symbolTable = result.getSymbolTable();
152.624 + SymInfo sym = symbolTable.findBySignature(o.getKind(), signature);
152.625 + if (sym != null && sym.node != null) {
152.626 + // Temporary diagnostic checking
152.627 + //assert ((o.getKind() != ElementKind.CONSTRUCTOR && o.getKind() != ElementKind.METHOD) ||
152.628 + // sym.node instanceof FunctionDef);
152.629 + //assert o.getKind() != ElementKind.CLASS || sym.node instanceof ClassDef;
152.630 +
152.631 + return sym.node;
152.632 + }
152.633 +
152.634 + // TODO - check args etc.
152.635 +// String name = o.getName();
152.636 +// boolean lookForFunction = o.getKind() == ElementKind.CONSTRUCTOR || o.getKind() == ElementKind.METHOD;
152.637 +// if (lookForFunction) {
152.638 +// for (AstElement element : result.getStructure().getElements()) {
152.639 +// if (element.getName().equals(name) && element.getSignature().equals(signature)) {
152.640 +// return element.getNode();
152.641 +// }
152.642 +// }
152.643 +// }
152.644 +// }
152.645 +
152.646 + ElementKind kind = o.getKind();
152.647 + List<PythonStructureItem> items = PythonStructureScanner.analyze(info).getElements();
152.648 + if (items != null) {
152.649 + return find(items, signature, kind);
152.650 + } else {
152.651 + return null;
152.652 + }
152.653 + }
152.654 +
152.655 + private static PythonTree find(List<? extends StructureItem> items, String signature, ElementKind kind) {
152.656 + for (StructureItem item : items) {
152.657 + ElementKind childKind = item.getKind();
152.658 + if (childKind == kind &&
152.659 + item instanceof PythonStructureItem &&
152.660 + signature.equals(((PythonStructureItem)item).getSignature())) {
152.661 + return ((PythonStructureItem)item).getNode();
152.662 + }
152.663 + if (childKind == ElementKind.CLASS && signature.contains(item.getName())) {
152.664 + @SuppressWarnings("unchecked")
152.665 + List<? extends StructureItem> children = item.getNestedItems();
152.666 + PythonTree result = find(children, signature, kind);
152.667 + if (result != null) {
152.668 + return result;
152.669 + }
152.670 + }
152.671 + }
152.672 +
152.673 + return null;
152.674 + }
152.675 +
152.676 + public static Set<OffsetRange> getAllOffsets(PythonParserResult info, AstPath path, int lexOffset, String name, boolean abortOnFree) {
152.677 + if (path == null) {
152.678 + path = AstPath.get(PythonAstUtils.getRoot(info), lexOffset);
152.679 + }
152.680 + PythonTree scope = PythonAstUtils.getLocalScope(path);
152.681 + SymbolTable symbolTable = PythonAstUtils.getParseResult(info).getSymbolTable();
152.682 + List<PythonTree> nodes = symbolTable.getOccurrences(scope, name, abortOnFree);
152.683 + if (nodes == null) {
152.684 + return null;
152.685 + }
152.686 + Set<OffsetRange> offsets = new HashSet<>();
152.687 + Document doc = GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false);
152.688 + if (doc == null) {
152.689 + return Collections.emptySet();
152.690 + }
152.691 + for (PythonTree node : nodes) {
152.692 + OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
152.693 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
152.694 +
152.695 + if (node instanceof Import || node instanceof ImportFrom) {
152.696 + // Try to find the exact spot
152.697 + if (abortOnFree) {
152.698 + return null;
152.699 + } else {
152.700 + lexRange = PythonLexerUtils.getImportNameOffset((BaseDocument)doc, lexRange, node, name);
152.701 + }
152.702 + } else if (abortOnFree && (node instanceof FunctionDef || node instanceof ClassDef)) {
152.703 + return null;
152.704 + }
152.705 +
152.706 + if (lexRange != OffsetRange.NONE) {
152.707 + offsets.add(lexRange);
152.708 + }
152.709 + }
152.710 + // Look for type variables
152.711 + ScopeInfo scopeInfo = symbolTable.getScopeInfo(scope);
152.712 + if (scopeInfo != null) {
152.713 + SymInfo sym = scopeInfo.tbl.get(name);
152.714 + if (sym != null && sym.isVariable(false)) {
152.715 + // Look for type declarations that can apply to this variable
152.716 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, PythonAstUtils.getRange(scope));
152.717 + if (lexRange != OffsetRange.NONE) {
152.718 + BaseDocument bdoc = (BaseDocument)doc;
152.719 + try {
152.720 + bdoc.readLock(); // For TokenHierarchy usage
152.721 + TokenHierarchy hi = TokenHierarchy.get(doc);
152.722 + LanguagePath languagePath = LanguagePath.get(LanguagePath.get(PythonTokenId.language()), PythonCommentTokenId.language());
152.723 + int startOffset = Math.min(lexRange.getStart(), doc.getLength());
152.724 + if (scope instanceof Module) {
152.725 + startOffset = 0; // Pick up comments before code starts
152.726 + }
152.727 + int endOffset = Math.min(lexRange.getEnd(), doc.getLength());
152.728 + @SuppressWarnings("unchecked")
152.729 + List<TokenSequence<? extends PythonCommentTokenId>> tsl = hi.tokenSequenceList(languagePath, startOffset, endOffset);
152.730 + for (TokenSequence<? extends PythonCommentTokenId> ts : tsl) {
152.731 + ts.moveStart();
152.732 + while (ts.moveNext()) {
152.733 + PythonCommentTokenId id = ts.token().id();
152.734 + if (id == PythonCommentTokenId.TYPEKEY) {
152.735 + if (ts.moveNext() && // skip separator
152.736 + ts.moveNext()) {
152.737 + if (ts.token().id() == PythonCommentTokenId.VARNAME) {
152.738 + if (TokenUtilities.equals(ts.token().text(), name)) {
152.739 + int start = ts.offset();
152.740 + OffsetRange nameRange = new OffsetRange(start, start + name.length());
152.741 + offsets.add(nameRange);
152.742 + }
152.743 + }
152.744 + }
152.745 + }
152.746 + }
152.747 + }
152.748 + } finally {
152.749 + bdoc.readUnlock();
152.750 + }
152.751 +
152.752 + }
152.753 + }
152.754 + }
152.755 +
152.756 + return offsets;
152.757 + }
152.758 +
152.759 + private static final class NameVisitor extends Visitor {
152.760 + @Override
152.761 + public Object visitName(Name name) throws Exception {
152.762 + return name.getInternalId();
152.763 + }
152.764 + }
152.765 +
152.766 + public static Set<OffsetRange> getLocalVarOffsets(PythonParserResult info, int lexOffset) {
152.767 + int astOffset = getAstOffset(info, lexOffset);
152.768 + if (astOffset != -1) {
152.769 + PythonTree root = getRoot(info);
152.770 + if (root != null) {
152.771 + AstPath path = AstPath.get(root, astOffset);
152.772 + if (path != null) {
152.773 + PythonTree closest = path.leaf();
152.774 + PythonTree scope = getLocalScope(path);
152.775 + String name = ((Name)closest).getInternalId();
152.776 +
152.777 + return getLocalVarOffsets(info, scope, name);
152.778 + }
152.779 + }
152.780 + }
152.781 +
152.782 + return Collections.emptySet();
152.783 + }
152.784 +
152.785 + public static Set<OffsetRange> getLocalVarOffsets(PythonParserResult info, PythonTree scope, String name) {
152.786 + LocalVarVisitor visitor = new LocalVarVisitor(info, name, false, true);
152.787 + try {
152.788 + visitor.visit(scope);
152.789 + return visitor.getOffsets();
152.790 + } catch (Exception ex) {
152.791 + Exceptions.printStackTrace(ex);
152.792 + return Collections.emptySet();
152.793 + }
152.794 + }
152.795 +
152.796 + public static List<Name> getLocalVarNodes(PythonParserResult info, PythonTree scope, String name) {
152.797 + LocalVarVisitor visitor = new LocalVarVisitor(info, name, true, false);
152.798 + try {
152.799 + visitor.visit(scope);
152.800 + return visitor.getVars();
152.801 + } catch (Exception ex) {
152.802 + Exceptions.printStackTrace(ex);
152.803 + return Collections.emptyList();
152.804 + }
152.805 + }
152.806 +
152.807 + public static List<Name> getLocalVarAssignNodes(PythonParserResult info, PythonTree scope, String name) {
152.808 + LocalVarAssignVisitor visitor = new LocalVarAssignVisitor(info, name, true, false);
152.809 + try {
152.810 + visitor.visit(scope);
152.811 + return visitor.getVars();
152.812 + } catch (Exception ex) {
152.813 + Exceptions.printStackTrace(ex);
152.814 + return Collections.emptyList();
152.815 + }
152.816 + }
152.817 +
152.818 + private static class LocalVarVisitor extends Visitor {
152.819 + private List<Name> vars = new ArrayList<>();
152.820 + private Set<OffsetRange> offsets = new HashSet<>();
152.821 + private String name;
152.822 + private PythonParserResult info;
152.823 + private boolean collectNames;
152.824 + private boolean collectOffsets;
152.825 + private PythonTree parent;
152.826 +
152.827 + private LocalVarVisitor(PythonParserResult info, String name, boolean collectNames, boolean collectOffsets) {
152.828 + this.info = info;
152.829 + this.name = name;
152.830 + this.collectNames = collectNames;
152.831 + this.collectOffsets = collectOffsets;
152.832 + }
152.833 +
152.834 + @Override
152.835 + public void traverse(PythonTree node) throws Exception {
152.836 + PythonTree oldParent = parent;
152.837 + parent = node;
152.838 + super.traverse(node);
152.839 + parent = oldParent;
152.840 + }
152.841 +
152.842 + @Override
152.843 + public Object visitName(Name node) throws Exception {
152.844 + if (parent instanceof Call && ((Call)parent).getInternalFunc() == node) {
152.845 + return super.visitName(node);
152.846 + }
152.847 +
152.848 + if ((name == null && !PythonUtils.isClassName(node.getInternalId(), false)) ||
152.849 + (name != null && name.equals(node.getInternalId()))) {
152.850 + if (collectOffsets) {
152.851 + OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
152.852 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
152.853 + if (lexRange != OffsetRange.NONE) {
152.854 + offsets.add(astRange);
152.855 + }
152.856 + }
152.857 + if (collectNames) {
152.858 + vars.add(node);
152.859 + }
152.860 + }
152.861 +
152.862 + return super.visitName(node);
152.863 + }
152.864 +
152.865 + public Set<OffsetRange> getOffsets() {
152.866 + return offsets;
152.867 + }
152.868 +
152.869 + public List<Name> getVars() {
152.870 + return vars;
152.871 + }
152.872 + }
152.873 +
152.874 + private static class LocalVarAssignVisitor extends Visitor {
152.875 + private List<Name> vars = new ArrayList<>();
152.876 + private Set<OffsetRange> offsets = new HashSet<>();
152.877 + private String name;
152.878 + private PythonParserResult info;
152.879 + private boolean collectNames;
152.880 + private boolean collectOffsets;
152.881 + private PythonTree parent;
152.882 +
152.883 + private LocalVarAssignVisitor(PythonParserResult info, String name, boolean collectNames, boolean collectOffsets) {
152.884 + this.info = info;
152.885 + this.name = name;
152.886 + this.collectNames = collectNames;
152.887 + this.collectOffsets = collectOffsets;
152.888 + }
152.889 +
152.890 + @Override
152.891 + public Object visitName(Name node) throws Exception {
152.892 + if (parent instanceof FunctionDef || parent instanceof Assign) {
152.893 + if ((name == null && !PythonUtils.isClassName(node.getInternalId(), false)) ||
152.894 + (name != null && name.equals(node.getInternalId()))) {
152.895 + if (collectOffsets) {
152.896 + OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
152.897 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
152.898 + if (lexRange != OffsetRange.NONE) {
152.899 + offsets.add(astRange);
152.900 + }
152.901 + }
152.902 + if (collectNames) {
152.903 + vars.add(node);
152.904 + }
152.905 + }
152.906 + }
152.907 +
152.908 + return super.visitName(node);
152.909 + }
152.910 +
152.911 + @Override
152.912 + public void traverse(PythonTree node) throws Exception {
152.913 + PythonTree oldParent = parent;
152.914 + parent = node;
152.915 + super.traverse(node);
152.916 + parent = oldParent;
152.917 + }
152.918 +
152.919 + public Set<OffsetRange> getOffsets() {
152.920 + return offsets;
152.921 + }
152.922 +
152.923 + public List<Name> getVars() {
152.924 + return vars;
152.925 + }
152.926 + }
152.927 +
152.928 + /** Collect nodes of the given types (node.nodeId==NodeTypes.x) under the given root */
152.929 + public static void addNodesByType(PythonTree root, Class[] nodeClasses, List<PythonTree> result) {
152.930 + try {
152.931 + new NodeTypeVisitor(result, nodeClasses).visit(root);
152.932 + } catch (Exception ex) {
152.933 + Exceptions.printStackTrace(ex);
152.934 + }
152.935 + }
152.936 +
152.937 + private static class NodeTypeVisitor extends Visitor {
152.938 + private Class[] nodeClasses;
152.939 + private List<PythonTree> result;
152.940 +
152.941 + NodeTypeVisitor(List<PythonTree> result, Class[] nodeClasses) {
152.942 + this.result = result;
152.943 + this.nodeClasses = nodeClasses;
152.944 + }
152.945 +
152.946 + @Override
152.947 + public void traverse(PythonTree node) throws Exception {
152.948 + for (Class nodeClasse : nodeClasses) {
152.949 + if (node.getClass() == nodeClasse) {
152.950 + result.add(node);
152.951 + break;
152.952 + }
152.953 + }
152.954 +
152.955 + super.traverse(node);
152.956 + }
152.957 + }
152.958 +
152.959 + public static Name getParentClassFromNode(AstPath path, PythonTree from, String name) {
152.960 + ClassDef curClass = (ClassDef)path.getTypedAncestor(ClassDef.class, from);
152.961 + if (curClass == null) {
152.962 + return null;
152.963 + }
152.964 +
152.965 + List<expr> baseClasses = curClass.getInternalBases();
152.966 + if (baseClasses == null) {
152.967 + return null; // no inheritance ;
152.968 + }
152.969 + int ii = 0;
152.970 + while (ii < baseClasses.size()) {
152.971 + if (baseClasses.get(ii) instanceof Name) {
152.972 + Name cur = (Name)baseClasses.get(ii);
152.973 + if (cur.getInternalId().equals(name)) {
152.974 + return cur;
152.975 + }
152.976 + }
152.977 + ii++;
152.978 + }
152.979 + return null;
152.980 + }
152.981 +
152.982 + /**
152.983 + * Look for the caret offset in the parameter list; return the
152.984 + * index of the parameter that contains it.
152.985 + */
152.986 + public static int findArgumentIndex(Call call, int astOffset, AstPath path) {
152.987 +
152.988 + // On the name part in the call rather than the args?
152.989 + if (astOffset <= call.getInternalFunc().getCharStopIndex()) {
152.990 + return -1;
152.991 + }
152.992 + List<expr> args = call.getInternalArgs();
152.993 + if (args != null) {
152.994 + int index = 0;
152.995 + for (; index < args.size(); index++) {
152.996 + expr et = args.get(index);
152.997 + if (et.getCharStopIndex() >= astOffset) {
152.998 + return index;
152.999 + }
152.1000 + }
152.1001 + }
152.1002 +
152.1003 + // TODO what about the other stuff in there --
152.1004 + //call.keywords;
152.1005 + //call.kwargs;
152.1006 + //call.starargs;
152.1007 +
152.1008 + return -1;
152.1009 + }
152.1010 +}
153.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
153.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonExample.py Mon Sep 21 13:01:16 2015 +0200
153.3 @@ -0,0 +1,10 @@
153.4 +"""Sample Module"""
153.5 +import foo
153.6 +CONSTANT = "VALUE"
153.7 +
153.8 +class Foo(Bar):
153.9 + """Class doc"""
153.10 +
153.11 + def __init__(self,args=''):
153.12 + # Comment
153.13 + print 1+2.0
154.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
154.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonFormatter.java Mon Sep 21 13:01:16 2015 +0200
154.3 @@ -0,0 +1,655 @@
154.4 +/*
154.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
154.6 + *
154.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
154.8 + *
154.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
154.10 + * Other names may be trademarks of their respective owners.
154.11 + *
154.12 + * The contents of this file are subject to the terms of either the GNU
154.13 + * General Public License Version 2 only ("GPL") or the Common
154.14 + * Development and Distribution License("CDDL") (collectively, the
154.15 + * "License"). You may not use this file except in compliance with the
154.16 + * License. You can obtain a copy of the License at
154.17 + * http://www.netbeans.org/cddl-gplv2.html
154.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
154.19 + * specific language governing permissions and limitations under the
154.20 + * License. When distributing the software, include this License Header
154.21 + * Notice in each file and include the License file at
154.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
154.23 + * particular file as subject to the "Classpath" exception as provided
154.24 + * by Oracle in the GPL Version 2 section of the License file that
154.25 + * accompanied this code. If applicable, add the following below the
154.26 + * License Header, with the fields enclosed by brackets [] replaced by
154.27 + * your own identifying information:
154.28 + * "Portions Copyrighted [year] [name of copyright owner]"
154.29 + *
154.30 + * If you wish your version of this file to be governed by only the CDDL
154.31 + * or only the GPL Version 2, indicate your decision by adding
154.32 + * "[Contributor] elects to include this software in this distribution
154.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
154.34 + * single choice of license, a recipient has the option to distribute
154.35 + * your version of this file under either the CDDL, the GPL Version 2 or
154.36 + * to extend the choice of license to its licensees as provided above.
154.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
154.38 + * Version 2 license, then the option applies only if the new code is
154.39 + * made subject to such option by the copyright holder.
154.40 + *
154.41 + * Contributor(s):
154.42 + *
154.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
154.44 + */
154.45 +package org.netbeans.modules.python.source;
154.46 +
154.47 +import java.util.ArrayList;
154.48 +import java.util.Collections;
154.49 +import java.util.HashMap;
154.50 +import java.util.List;
154.51 +import java.util.Map;
154.52 +import javax.swing.text.BadLocationException;
154.53 +import javax.swing.text.Document;
154.54 +import javax.swing.text.JTextComponent;
154.55 +import org.netbeans.api.editor.EditorRegistry;
154.56 +import org.netbeans.api.lexer.TokenSequence;
154.57 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
154.58 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
154.59 +import org.netbeans.api.lexer.Token;
154.60 +import org.netbeans.api.lexer.TokenId;
154.61 +import org.netbeans.api.lexer.TokenUtilities;
154.62 +import org.netbeans.editor.BaseDocument;
154.63 +import org.netbeans.editor.Utilities;
154.64 +import org.netbeans.modules.csl.api.EditList;
154.65 +import org.netbeans.modules.csl.api.Formatter;
154.66 +import org.netbeans.modules.csl.spi.GsfUtilities;
154.67 +import org.netbeans.modules.csl.spi.ParserResult;
154.68 +import org.netbeans.modules.editor.indent.api.IndentUtils;
154.69 +import org.netbeans.modules.editor.indent.spi.Context;
154.70 +import org.openide.util.Exceptions;
154.71 +
154.72 +/**
154.73 + * Implement formatting for Python. Since there are no {}'s etc. to uniquely
154.74 + * impose indentation on Python, this formatter really just tries to enforce
154.75 + * spaces-versus-tabs, and indentation width. E.g. it uses the existing indentation
154.76 + * to determine whether the next line should be idented more, same or less as the
154.77 + * current line and then enforces the current space and indent size settings.
154.78 + *
154.79 + * @todo Implement pretty printing: inserting newlines, removing spaces inside
154.80 + * parentheses, etc. See the recommendations in
154.81 + * http://www.python.org/dev/peps/pep-0008/
154.82 + * Do import statement cleanup too.
154.83 + * @todo Line up comment lines (# as a suffix, continued from a previous line)
154.84 + * @todo Handle continuation lines with extra indentation
154.85 + * @todo Line up list initializations better?
154.86 + *
154.87 + * @author Tor Norbye
154.88 + */
154.89 +public class PythonFormatter implements Formatter {
154.90 + private int indentSize;
154.91 + private int continuationIndentSize;
154.92 + private CodeStyle codeStyle;
154.93 +
154.94 + public PythonFormatter() {
154.95 + }
154.96 +
154.97 + public PythonFormatter(CodeStyle codeStyle) {
154.98 + this.codeStyle = codeStyle;
154.99 + }
154.100 +
154.101 + @Override
154.102 + public void reformat(Context context, ParserResult compilationInfo) {
154.103 +
154.104 + // No AST pretty printing yet
154.105 + // I should offer to go and do space insert/removal around commas, parentheses, etc.
154.106 + // as well as balancing long argument lists across lines
154.107 + Document document = context.document();
154.108 + int startOffset = context.startOffset();
154.109 + int endOffset = context.endOffset();
154.110 +
154.111 + reformat(context, document, startOffset, endOffset, (PythonParserResult) compilationInfo);
154.112 + }
154.113 +
154.114 + public void reformat(final Context context, Document document, int startOffset, int endOffset, PythonParserResult info) {
154.115 + if (codeStyle == null) {
154.116 + codeStyle = CodeStyle.getDefault(context.document());
154.117 + }
154.118 + if (info != null && codeStyle != null && codeStyle.formatImports() && !GsfUtilities.isCodeTemplateEditing(document) &&
154.119 + PythonAstUtils.getParseResult(info) != null) {
154.120 + new ImportManager(info, (BaseDocument)document, codeStyle).cleanup(null, startOffset, endOffset, false);
154.121 + }
154.122 +
154.123 + if (codeStyle != null) {
154.124 + cleanup(document, info, startOffset, endOffset);
154.125 + }
154.126 +
154.127 + reindent(context, document, startOffset, endOffset);
154.128 + }
154.129 +
154.130 + @Override
154.131 + public boolean needsParserResult() {
154.132 +// if (SourceUtils.isScanInProgress()) {
154.133 +// return false;
154.134 +// }
154.135 +
154.136 + // If we're going to format imports, then yes, we need the parser result
154.137 + JTextComponent target = EditorRegistry.lastFocusedComponent();
154.138 + if (target != null) {
154.139 + CodeStyle cs = CodeStyle.getDefault(target.getDocument());
154.140 + return cs != null ? cs.formatImports() : false;
154.141 + }
154.142 + return false;
154.143 + }
154.144 +
154.145 + @Override
154.146 + public int indentSize() {
154.147 + // 4 spaces: See http://www.python.org/dev/peps/pep-0008/
154.148 + return 4;
154.149 + }
154.150 +
154.151 + @Override
154.152 + public int hangingIndentSize() {
154.153 + return 4;
154.154 + }
154.155 +
154.156 + // Challenge: Two inconsistently formatted
154.157 + // Idea: Given a list of offsets and indentation, produce a graph (or recurse) where I mark all
154.158 + // siblings the exact same level
154.159 +
154.160 + // Algorithm:
154.161 + // Find smallest indent: That's the top level
154.162 + // Build a graph? Each indent line.
154.163 + //
154.164 + @Override
154.165 + public void reindent(final Context context) {
154.166 + Document document = context.document();
154.167 + int startOffset = context.startOffset();
154.168 + int endOffset = context.endOffset();
154.169 +
154.170 + reindent(context, document, startOffset, endOffset);
154.171 + }
154.172 +
154.173 + @SuppressWarnings("deprecation") // For doc.getFormatter()
154.174 + public void reindent(final Context context, Document document, int startOffset, int endOffset) {
154.175 + endOffset = Math.min(endOffset, document.getLength());
154.176 + startOffset = Math.min(startOffset, endOffset);
154.177 +
154.178 + continuationIndentSize = indentSize = IndentUtils.indentLevelSize(document);
154.179 +
154.180 +
154.181 + final BaseDocument doc = (BaseDocument)document;
154.182 + try {
154.183 + // Plan: Go through the lines, one by one, and compute the indentation levels relative to each other,
154.184 + // then normalize them (except inside strings), then apply!!
154.185 + // Also track whether we are used for newline indentation and if so, do smart bracket stuff
154.186 +
154.187 + // Current indentation for the given line. -1 means that it should be left alone (e.g.
154.188 + // we don't mess with multiline string literals.
154.189 + final List<Integer> offsets = new ArrayList<>();
154.190 +
154.191 + // Current indentation for the given line. -1 means that it should be left alone (e.g.
154.192 + // we don't mess with multiline string literals. Other negative numbers are offsets
154.193 + // pointing at a particular left parenthesis that this line should be aligned with
154.194 + final List<Integer> indentation = new ArrayList<>();
154.195 + final List<Integer> lParenOffsets = new ArrayList<>();
154.196 +
154.197 + try {
154.198 + doc.readLock(); // For token hierarchy usage
154.199 +
154.200 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, startOffset);
154.201 +
154.202 + int currentOffset = Utilities.getRowStart(doc, startOffset);
154.203 + int balance = 0;
154.204 + while (currentOffset <= endOffset) {
154.205 + if (!(Utilities.isRowEmpty(doc, currentOffset) || Utilities.isRowWhite(doc, currentOffset))) {
154.206 + Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, currentOffset);
154.207 + int indent = GsfUtilities.getLineIndent(doc, currentOffset);
154.208 + if (token != null) {
154.209 + if (token.id() == PythonTokenId.STRING_LITERAL || token.id() == PythonTokenId.STRING_END) {
154.210 + indent = -1;
154.211 + }
154.212 + }
154.213 +
154.214 + if (indent != -1) {
154.215 + if (balance <= 0) {
154.216 + indentation.add(indent);
154.217 + offsets.add(currentOffset);
154.218 + } else {
154.219 + assert balance <= lParenOffsets.size();
154.220 + int parenOffset = lParenOffsets.get(lParenOffsets.size()-balance);
154.221 + indentation.add(-parenOffset);
154.222 + offsets.add(currentOffset);
154.223 + }
154.224 + }
154.225 + }
154.226 +
154.227 + // TODO - look up the tokens to make sure we don't have a problem with literal nodes
154.228 +
154.229 + if (currentOffset > doc.getLength()) {
154.230 + break;
154.231 + }
154.232 +
154.233 + // Update the line balance
154.234 + int begin = Utilities.getRowStart(doc, currentOffset);
154.235 + int end = Utilities.getRowEnd(doc, currentOffset);
154.236 +
154.237 + ts.move(begin);
154.238 +
154.239 + if (ts.moveNext()) {
154.240 + do {
154.241 + Token<? extends PythonTokenId> token = ts.token();
154.242 + TokenId id = token.id();
154.243 +
154.244 + if (id == PythonTokenId.LPAREN) {
154.245 + balance++;
154.246 + lParenOffsets.add(ts.offset());
154.247 + } else if (id == PythonTokenId.RPAREN) {
154.248 + balance--;
154.249 + if (!lParenOffsets.isEmpty()) {
154.250 + lParenOffsets.remove(lParenOffsets.size()-1);
154.251 + }
154.252 + }
154.253 + } while (ts.moveNext() && (ts.offset() <= end));
154.254 + }
154.255 +
154.256 + currentOffset = Utilities.getRowEnd(doc, currentOffset) + 1;
154.257 + }
154.258 + } finally {
154.259 + doc.readUnlock();
154.260 + }
154.261 +
154.262 + // Nothing to do
154.263 + if (offsets.size() == 0) {
154.264 + return;
154.265 + }
154.266 +
154.267 + assert indentation.size() == offsets.size();
154.268 +
154.269 + final Map<Integer, Integer> offsetToLevel = new HashMap<>();
154.270 + final Map<Integer,Integer> offsetToIndex = new HashMap<>();
154.271 + List<Integer> parentIndentations = new ArrayList<>();
154.272 + int currentParentIndent = -1;
154.273 + int currentLevel = -1;
154.274 +
154.275 + int firstIndent = indentation.get(0);
154.276 + List<Integer> sorted = new ArrayList<>(indentation);
154.277 + Collections.sort(sorted);
154.278 + // Attempt to shift the computed indentation to fit the right indentation levels
154.279 + // that are currently in the file?
154.280 + int firstNonNeg = 0;
154.281 + for (; firstNonNeg < sorted.size(); firstNonNeg++) {
154.282 + if (sorted.get(firstNonNeg) >= 0) {
154.283 + break;
154.284 + }
154.285 + }
154.286 + boolean shiftToCurrent = true;
154.287 + if (firstIndent > sorted.get(firstNonNeg)) {
154.288 + shiftToCurrent = false;
154.289 + // The start is not at the top level... e.g. we have something like
154.290 + // foo
154.291 + // else
154.292 + // bar
154.293 + // (e.g. we are formatting a fragment of code which doesn't include
154.294 + // the top). Here we need to find the "true" top levels, so we
154.295 + // push levels on to the stack
154.296 + int prev = -1;
154.297 + for (int indent : sorted) {
154.298 + if (prev == indent) {
154.299 + continue;
154.300 + }
154.301 + prev = indent;
154.302 + if (indent < firstIndent) {
154.303 + parentIndentations.add(currentParentIndent);
154.304 + currentParentIndent = indent;
154.305 + currentLevel++;
154.306 + } else {
154.307 + break;
154.308 + }
154.309 + }
154.310 + }
154.311 +
154.312 +
154.313 + // TODO: What if I start in the middle of an expression such that I outdent
154.314 + // more than I indent? I have to build up the index levels if necessary
154.315 + // Go count popping levels
154.316 +
154.317 + for (int i = 0, n = offsets.size(); i < n; i++) {
154.318 + int offset = offsets.get(i);
154.319 + int indent = indentation.get(i);
154.320 + if (indent == -1) {
154.321 + // Leave line alone
154.322 + offsetToLevel.put(offset, -1);
154.323 + continue;
154.324 + }
154.325 + offsetToIndex.put(offset, i);
154.326 +
154.327 + if (indent < 0) {
154.328 + // Want to keep everything the same as the prev, plus delta
154.329 + } else if (indent > currentParentIndent) {
154.330 + // New level
154.331 + currentLevel++;
154.332 + parentIndentations.add(currentParentIndent);
154.333 + currentParentIndent = indent;
154.334 + } else if (indent < currentParentIndent) {
154.335 + while (currentParentIndent > indent) {
154.336 + currentLevel--;
154.337 + if (parentIndentations.size() > 0) {
154.338 + currentParentIndent = parentIndentations.remove(parentIndentations.size() - 1);
154.339 + } else {
154.340 + currentParentIndent = indent;
154.341 + }
154.342 + }
154.343 + }
154.344 +
154.345 + offsetToLevel.put(offset, currentLevel);
154.346 + }
154.347 +
154.348 + // Compute relative shift
154.349 + int firstLineIndent = indentation.get(0);
154.350 + int firstLineLevel = offsetToLevel.get(offsets.get(0));
154.351 + int computedIndent = firstLineLevel * indentSize;
154.352 + final int relativeShift = shiftToCurrent ? computedIndent - firstLineIndent : 0;
154.353 +
154.354 + doc.runAtomic(new Runnable() {
154.355 + @Override
154.356 + public void run() {
154.357 + int[] computedIndents = new int[offsets.size()];
154.358 + // Process backwards so I don't have to worry about updating offsets affected by
154.359 + // indentation changes
154.360 + for (int i = offsets.size() - 1; i >= 0; i--) {
154.361 + int indent = indentation.get(i);
154.362 + if (indent == -1) {
154.363 + // Leave line alone
154.364 + continue;
154.365 + }
154.366 + if (indent >= 0) {
154.367 + int offset = offsets.get(i);
154.368 + int level = offsetToLevel.get(offset);
154.369 + int computedIndent = level * indentSize - relativeShift;
154.370 + if (computedIndent < 0) {
154.371 + computedIndent = 0;
154.372 + }
154.373 + computedIndents[i] =computedIndent;
154.374 + } else {
154.375 + computedIndents[i] = -1;
154.376 + }
154.377 + }
154.378 +
154.379 + for (int i = offsets.size() - 1; i >= 0; i--) {
154.380 + int indent = indentation.get(i);
154.381 + if (indent < -1) {
154.382 + try {
154.383 + // Negative offset pointing to a left parenthesis we should align with
154.384 + int parenOffset = -indent;
154.385 + int lineStart = Utilities.getRowStart(doc, parenOffset);
154.386 + if (lineStart != -1) {
154.387 + int parenLineIndent = computedIndents[offsetToIndex.get(lineStart)];
154.388 + assert parenLineIndent >= 0;
154.389 + int textBegin = Utilities.getRowFirstNonWhite(doc, lineStart);
154.390 + assert textBegin != -1;
154.391 + // Indent to new indentation + text up to paren plus the paren itself
154.392 + int newIndent = parenLineIndent + (parenOffset-textBegin) + 1;
154.393 + computedIndents[i] = newIndent;
154.394 + }
154.395 + } catch (BadLocationException ble) {
154.396 + Exceptions.printStackTrace(ble);
154.397 + }
154.398 + }
154.399 + }
154.400 +
154.401 + // Process backwards so I don't have to worry about updating offsets affected by
154.402 + // indentation changes
154.403 + for (int i = offsets.size() - 1; i >= 0; i--) {
154.404 + int indent = indentation.get(i);
154.405 + if (indent == -1) {
154.406 + // Leave line alone
154.407 + continue;
154.408 + }
154.409 + int offset = offsets.get(i);
154.410 + int computedIndent = computedIndents[i];
154.411 + if (computedIndent < 0) {
154.412 + computedIndent = 0;
154.413 + }
154.414 +
154.415 + if (computedIndent != indent) {
154.416 + try {
154.417 + context.modifyIndent(offset, computedIndent);
154.418 + } catch (BadLocationException ex) {
154.419 + Exceptions.printStackTrace(ex);
154.420 + }
154.421 + }
154.422 + }
154.423 + }
154.424 + });
154.425 + } catch (BadLocationException ble) {
154.426 + Exceptions.printStackTrace(ble);
154.427 + }
154.428 + }
154.429 +
154.430 + private boolean isLinePrefix(BaseDocument doc, int offset) throws BadLocationException {
154.431 + return Utilities.getRowFirstNonWhite(doc, offset) == offset;
154.432 + }
154.433 +
154.434 + private void cleanup(Document document, PythonParserResult info, int startOffset, int endOffset) {
154.435 + BaseDocument doc = (BaseDocument)document;
154.436 + final EditList edits = new EditList(doc);
154.437 + try {
154.438 + doc.readLock(); // For token hierarchy usage
154.439 +
154.440 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, startOffset);
154.441 + if (ts == null) {
154.442 + return;
154.443 + }
154.444 +
154.445 + ts.move(startOffset);
154.446 +
154.447 +
154.448 +
154.449 + // TODO:
154.450 + // Control whether I collapse spaces to a single space, or just ensure there is at least one
154.451 + // "None", "1", "At least 1", "Leave Alone"
154.452 +
154.453 + // TODO: Insert and remove needed or unnecessary parentheses!
154.454 + // TODO: Alignment! Especially of trailing line comments on adjacent lines!
154.455 + // TODO: Collapse blank newlines!
154.456 + boolean addSpaceAroundOperators = true;
154.457 + boolean removeSpaceInsideParens = true; // also applies to braces and brackets
154.458 + boolean addSpaceAfterComma = true;
154.459 + // boolean spaceArondParens = false;
154.460 + // boolean spaceBeforeArgs = false; // before parentheses in a call
154.461 + boolean removeSpaceBeforeSep = true; // before comma, semicolon or colon
154.462 + // boolean alignAssignments = false; // Only one space around assignments
154.463 + boolean removeSpaceInParamAssign = true; // Around assignment in parameter list, e.g.
154.464 + boolean collapseSpaces = true;
154.465 + //def complex(real, imag=0.0):
154.466 + // return magic(r=real, i=imag)
154.467 + if (codeStyle != null) {
154.468 + addSpaceAroundOperators = codeStyle.addSpaceAroundOperators();
154.469 + removeSpaceInsideParens = codeStyle.removeSpaceInsideParens();
154.470 + addSpaceAfterComma = codeStyle.addSpaceAfterComma();
154.471 + removeSpaceBeforeSep = codeStyle.removeSpaceBeforeSep();
154.472 + removeSpaceInParamAssign = codeStyle.removeSpaceInParamAssign();
154.473 + collapseSpaces = codeStyle.collapseSpaces();
154.474 + }
154.475 +
154.476 + // TODO - back up to the nearest function or class or beginning of the document to get the right
154.477 + // parenthesis balance.
154.478 + int parenBalance = 0;
154.479 +
154.480 + Token<? extends PythonTokenId> prev = null;
154.481 + Token<? extends PythonTokenId> token = null;
154.482 + Token<? extends PythonTokenId> next = null;
154.483 + int tokenOffset = 0;
154.484 + int nextOffset = 0;
154.485 + int prevOffset = -1;
154.486 + if (ts.moveNext()) {
154.487 + token = ts.token();
154.488 + tokenOffset = ts.offset();
154.489 + if (ts.moveNext()) {
154.490 + next = ts.token();
154.491 + nextOffset = ts.offset();
154.492 + } else {
154.493 + return;
154.494 + }
154.495 + }
154.496 + boolean prevRemoved = false;
154.497 + boolean tokenRemoved = false;
154.498 + boolean nextRemoved = false;
154.499 + while (token != null) {
154.500 + TokenId prevId = prev != null ? prev.id() : null;
154.501 + TokenId id = token.id();
154.502 + TokenId nextId = next != null ? next.id() : null;
154.503 +
154.504 + if (id == PythonTokenId.LPAREN) {
154.505 + parenBalance++;
154.506 + } else if (id == PythonTokenId.RPAREN) {
154.507 + parenBalance--;
154.508 + }
154.509 +
154.510 + if (removeSpaceInsideParens) {
154.511 + if (id == PythonTokenId.LPAREN) {
154.512 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
154.513 + edits.replace(nextOffset, next.length(), null, false, 0);
154.514 + nextRemoved = true;
154.515 + }
154.516 + } else if (id == PythonTokenId.RPAREN) {
154.517 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
154.518 + // I don't remove space in front of paren's at the beginning of the line; these might have
154.519 + // been aligned with indented content above
154.520 + edits.replace(prevOffset, prev.length(), null, false, 0);
154.521 + prevRemoved = true;
154.522 + }
154.523 + } else if (id == PythonTokenId.LBRACKET) {
154.524 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
154.525 + edits.replace(nextOffset, next.length(), null, false, 0);
154.526 + nextRemoved = true;
154.527 + }
154.528 + } else if (id == PythonTokenId.RBRACKET) {
154.529 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
154.530 + edits.replace(prevOffset, prev.length(), null, false, 0);
154.531 + prevRemoved = true;
154.532 + }
154.533 + } else if (id == PythonTokenId.LBRACE) {
154.534 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
154.535 + edits.replace(nextOffset, next.length(), null, false, 0);
154.536 + nextRemoved = true;
154.537 + }
154.538 + } else if (id == PythonTokenId.RBRACE) {
154.539 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
154.540 + edits.replace(prevOffset, prev.length(), null, false, 0);
154.541 + prevRemoved = true;
154.542 + }
154.543 + }
154.544 + }
154.545 +
154.546 + if (addSpaceAfterComma) {
154.547 + if (id == PythonTokenId.COMMA) {
154.548 + if (collapseSpaces && nextId == PythonTokenId.WHITESPACE && next.length() > 1) {
154.549 + edits.replace(nextOffset, next.length() - 1, null, false, 1); // NOI18N
154.550 + } else if (next == null ||
154.551 + (nextId != PythonTokenId.WHITESPACE && nextId != PythonTokenId.NEWLINE)) {
154.552 + edits.replace(nextOffset, 0, " ", false, 1); // NOI18N
154.553 + }
154.554 + }
154.555 + }
154.556 +
154.557 + if (removeSpaceBeforeSep &&
154.558 + (id == PythonTokenId.COMMA || id == PythonTokenId.COLON ||
154.559 + (id == PythonTokenId.ANY_OPERATOR && TokenUtilities.equals(token.text(), ";"))) && // NOI18N
154.560 + prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
154.561 + edits.replace(prevOffset, prev.length(), null, false, 2);
154.562 + prevRemoved = true;
154.563 + }
154.564 +
154.565 + if (addSpaceAroundOperators && id == PythonTokenId.ANY_OPERATOR) {
154.566 + CharSequence seq = token.text();
154.567 +
154.568 + // These aren't binary, and ; isn't really an operator and has its own setting
154.569 + if (!(TokenUtilities.equals(seq, "@") || // NOI18N
154.570 + TokenUtilities.equals(seq, "`") || // NOI18N
154.571 + TokenUtilities.equals(seq, ";"))) { // NOI18N
154.572 +
154.573 + boolean insertSpace = true;
154.574 + if (removeSpaceInParamAssign && TokenUtilities.equals(seq, "=")) { // NOI18N
154.575 + // Special handling: keyword arguments should typically NOT
154.576 + // have space inserted
154.577 + if (parenBalance > 0) {
154.578 + insertSpace = false;
154.579 + // Remove spaces around the =
154.580 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved) {
154.581 + edits.replace(prevOffset, prev.length(), null, false, 5); // NOI18N
154.582 + prevRemoved = true;
154.583 + }
154.584 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
154.585 + edits.replace(nextOffset, next.length(), null, false, 6); // NOI18N
154.586 + nextRemoved = true;
154.587 + }
154.588 + }
154.589 + }
154.590 +
154.591 + if (insertSpace && TokenUtilities.equals(seq, "-")/* && (nextId == PythonTokenId.FLOAT_LITERAL || nextId == PythonTokenId.INT_LITERAL)*/) {
154.592 + // Leave -'s alone for now. The code is a little unclear on the difference between
154.593 + // x-1 and =-1 etc. For numbers (floating and integer) the minus isn't part of the lexical token for the number;
154.594 + // it's a separate operator. However, it's tricky to tell this apart from the binary subtraction, since it depends
154.595 + // on what came before. For now play it safe an leave these alone.
154.596 + // TODO - implement this properly.
154.597 + insertSpace = false;
154.598 + }
154.599 +
154.600 + if (insertSpace && TokenUtilities.equals(seq, "*")) { // NOI18N
154.601 + // "*" in (*foo) doesn't mean multiplication; it's not a binary operator here,
154.602 + // it's many args.
154.603 + if (prevId == PythonTokenId.COMMA || prevId == PythonTokenId.LPAREN) {
154.604 + insertSpace = false;
154.605 + }
154.606 + }
154.607 +
154.608 + if (insertSpace) {
154.609 + // Ensure that we have space on both sides
154.610 + if (collapseSpaces && prevId == PythonTokenId.WHITESPACE && next.length() > 1 &&
154.611 + !isLinePrefix(doc, tokenOffset)) {
154.612 + edits.replace(prevOffset, prev.length() - 1, null, false, 1); // NOI18N
154.613 + } else if (prevId != PythonTokenId.WHITESPACE) {
154.614 + edits.replace(tokenOffset, 0, " ", false, 3); // NOI18N
154.615 + }
154.616 +
154.617 + if (collapseSpaces && nextId == PythonTokenId.WHITESPACE && next.length() > 1) {
154.618 + edits.replace(nextOffset, next.length() - 1, null, false, 1); // NOI18N
154.619 + } else if (nextId != PythonTokenId.WHITESPACE && nextId != PythonTokenId.NEWLINE) {
154.620 + edits.replace(nextOffset, 0, " ", false, 4); // NOI18N
154.621 + }
154.622 + }
154.623 + }
154.624 + }
154.625 +
154.626 + if (tokenOffset + token.length() >= endOffset) {
154.627 + break;
154.628 + }
154.629 +
154.630 + prevRemoved = tokenRemoved;
154.631 + tokenRemoved = nextRemoved;
154.632 + nextRemoved = false;
154.633 +
154.634 + prev = token;
154.635 + token = next;
154.636 + prevOffset = tokenOffset;
154.637 + tokenOffset = nextOffset;
154.638 + if (ts.moveNext()) {
154.639 + next = ts.token();
154.640 + nextOffset = ts.offset();
154.641 + } else {
154.642 + next = null;
154.643 + }
154.644 + }
154.645 + } catch (BadLocationException ble) {
154.646 + Exceptions.printStackTrace(ble);
154.647 + } finally {
154.648 + doc.readUnlock();
154.649 + }
154.650 +
154.651 + doc.runAtomic(new Runnable() {
154.652 + @Override
154.653 + public void run() {
154.654 + edits.apply();
154.655 + }
154.656 + });
154.657 + }
154.658 +}
155.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
155.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndex.java Mon Sep 21 13:01:16 2015 +0200
155.3 @@ -0,0 +1,1470 @@
155.4 +/*
155.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
155.6 + *
155.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
155.8 + *
155.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
155.10 + * Other names may be trademarks of their respective owners.
155.11 + *
155.12 + * The contents of this file are subject to the terms of either the GNU
155.13 + * General Public License Version 2 only ("GPL") or the Common
155.14 + * Development and Distribution License("CDDL") (collectively, the
155.15 + * "License"). You may not use this file except in compliance with the
155.16 + * License. You can obtain a copy of the License at
155.17 + * http://www.netbeans.org/cddl-gplv2.html
155.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
155.19 + * specific language governing permissions and limitations under the
155.20 + * License. When distributing the software, include this License Header
155.21 + * Notice in each file and include the License file at
155.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
155.23 + * particular file as subject to the "Classpath" exception as provided
155.24 + * by Oracle in the GPL Version 2 section of the License file that
155.25 + * accompanied this code. If applicable, add the following below the
155.26 + * License Header, with the fields enclosed by brackets [] replaced by
155.27 + * your own identifying information:
155.28 + * "Portions Copyrighted [year] [name of copyright owner]"
155.29 + *
155.30 + * Contributor(s):
155.31 + *
155.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
155.33 + */
155.34 +package org.netbeans.modules.python.source;
155.35 +
155.36 +import java.io.File;
155.37 +import java.io.IOException;
155.38 +import java.net.MalformedURLException;
155.39 +import java.net.URL;
155.40 +import java.util.ArrayList;
155.41 +import java.util.Arrays;
155.42 +import java.util.Collection;
155.43 +import java.util.Collections;
155.44 +import java.util.EnumSet;
155.45 +import java.util.HashMap;
155.46 +import java.util.HashSet;
155.47 +import java.util.Iterator;
155.48 +import java.util.List;
155.49 +import java.util.Map;
155.50 +import java.util.Set;
155.51 +import java.util.WeakHashMap;
155.52 +import java.util.logging.Level;
155.53 +import java.util.logging.Logger;
155.54 +import org.netbeans.api.project.Project;
155.55 +import org.netbeans.modules.csl.api.ElementKind;
155.56 +import org.netbeans.modules.parsing.spi.indexing.PathRecognizer;
155.57 +import org.netbeans.modules.parsing.spi.indexing.support.IndexResult;
155.58 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
155.59 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CAMEL_CASE;
155.60 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CASE_INSENSITIVE_PREFIX;
155.61 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CASE_INSENSITIVE_REGEXP;
155.62 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.PREFIX;
155.63 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.REGEXP;
155.64 +import org.netbeans.modules.python.source.elements.IndexedElement;
155.65 +import org.netbeans.modules.python.api.PythonPlatform;
155.66 +import org.netbeans.modules.python.api.PythonPlatformManager;
155.67 +import org.netbeans.modules.python.source.impl.QuerySupportFactory;
155.68 +import org.netbeans.modules.python.source.elements.IndexedPackage;
155.69 +import org.openide.filesystems.FileObject;
155.70 +import org.openide.filesystems.FileStateInvalidException;
155.71 +import org.openide.filesystems.URLMapper;
155.72 +import org.openide.modules.InstalledFileLocator;
155.73 +import org.openide.util.Exceptions;
155.74 +import org.openide.util.Lookup;
155.75 +import org.python.antlr.ast.Import;
155.76 +import org.python.antlr.ast.ImportFrom;
155.77 +import org.python.antlr.ast.alias;
155.78 +
155.79 +/**
155.80 + *
155.81 + * @author alley
155.82 + * @author Tor Norbye
155.83 + */
155.84 +public class PythonIndex {
155.85 +// public static final Set<SearchScope> ALL_SCOPE = EnumSet.allOf(SearchScope.class);
155.86 +// public static final Set<SearchScope> SOURCE_SCOPE = EnumSet.of(SearchScope.SOURCE);
155.87 + static final String CLUSTER_URL = "cluster:"; // NOI18N
155.88 + static final String PYTHONHOME_URL = "python:"; // NOI18N
155.89 + private static final String STUB_MISSING = "stub_missing"; // NOI18N
155.90 +
155.91 + // The "functions" module is always imported by the interpreter, and ditto
155.92 + // for exceptions, constants, etc.
155.93 + public static Set<String> BUILTIN_MODULES = new HashSet<>();
155.94 +
155.95 +
155.96 + private static final Logger LOG = Logger.getLogger(PythonIndex.class.getName());
155.97 + public static final String OBJECT = "object"; // NOI18N
155.98 + static Map<String, Set<String>> wildcardImports = new HashMap<>();
155.99 + static Set<String> systemModules;
155.100 + // TODO - make weak?
155.101 + static Set<String> availableClasses;
155.102 + private static String clusterUrl = null;
155.103 + static {
155.104 + //BUILTIN_MODULES.add("objects"); // NOI18N -- just links to the others
155.105 + BUILTIN_MODULES.add("stdtypes"); // NOI18N
155.106 + //BUILTIN_MODULES.add("types"); // NOI18N
155.107 + BUILTIN_MODULES.add("exceptions"); // NOI18N
155.108 + BUILTIN_MODULES.add("functions"); // NOI18N
155.109 + BUILTIN_MODULES.add("constants"); // NOI18N
155.110 + }
155.111 +
155.112 + public static PythonIndex get(Collection<FileObject> roots) {
155.113 + // XXX no cache - is it needed?
155.114 + LOG.log(Level.FINE, "PythonIndex for roots: {0}", roots); //NOI18N
155.115 + return new PythonIndex(QuerySupportFactory.getQuerySupport(roots), false);
155.116 + }
155.117 +
155.118 + public static PythonIndex get(Project project) {
155.119 + Set<String> sourceIds = new HashSet<>();
155.120 + Set<String> libraryIds = new HashSet<>();
155.121 + Collection<? extends PathRecognizer> lookupAll = Lookup.getDefault().lookupAll(PathRecognizer.class);
155.122 + for (PathRecognizer pathRecognizer : lookupAll) {
155.123 + Set<String> source = pathRecognizer.getSourcePathIds();
155.124 + if (source != null) {
155.125 + sourceIds.addAll(source);
155.126 + }
155.127 + Set<String> library = pathRecognizer.getLibraryPathIds();
155.128 + if (library != null) {
155.129 + libraryIds.addAll(library);
155.130 + }
155.131 + }
155.132 +
155.133 + final Collection<FileObject> findRoots = QuerySupport.findRoots(project,
155.134 + sourceIds,
155.135 + libraryIds,
155.136 + Collections.<String>emptySet());
155.137 + return PythonIndex.get(findRoots);
155.138 + }
155.139 +
155.140 + private static final WeakHashMap<FileObject, PythonIndex> INDEX_CACHE = new WeakHashMap<>();
155.141 + public static PythonIndex get(FileObject fo) {
155.142 + PythonIndex index = INDEX_CACHE.get(fo);
155.143 + if (index == null) {
155.144 + LOG.log(Level.FINE, "Creating PythonIndex for FileObject: {0}", fo); //NOI18N
155.145 + index = new PythonIndex(QuerySupportFactory.getQuerySupport(fo), true);
155.146 + INDEX_CACHE.put(fo, index);
155.147 + }
155.148 + return index;
155.149 + }
155.150 +
155.151 + public static boolean isBuiltinModule(String module) {
155.152 + return BUILTIN_MODULES.contains(module) || STUB_MISSING.equals(module);
155.153 + }
155.154 +
155.155 + // For testing only
155.156 + public static void setClusterUrl(String url) {
155.157 + clusterUrl = url;
155.158 + }
155.159 +
155.160 + static String getPreindexUrl(String url) {
155.161 + // TODO - look up the correct platform to use!
155.162 + final PythonPlatformManager manager = PythonPlatformManager.getInstance();
155.163 + final String platformName = manager.getDefaultPlatform();
155.164 + PythonPlatform platform = manager.getPlatform(platformName);
155.165 + if (platform != null) {
155.166 + String s = platform.getHomeUrl();
155.167 + if (s != null) {
155.168 + if (url.startsWith(s)) {
155.169 + url = PYTHONHOME_URL + url.substring(s.length());
155.170 + return url;
155.171 + }
155.172 + }
155.173 + }
155.174 +
155.175 + String s = getClusterUrl();
155.176 +
155.177 + if (url.startsWith(s)) {
155.178 + return CLUSTER_URL + url.substring(s.length());
155.179 + }
155.180 +
155.181 + if (url.startsWith("jar:file:")) { // NOI18N
155.182 + String sub = url.substring(4);
155.183 + if (sub.startsWith(s)) {
155.184 + return CLUSTER_URL + sub.substring(s.length());
155.185 + }
155.186 + }
155.187 +
155.188 + return url;
155.189 + }
155.190 +
155.191 +/** Get the FileObject corresponding to a URL returned from the index */
155.192 + public static FileObject getFileObject(String url) {
155.193 + return getFileObject(url, null);
155.194 + }
155.195 +
155.196 + public static FileObject getFileObject(String url, FileObject context) {
155.197 + try {
155.198 + if (url.startsWith(PYTHONHOME_URL)) {
155.199 + Iterator<String> it = null;
155.200 +
155.201 + // TODO - look up the right platform for the given project
155.202 + //if (context != null) {
155.203 + // Project project = FileOwnerQuery.getOwner(context);
155.204 + // if (project != null) {
155.205 + // PythonPlatform platform = PythonPlatform.platformFor(project);
155.206 + // if (platform != null) {
155.207 + // it = Collections.singleton(platform).iterator();
155.208 + // }
155.209 + // }
155.210 + //}
155.211 +
155.212 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
155.213 + if (it == null) {
155.214 + it = manager.getPlatformList().iterator();
155.215 + }
155.216 + while (it.hasNext()) {
155.217 + String name = it.next();
155.218 + PythonPlatform platform = manager.getPlatform(name);
155.219 + if (platform != null) {
155.220 + String u = platform.getHomeUrl();
155.221 + if (u != null) {
155.222 + try {
155.223 + u = u + url.substring(PYTHONHOME_URL.length());
155.224 + FileObject fo = URLMapper.findFileObject(new URL(u));
155.225 + if (fo != null) {
155.226 + return fo;
155.227 + }
155.228 + } catch (MalformedURLException mue) {
155.229 + Exceptions.printStackTrace(mue);
155.230 + }
155.231 + }
155.232 + }
155.233 + }
155.234 +
155.235 + return null;
155.236 + } else if (url.startsWith(CLUSTER_URL)) {
155.237 + url = getClusterUrl() + url.substring(CLUSTER_URL.length()); // NOI18N
155.238 + if (url.contains(".egg!/")) { // NOI18N
155.239 + url = "jar:" + url; // NOI18N
155.240 + }
155.241 + }
155.242 +
155.243 + return URLMapper.findFileObject(new URL(url));
155.244 + } catch (MalformedURLException ex) {
155.245 + Exceptions.printStackTrace(ex);
155.246 + }
155.247 +
155.248 + return null;
155.249 + }
155.250 +
155.251 + static String getClusterUrl() {
155.252 + if (clusterUrl == null) {
155.253 + File f =
155.254 + InstalledFileLocator.getDefault().locate("modules/org-netbeans-modules-python-editor.jar", null, false); // NOI18N
155.255 +
155.256 + if (f == null) {
155.257 + throw new RuntimeException("Can't find cluster");
155.258 + }
155.259 +
155.260 + f = new File(f.getParentFile().getParentFile().getAbsolutePath());
155.261 +
155.262 + try {
155.263 + f = f.getCanonicalFile();
155.264 + clusterUrl = f.toURI().toURL().toExternalForm();
155.265 + } catch (IOException ioe) {
155.266 + Exceptions.printStackTrace(ioe);
155.267 + }
155.268 + }
155.269 +
155.270 + return clusterUrl;
155.271 + }
155.272 +
155.273 + private final QuerySupport index;
155.274 + private final boolean updateCache;
155.275 +
155.276 + /** Creates a new instance of PythonIndex */
155.277 + private PythonIndex(QuerySupport index, boolean updateCache) {
155.278 + this.index = index;
155.279 + this.updateCache = updateCache;
155.280 + }
155.281 +
155.282 + private boolean search(String fieldName, String fieldValue, QuerySupport.Kind kind, Set<? super IndexResult> result, final String... fieldsToLoad) {
155.283 + try {
155.284 + result.addAll(index.query(fieldName, fieldValue, kind, fieldsToLoad));
155.285 + return true;
155.286 + } catch (IOException ioe) {
155.287 + Exceptions.printStackTrace(ioe);
155.288 +
155.289 + return false;
155.290 + } catch (UnsupportedOperationException iuoe) {
155.291 + return false;
155.292 + }
155.293 + }
155.294 +
155.295 + public Set<IndexedElement> getModules(String name, final QuerySupport.Kind kind) {
155.296 + final Set<IndexResult> result = new HashSet<>();
155.297 +
155.298 + // if (!isValid()) {
155.299 + // LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
155.300 + // return;
155.301 + // }
155.302 +
155.303 + // TODO - handle case insensitive searches etc?
155.304 + String field = PythonIndexer.FIELD_MODULE_NAME;
155.305 +
155.306 + search(field, name, kind, result, PythonIndexer.FIELD_MODULE_ATTR_NAME, PythonIndexer.FIELD_MODULE_NAME);
155.307 +
155.308 + final Set<IndexedElement> modules = new HashSet<>();
155.309 +
155.310 + for (IndexResult map : result) {
155.311 + URL url = map.getUrl();
155.312 + if (url == null) {
155.313 + continue;
155.314 + }
155.315 + String path = url.toExternalForm();
155.316 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
155.317 + if (STUB_MISSING.equals(module)) {
155.318 + continue;
155.319 + }
155.320 +
155.321 + IndexedElement element = new IndexedElement(module, ElementKind.MODULE, path, null, null, null);
155.322 +
155.323 + String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
155.324 + if (attrs != null && attrs.indexOf('D') != -1) {
155.325 + element.setFlags(IndexedElement.DEPRECATED);
155.326 + }
155.327 +
155.328 + String rhs = path.substring(path.lastIndexOf('/') + 1);
155.329 + element.setRhs(rhs);
155.330 + modules.add(element);
155.331 + }
155.332 +
155.333 + return modules;
155.334 + }
155.335 +
155.336 + public Set<IndexedPackage> getPackages(String name, final QuerySupport.Kind kind) {
155.337 + final Set<IndexResult> result = new HashSet<>();
155.338 +
155.339 + String field = PythonIndexer.FIELD_MODULE_NAME;
155.340 + search(field, name, kind, result, PythonIndexer.FIELD_MODULE_NAME);
155.341 +
155.342 + final Set<IndexedPackage> packages = new HashSet<>();
155.343 +
155.344 + for (IndexResult map : result) {
155.345 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
155.346 +
155.347 + String pkgName = null;
155.348 + String pkg = null;
155.349 +
155.350 + int nextNextDot = -1;
155.351 + int lastDot = module.lastIndexOf('.');
155.352 + int nameLength = name.length();
155.353 + if (nameLength < lastDot) {
155.354 + int nextDot = module.indexOf('.', nameLength);
155.355 + if (nextDot != -1) {
155.356 + pkg = module.substring(0, nextDot);
155.357 + nextNextDot = module.indexOf('.', nextDot + 1);
155.358 + int start = module.lastIndexOf('.', name.length());
155.359 + if (start == -1) {
155.360 + start = 0;
155.361 + } else {
155.362 + start++;
155.363 + }
155.364 + pkgName = module.substring(start, nextDot);
155.365 + }
155.366 + } else if (lastDot != -1) {
155.367 + pkgName = module.substring(lastDot + 1);
155.368 + pkg = module;
155.369 + }
155.370 +
155.371 + if (pkgName != null) {
155.372 + String url = map.getUrl().toExternalForm();
155.373 + IndexedPackage element = new IndexedPackage(pkgName, pkg, url, nextNextDot != -1);
155.374 + element.setRhs("");
155.375 + packages.add(element);
155.376 + }
155.377 + }
155.378 +
155.379 + return packages;
155.380 + }
155.381 +
155.382 + public Set<IndexedElement> getClasses(String name, final QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
155.383 + final Set<IndexResult> result = new HashSet<>();
155.384 +
155.385 + // if (!isValid()) {
155.386 + // LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
155.387 + // return;
155.388 + // }
155.389 + String field;
155.390 +
155.391 + switch (kind) {
155.392 + case EXACT:
155.393 + case PREFIX:
155.394 + case CAMEL_CASE:
155.395 + case REGEXP:
155.396 + field = PythonIndexer.FIELD_CLASS_NAME;
155.397 +
155.398 + break;
155.399 +
155.400 + case CASE_INSENSITIVE_PREFIX:
155.401 + case CASE_INSENSITIVE_REGEXP:
155.402 + case CASE_INSENSITIVE_CAMEL_CASE:
155.403 + field = PythonIndexer.FIELD_CASE_INSENSITIVE_CLASS_NAME;
155.404 +
155.405 + break;
155.406 +
155.407 + default:
155.408 + throw new UnsupportedOperationException(kind.toString());
155.409 + }
155.410 +
155.411 + search(field, name, kind, result, PythonIndexer.FIELD_IN, PythonIndexer.FIELD_CLASS_ATTR_NAME, PythonIndexer.FIELD_CLASS_NAME);
155.412 +
155.413 + Set<String> uniqueClasses = includeDuplicates ? null : new HashSet<String>();
155.414 +
155.415 + final Set<IndexedElement> classes = new HashSet<>();
155.416 +
155.417 + for (IndexResult map : result) {
155.418 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.419 + if (clz == null) {
155.420 + // A module without classes
155.421 + continue;
155.422 + }
155.423 + String url = map.getUrl().toExternalForm();
155.424 + String module = map.getValue(PythonIndexer.FIELD_IN);
155.425 + boolean isBuiltin = isBuiltinModule(module);
155.426 +
155.427 + String fqn = clz; // No further namespaces in Python, right?
155.428 + if (!includeDuplicates) {
155.429 + if (!uniqueClasses.contains(fqn)) { // use a map to point right to the class
155.430 + uniqueClasses.add(fqn);
155.431 + IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
155.432 + if (isBuiltin) {
155.433 + element.setRhs("<i>builtin</i>");
155.434 + }
155.435 + String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
155.436 + if (attrs != null) {
155.437 + int flags = IndexedElement.decode(attrs, 0, 0);
155.438 + element.setFlags(flags);
155.439 + }
155.440 + element.setInherited(true);
155.441 +
155.442 + classes.add(element);
155.443 + } // else: Possibly pick the best version... based on which items have documentation attributes etc.
155.444 + } else {
155.445 + IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
155.446 + classes.add(element);
155.447 + }
155.448 + }
155.449 +
155.450 + return classes;
155.451 + }
155.452 +
155.453 +// /** Return the most distant method in the hierarchy that is overriding the given method, or null
155.454 +// * @todo Make this method actually compute most distant ancestor
155.455 +// * @todo Use arglist arity comparison to reject methods that are not overrides...
155.456 +// */
155.457 +// public IndexedMethod getOverridingMethod(String className, String methodName) {
155.458 +// Set<IndexedElement> methods = getInheritedElements(className, methodName, QuerySupport.Kind.EXACT);
155.459 +//
155.460 +// // TODO - this is only returning ONE match, not the most distant one. I really need to
155.461 +// // produce a PythonIndex method for this which can walk in there and do a decent job!
155.462 +//
155.463 +// for (IndexedElement method : methods) {
155.464 +// if (method.getKind() == ElementKind.METHOD || method.getKind() == ElementKind.CONSTRUCTOR) {
155.465 +// // getInheritedMethods may return methods ON fqn itself
155.466 +// if (!method.getIn().equals(className)) {
155.467 +// return (IndexedMethod)method;
155.468 +// }
155.469 +// }
155.470 +// }
155.471 +//
155.472 +// return null;
155.473 +// }
155.474 + /** Get the super implementation of the given method */
155.475 + public Set<IndexedElement> getOverridingMethods(String className, String function) {
155.476 + Set<IndexedElement> methods = getInheritedElements(className, function, QuerySupport.Kind.EXACT, true);
155.477 +
155.478 + // TODO - remove all methods that are in the same file
155.479 + if (methods.size() > 0) {
155.480 + Set<IndexedElement> result = new HashSet<>(methods.size());
155.481 + for (IndexedElement element : methods) {
155.482 + if (!className.equals(element.getClz())) {
155.483 + result.add(element);
155.484 + }
155.485 + }
155.486 + methods = result;
155.487 + }
155.488 +
155.489 + return methods;
155.490 +// // TODO - this is only returning ONE match, not the most distant one. I really need to
155.491 +// // produce a PythonIndex method for this which can walk in there and do a decent job!
155.492 +//
155.493 +// for (IndexedElement method : methods) {
155.494 +// if (method.getKind() == ElementKind.METHOD || method.getKind() == ElementKind.CONSTRUCTOR) {
155.495 +// // getInheritedMethods may return methods ON fqn itself
155.496 +// if (!method.getIn().equals(className)) {
155.497 +// return (IndexedMethod)method;
155.498 +// }
155.499 +// }
155.500 +// }
155.501 +//
155.502 +// return null;
155.503 + }
155.504 +
155.505 + /** Get the super class of the given class */
155.506 + public Set<IndexedElement> getSuperClasses(String className) {
155.507 + final Set<IndexResult> result = new HashSet<>();
155.508 +
155.509 + search(PythonIndexer.FIELD_CLASS_NAME, className, QuerySupport.Kind.EXACT, result, PythonIndexer.FIELD_EXTENDS_NAME, PythonIndexer.FIELD_CLASS_NAME);
155.510 +
155.511 + Set<String> classNames = new HashSet<>();
155.512 + for (IndexResult map : result) {
155.513 + String[] extendsClasses = map.getValues(PythonIndexer.FIELD_EXTENDS_NAME);
155.514 + if (extendsClasses != null && extendsClasses.length > 0) {
155.515 + for (String clzName : extendsClasses) {
155.516 + classNames.add(clzName);
155.517 + }
155.518 + }
155.519 + }
155.520 +
155.521 + String[] terms = { PythonIndexer.FIELD_IN, PythonIndexer.FIELD_CLASS_NAME };
155.522 +
155.523 + Set<IndexedElement> superClasses = new HashSet<>();
155.524 +
155.525 + for (String superClz : classNames) {
155.526 + result.clear();
155.527 + search(PythonIndexer.FIELD_CLASS_NAME, superClz, QuerySupport.Kind.EXACT, result, terms);
155.528 + for (IndexResult map : result) {
155.529 + assert superClz.equals(map.getValue(PythonIndexer.FIELD_CLASS_NAME));
155.530 + String url = map.getUrl().toExternalForm();
155.531 + String module = map.getValue(PythonIndexer.FIELD_IN);
155.532 + IndexedElement clz = new IndexedElement(superClz, ElementKind.CLASS, url, module, null, null);
155.533 + superClasses.add(clz);
155.534 + }
155.535 + }
155.536 +
155.537 + return superClasses;
155.538 + }
155.539 +
155.540 + /**
155.541 + * Get the set of inherited (through super classes and mixins) for the given fully qualified class name.
155.542 + * @param classFqn FQN: module1::module2::moduleN::class
155.543 + * @param prefix If kind is QuerySupport.Kind.PREFIX/CASE_INSENSITIVE_PREFIX, a prefix to filter methods by. Else,
155.544 + * if kind is QuerySupport.Kind.EXACT filter methods by the exact name.
155.545 + * @param kind Whether the prefix field should be taken as a prefix or a whole name
155.546 + */
155.547 + public Set<IndexedElement> getInheritedElements(String classFqn, String prefix, QuerySupport.Kind kind) {
155.548 + return getInheritedElements(classFqn, prefix, kind, false);
155.549 + }
155.550 +
155.551 + public Set<IndexedElement> getInheritedElements(String classFqn, String prefix, QuerySupport.Kind kind, boolean includeOverrides) {
155.552 + boolean haveRedirected = false;
155.553 +
155.554 + if (classFqn == null) {
155.555 + classFqn = OBJECT;
155.556 + haveRedirected = true;
155.557 + }
155.558 +
155.559 + //String field = PythonIndexer.FIELD_FQN_NAME;
155.560 + Set<IndexedElement> elements = new HashSet<>();
155.561 + Set<String> scannedClasses = new HashSet<>();
155.562 + Set<String> seenSignatures = new HashSet<>();
155.563 +
155.564 + if (prefix == null) {
155.565 + prefix = "";
155.566 + }
155.567 +
155.568 +// String searchUrl = null;
155.569 +// if (context != null) {
155.570 +// try {
155.571 +// searchUrl = context.getFile().getFileObject().getURL().toExternalForm();
155.572 +// } catch (FileStateInvalidException ex) {
155.573 +// Exceptions.printStackTrace(ex);
155.574 +// }
155.575 +// }
155.576 +
155.577 + addMethodsFromClass(prefix, kind, classFqn, elements, seenSignatures, scannedClasses,
155.578 + haveRedirected, false, includeOverrides, 0);
155.579 +
155.580 + return elements;
155.581 + }
155.582 +
155.583 + /** Return whether the specific class referenced (classFqn) was found or not. This is
155.584 + * not the same as returning whether any classes were added since it may add
155.585 + * additional methods from parents (Object/Class).
155.586 + */
155.587 + private boolean addMethodsFromClass(String prefix, QuerySupport.Kind kind, String classFqn, Set<IndexedElement> elements, Set<String> seenSignatures, Set<String> scannedClasses, boolean haveRedirected, boolean inheriting, boolean includeOverrides, int depth) {
155.588 + // Prevent problems with circular includes or redundant includes
155.589 + if (scannedClasses.contains(classFqn)) {
155.590 + return false;
155.591 + }
155.592 +
155.593 + scannedClasses.add(classFqn);
155.594 +
155.595 + String searchField = PythonIndexer.FIELD_CLASS_NAME;
155.596 +
155.597 + Set<IndexResult> result = new HashSet<>();
155.598 +
155.599 + String[] terms = {PythonIndexer.FIELD_IN,
155.600 + PythonIndexer.FIELD_EXTENDS_NAME,
155.601 + PythonIndexer.FIELD_MEMBER,
155.602 + PythonIndexer.FIELD_CLASS_NAME};
155.603 +
155.604 +
155.605 + search(searchField, classFqn, QuerySupport.Kind.EXACT, result, terms);
155.606 +
155.607 + boolean foundIt = result.size() > 0;
155.608 +
155.609 + // If this is a bogus class entry (no search rsults) don't continue
155.610 + if (!foundIt) {
155.611 + return foundIt;
155.612 + }
155.613 +
155.614 + List<String> extendsClasses = null;
155.615 +
155.616 + String classIn = null;
155.617 + int fqnIndex = classFqn.lastIndexOf("::"); // NOI18N
155.618 +
155.619 + if (fqnIndex != -1) {
155.620 + classIn = classFqn.substring(0, fqnIndex);
155.621 + }
155.622 + int prefixLength = prefix.length();
155.623 +
155.624 + for (IndexResult map : result) {
155.625 + assert map != null;
155.626 +
155.627 + String url = map.getUrl().toExternalForm();
155.628 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.629 + String module = map.getValue(PythonIndexer.FIELD_IN);
155.630 +
155.631 + if (extendsClasses == null) {
155.632 + String[] ext = map.getValues(PythonIndexer.FIELD_EXTENDS_NAME);
155.633 + if (ext != null && ext.length > 0) {
155.634 + if (extendsClasses == null) {
155.635 + extendsClasses = Arrays.asList(ext);
155.636 + } else {
155.637 + extendsClasses = new ArrayList<>(extendsClasses);
155.638 + extendsClasses.addAll(Arrays.asList(ext));
155.639 + }
155.640 + }
155.641 + }
155.642 +
155.643 + String[] members = map.getValues(PythonIndexer.FIELD_MEMBER);
155.644 +
155.645 + if (members != null) {
155.646 + for (String signature : members) {
155.647 + // Prevent duplicates when method is redefined
155.648 + if (includeOverrides || !seenSignatures.contains(signature)) {
155.649 + if (signature.startsWith(prefix)) {
155.650 + if (kind == QuerySupport.Kind.EXACT) {
155.651 + if (signature.charAt(prefixLength) != ';') {
155.652 + continue;
155.653 + }
155.654 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, prefix, 0, prefix.length())) {
155.655 + continue;
155.656 + } else {
155.657 + // REGEXP, CAMELCASE filtering etc. not supported here
155.658 + assert (kind == QuerySupport.Kind.PREFIX) ||
155.659 + (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
155.660 + }
155.661 +
155.662 + if (!includeOverrides) {
155.663 + seenSignatures.add(signature);
155.664 + }
155.665 + IndexedElement element = IndexedElement.create(signature, module, url, clz);
155.666 + // TODO - filter out private? Or let code completer do that? Probably should, in case
155.667 + // we have more rights when inheriting
155.668 + element.setSmart(!haveRedirected);
155.669 + element.setInherited(inheriting);
155.670 + if (includeOverrides) {
155.671 + element.setOrder(depth);
155.672 + }
155.673 + elements.add(element);
155.674 + }
155.675 + }
155.676 + }
155.677 + }
155.678 + }
155.679 +
155.680 + if (classFqn.equals(OBJECT)) {
155.681 + return foundIt;
155.682 + }
155.683 +
155.684 + if (extendsClasses == null || extendsClasses.size() == 0) {
155.685 + addMethodsFromClass(prefix, kind, OBJECT, elements, seenSignatures, scannedClasses,
155.686 + true, true, includeOverrides, depth + 1);
155.687 + } else {
155.688 + // We're not sure we have a fully qualified path, so try some different candidates
155.689 + for (String extendsClass : extendsClasses) {
155.690 + if (!addMethodsFromClass(prefix, kind, extendsClass, elements, seenSignatures,
155.691 + scannedClasses, haveRedirected, true, includeOverrides, depth + 1)) {
155.692 + // Search by classIn
155.693 + String fqn = classIn;
155.694 +
155.695 + while (fqn != null) {
155.696 + if (addMethodsFromClass(prefix, kind, fqn + "::" + extendsClass, elements,
155.697 + seenSignatures, scannedClasses, haveRedirected, true, includeOverrides, depth + 1)) {
155.698 + break;
155.699 + }
155.700 +
155.701 + int f = fqn.lastIndexOf("::"); // NOI18N
155.702 +
155.703 + if (f == -1) {
155.704 + break;
155.705 + } else {
155.706 + fqn = fqn.substring(0, f);
155.707 + }
155.708 + }
155.709 + }
155.710 + }
155.711 + }
155.712 +
155.713 + return foundIt;
155.714 + }
155.715 +
155.716 +
155.717 + public Set<IndexedElement> getAllMembers(String name, QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
155.718 + final Set<IndexResult> result = new HashSet<>();
155.719 + // TODO - handle case sensitivity better...
155.720 + String field = PythonIndexer.FIELD_MEMBER;
155.721 + QuerySupport.Kind originalKind = kind;
155.722 + if (kind == QuerySupport.Kind.EXACT) {
155.723 + // I can't do exact searches on methods because the method
155.724 + // entries include signatures etc. So turn this into a prefix
155.725 + // search and then compare chopped off signatures with the name
155.726 + kind = QuerySupport.Kind.PREFIX;
155.727 + }
155.728 +
155.729 + String searchUrl = null;
155.730 + if (context != null) {
155.731 + searchUrl = context.getSnapshot().getSource().getFileObject().toURL().toExternalForm();
155.732 + }
155.733 +
155.734 + String[] terms = {PythonIndexer.FIELD_IN,
155.735 + PythonIndexer.FIELD_EXTENDS_NAME,
155.736 + PythonIndexer.FIELD_MEMBER,
155.737 + PythonIndexer.FIELD_CLASS_NAME};
155.738 +
155.739 + search(field, name, kind, result, terms);
155.740 +
155.741 +// Set<String> uniqueClasses = null;
155.742 +// if (includeDuplicates) {
155.743 +// uniqueClasses = null;
155.744 +// } else if (uniqueClasses == null) {
155.745 +// uniqueClasses = new HashSet<String>();
155.746 +// }
155.747 +
155.748 + final Set<IndexedElement> members = new HashSet<>();
155.749 + int nameLength = name.length();
155.750 +
155.751 + for (IndexResult map : result) {
155.752 + String[] signatures = map.getValues(PythonIndexer.FIELD_MEMBER);
155.753 + if (signatures != null && signatures.length > 0) {
155.754 + String url = map.getUrl().toExternalForm();
155.755 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.756 + String module = map.getValue(PythonIndexer.FIELD_IN);
155.757 + boolean inherited = searchUrl == null || !searchUrl.equals(url);
155.758 +
155.759 + for (String signature : signatures) {
155.760 + if (originalKind == QuerySupport.Kind.EXACT) {
155.761 + if (signature.charAt(nameLength) != ';') {
155.762 + continue;
155.763 + }
155.764 + } else if (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, name, 0, name.length())) {
155.765 + continue;
155.766 + } else {
155.767 + // REGEXP, CAMELCASE filtering etc. not supported here
155.768 + assert (originalKind == QuerySupport.Kind.PREFIX) ||
155.769 + (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
155.770 + }
155.771 +
155.772 + IndexedElement element = IndexedElement.create(signature, module, url, clz);
155.773 + element.setInherited(inherited);
155.774 + members.add(element);
155.775 + }
155.776 + }
155.777 + }
155.778 +
155.779 + return members;
155.780 + }
155.781 +
155.782 + public Set<IndexedElement> getAllElements(String name, QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
155.783 + final Set<IndexResult> result = new HashSet<>();
155.784 + // TODO - handle case sensitivity better...
155.785 + String field = PythonIndexer.FIELD_ITEM;
155.786 + QuerySupport.Kind originalKind = kind;
155.787 + if (kind == QuerySupport.Kind.EXACT) {
155.788 + // I can't do exact searches on methods because the method
155.789 + // entries include signatures etc. So turn this into a prefix
155.790 + // search and then compare chopped off signatures with the name
155.791 + kind = QuerySupport.Kind.PREFIX;
155.792 + }
155.793 +
155.794 + String searchUrl = null;
155.795 + if (context != null) {
155.796 + searchUrl = context.getSnapshot().getSource().getFileObject().toURL().toExternalForm();
155.797 + }
155.798 +
155.799 + String[] terms = { PythonIndexer.FIELD_ITEM,
155.800 + PythonIndexer.FIELD_MODULE_NAME };
155.801 +
155.802 + search(field, name, kind, result, terms);
155.803 +
155.804 + final Set<IndexedElement> elements = new HashSet<>();
155.805 + int nameLength = name.length();
155.806 +
155.807 + for (IndexResult map : result) {
155.808 + String[] signatures = map.getValues(PythonIndexer.FIELD_ITEM);
155.809 + if (signatures != null && signatures.length > 0) {
155.810 + String url = map.getUrl().toExternalForm();
155.811 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
155.812 + boolean inherited = searchUrl == null || !searchUrl.equals(url);
155.813 +
155.814 + for (String signature : signatures) {
155.815 + if (originalKind == QuerySupport.Kind.EXACT) {
155.816 + if (signature.charAt(nameLength) != ';') {
155.817 + continue;
155.818 + }
155.819 + } else if (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, name, 0, name.length())) {
155.820 + continue;
155.821 + } else {
155.822 + // REGEXP, CAMELCASE filtering etc. not supported here
155.823 + assert (originalKind == QuerySupport.Kind.PREFIX) ||
155.824 + (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
155.825 + }
155.826 +
155.827 + IndexedElement element = IndexedElement.create(signature, module, url, null);
155.828 + if (element.isPrivate() && !url.equals(searchUrl)) {
155.829 + continue;
155.830 + }
155.831 + element.setInherited(inherited);
155.832 + elements.add(element);
155.833 + }
155.834 + }
155.835 + }
155.836 +
155.837 + return elements;
155.838 + }
155.839 +
155.840 + public Set<String> getBuiltinSymbols() {
155.841 + Set<String> modules = new HashSet<>();
155.842 +
155.843 + // The "functions" module is always imported by the interpreter, and ditto
155.844 + // for exceptions, constants, etc.
155.845 + //modules.add("objects"); // NOI18N -- just links to the others
155.846 + modules.addAll(BUILTIN_MODULES);
155.847 +
155.848 + Set<String> symbols = new HashSet<>(250);
155.849 +
155.850 + String[] terms = { PythonIndexer.FIELD_MODULE_NAME,
155.851 + PythonIndexer.FIELD_ITEM };
155.852 +
155.853 + // Look up all symbols
155.854 + for (String module : modules) {
155.855 + final Set<IndexResult> result = new HashSet<>();
155.856 + // TODO - handle case sensitivity better...
155.857 + String field = PythonIndexer.FIELD_MODULE_NAME;
155.858 + QuerySupport.Kind kind = QuerySupport.Kind.EXACT;
155.859 +
155.860 + search(field, module, kind, result, terms);
155.861 +
155.862 + for (IndexResult map : result) {
155.863 + String[] signatures = map.getValues(PythonIndexer.FIELD_ITEM);
155.864 + if (signatures != null) {
155.865 + for (String signature : signatures) {
155.866 + int semi = signature.indexOf(';');
155.867 + assert semi != -1;
155.868 + int flags = IndexedElement.decode(signature, semi + 3, 0);
155.869 + if ((flags & IndexedElement.PRIVATE) != 0) {
155.870 + // Skip private symbols - can't import those
155.871 + continue;
155.872 + }
155.873 + String name = signature.substring(0, semi);
155.874 + symbols.add(name);
155.875 + }
155.876 + }
155.877 + }
155.878 + }
155.879 +
155.880 + // Computed as described below
155.881 + String[] MISSING = {
155.882 + "Ellipsis", "False", "IndentationError", "None", "NotImplemented", "TabError", // NOI18N
155.883 + "True", "__debug__", "__doc__", "__name__", "copyright", "credits", "exit", "license", // NOI18N
155.884 + "quit" // NOI18N
155.885 + };
155.886 + for (String s : MISSING) {
155.887 + symbols.add(s);
155.888 + }
155.889 + symbols.add("__builtins__"); // NOI18N
155.890 + symbols.add("__file__"); // NOI18N
155.891 +
155.892 + //// COMPUTING MISSING SYMBOLS:
155.893 + //// My builtin .rst files don't seem to define all the builtin symbols that the Python
155.894 + //// interpreter is configured with. I generated these pretty trivially; run
155.895 + //// python and type "dir(__builtins__)" and you end up a list like the below:
155.896 + ////String[] EXTRA_BUILTINS = {"ArithmeticError", "AssertionError", "AttributeError", "BaseException",
155.897 + // "DeprecationWarning", "EOFError", "Ellipsis", "EnvironmentError", "Exception", "False",
155.898 + // "FloatingPointError", "FutureWarning", "GeneratorExit", "IOError", "ImportError",
155.899 + // "ImportWarning", "IndentationError", "IndexError", "KeyError", "KeyboardInterrupt",
155.900 + // "LookupError", "MemoryError", "NameError", "None", "NotImplemented", "NotImplementedError",
155.901 + // "OSError", "OverflowError", "PendingDeprecationWarning", "ReferenceError", "RuntimeError",
155.902 + // "RuntimeWarning", "StandardError", "StopIteration", "SyntaxError", "SyntaxWarning", "SystemError",
155.903 + // "SystemExit", "TabError", "True", "TypeError", "UnboundLocalError", "UnicodeDecodeError",
155.904 + // "UnicodeEncodeError", "UnicodeError", "UnicodeTranslateError", "UnicodeWarning", "UserWarning",
155.905 + // "ValueError", "Warning", "ZeroDivisionError", "__debug__", "__doc__", "__import__", "__name__",
155.906 + // "abs", "all", "any", "apply", "basestring", "bool", "buffer", "callable", "chr", "classmethod",
155.907 + // "cmp", "coerce", "compile", "complex", "copyright", "credits", "delattr", "dict", "dir", "divmod",
155.908 + // "enumerate", "eval", "execfile", "exit", "file", "filter", "float", "frozenset", "getattr",
155.909 + // "globals", "hasattr", "hash", "help", "hex", "id", "input", "int", "intern", "isinstance",
155.910 + // "issubclass", "iter", "len", "license", "list", "locals", "long", "map", "max", "min", "object",
155.911 + // "oct", "open", "ord", "pow", "property", "quit", "range", "raw_input", "reduce", "reload",
155.912 + // "repr", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum",
155.913 + // "super", "tuple", "type", "unichr", "unicode", "vars", "xrange", "zip"};
155.914 + //// Most of these will be defined by my index search. However, for the missing ones, let's add them
155.915 + //// in. The following code computes the delta and produces a source-like string for it.
155.916 + //// It also counts the total symbol map size so we can pick a reasonable default:
155.917 + //List<String> asList = Arrays.asList(EXTRA_BUILTINS);
155.918 + //Set<String> asSet = new HashSet<String>(asList);
155.919 + //asSet.removeAll(symbols);
155.920 + //List<String> missing = new ArrayList<String>(asSet);
155.921 + //Collections.sort(missing);
155.922 + //int width = 0;
155.923 + //StringBuilder sb = new StringBuilder();
155.924 + //for (String s : missing) {
155.925 + // sb.append('"');
155.926 + // sb.append(s);
155.927 + // sb.append('"');
155.928 + // sb.append(',');
155.929 + // sb.append(' ');
155.930 + // width += s.length()+4;
155.931 + // if (width > 70) {
155.932 + // sb.append("\n");
155.933 + // width = 0;
155.934 + // }
155.935 + //}
155.936 + //String missingCode = "String[] MISSING = {\n" + sb.toString() + "\n};\n";
155.937 + //symbols.addAll(asList);
155.938 + //int requiredSetSize = symbols.size();
155.939 +
155.940 + return symbols;
155.941 + }
155.942 +
155.943 + @SuppressWarnings("unchecked")
155.944 + public Set<String> getImportsFor(String ident, boolean includeSymbol) {
155.945 + Set<String> modules = new HashSet<>(10);
155.946 +
155.947 + final Set<IndexResult> result = new HashSet<>();
155.948 + search(PythonIndexer.FIELD_MODULE_NAME, ident, QuerySupport.Kind.EXACT, result, PythonIndexer.FIELD_MODULE_NAME);
155.949 + for (IndexResult map : result) {
155.950 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
155.951 + if (module != null) {
155.952 + // TODO - record more information about this, such as the FQN
155.953 + // so it's easier for the user to disambiguate
155.954 + modules.add(module);
155.955 + }
155.956 + }
155.957 +
155.958 + // TODO - handle case sensitivity better...
155.959 + String field = PythonIndexer.FIELD_ITEM;
155.960 + QuerySupport.Kind kind = QuerySupport.Kind.PREFIX; // We're storing encoded signatures so not exact matches
155.961 +
155.962 + String[] terms = { PythonIndexer.FIELD_ITEM,
155.963 + PythonIndexer.FIELD_MODULE_NAME };
155.964 +
155.965 + result.clear();
155.966 + search(field, ident, kind, result, terms);
155.967 + String match = ident + ";";
155.968 +
155.969 + MapSearch:
155.970 + for (IndexResult map : result) {
155.971 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
155.972 + if (module == null) {
155.973 + continue;
155.974 + }
155.975 +
155.976 + if (module.indexOf('-') != -1) {
155.977 + // Don't include modules with -; these aren't real module
155.978 + // names (usually python scripts in directories containing a dash
155.979 + // that I incorrectly compute a module name for
155.980 + continue;
155.981 + }
155.982 +
155.983 + String[] members = map.getValues(PythonIndexer.FIELD_ITEM);
155.984 + if (members == null || members.length == 0) {
155.985 + continue;
155.986 + }
155.987 +
155.988 + int semi = match.length() - 1;
155.989 +
155.990 + for (String signature : members) {
155.991 + if (signature.startsWith(match)) {
155.992 + if (includeSymbol) {
155.993 + int flags = IndexedElement.decode(signature, semi + 3, 0);
155.994 + if ((flags & IndexedElement.PRIVATE) != 0) {
155.995 + // Skip private symbols - can't import those
155.996 + continue;
155.997 + }
155.998 + String sig = ident;
155.999 + char type = signature.charAt(semi + 1);
155.1000 + if (type == 'F') {
155.1001 + int sigStart = signature.indexOf(';', semi + 3) + 1;
155.1002 + int sigEnd = signature.indexOf(';', sigStart);
155.1003 + sig = ident + "(" + signature.substring(sigStart, sigEnd) + ")"; // NOI18N
155.1004 + } else if (type == 'I') {
155.1005 + // Don't provide modules that just -import- the symbol
155.1006 + continue;
155.1007 + }
155.1008 + if (!sig.equals(module)) {
155.1009 + modules.add(module + ": " + sig); // NOI18N
155.1010 + } else {
155.1011 + modules.add(module);
155.1012 + }
155.1013 + } else {
155.1014 + modules.add(module);
155.1015 + }
155.1016 + continue MapSearch;
155.1017 + }
155.1018 + }
155.1019 + }
155.1020 +
155.1021 + return modules;
155.1022 + }
155.1023 +
155.1024 + public Set<IndexedElement> getImportedElements(String prefix, QuerySupport.Kind kind, PythonParserResult context, List<Import> imports, List<ImportFrom> importsFrom) {
155.1025 + // TODO - separate methods from variables?? E.g. if you have method Foo() and class Foo
155.1026 + // coming from different places
155.1027 +
155.1028 +
155.1029 +// Set<String> imported = new HashSet<String>();
155.1030 +//
155.1031 + Set<IndexedElement> elements = new HashSet<>();
155.1032 +
155.1033 + // Look up the imports and compute all the symbols we get from the import
155.1034 + Set<String> modules = new HashSet<>();
155.1035 +
155.1036 + // ImportsFrom require no index lookup
155.1037 + for (ImportFrom from : importsFrom) {
155.1038 + if (ImportManager.isFutureImport(from)) {
155.1039 + continue;
155.1040 + }
155.1041 + List<alias> names = from.getInternalNames();
155.1042 + if (names != null) {
155.1043 + for (alias at : names) {
155.1044 + if ("*".equals(at.getInternalName())) { // NOI18N
155.1045 + modules.add(from.getInternalModule());
155.1046 +// } else {
155.1047 +// String name = at.getInternalAsname() != null ? at.getInternalAsname() : at.getInternalName();
155.1048 +// assert name.length() > 0;
155.1049 +// imported.add(name);
155.1050 + }
155.1051 + }
155.1052 + }
155.1053 + }
155.1054 +
155.1055 +// for (Import imp : imports) {
155.1056 +// if (imp.names != null) {
155.1057 +// for (alias at : imp.getInternalNames()) {
155.1058 +// if (at.getInternalAsname() != null) {
155.1059 +// String name = at.getInternalAsname();
155.1060 +// assert name.length() > 0;
155.1061 +// imported.add(name);
155.1062 +// } else {
155.1063 +// imported.add(at.getInternalName());
155.1064 +// }
155.1065 +// }
155.1066 +// }
155.1067 +// }
155.1068 +//
155.1069 +//
155.1070 +// // Create variable items for the locally imported symbols
155.1071 +// for (String name : imported) {
155.1072 +// if (name.startsWith(prefix)) {
155.1073 +// if (kind == QuerySupport.Kind.EXACT) {
155.1074 +// // Ensure that the method is not longer than the prefix
155.1075 +// if ((name.length() > prefix.length()) &&
155.1076 +// (name.charAt(prefix.length()) != '(') &&
155.1077 +// (name.charAt(prefix.length()) != ';')) {
155.1078 +// continue;
155.1079 +// }
155.1080 +// } else {
155.1081 +// // REGEXP, CAMELCASE filtering etc. not supported here
155.1082 +// assert (kind == QuerySupport.Kind.PREFIX) ||
155.1083 +// (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
155.1084 +// }
155.1085 +// String url = null;
155.1086 +// ElementKind elementKind = ElementKind.VARIABLE;
155.1087 +// if (Character.isUpperCase(name.charAt(0))) {
155.1088 +// // Class?
155.1089 +// elementKind = ElementKind.CLASS;
155.1090 +// }
155.1091 +// IndexedElement element = new IndexedElement(name, elementKind, url, null);
155.1092 +// element.setSmart(true);
155.1093 +// elements.add(element);
155.1094 +// // TODO - imported class symbls should be shown as classes!
155.1095 +// }
155.1096 +// }
155.1097 +
155.1098 + // Always include the current file as imported
155.1099 + String moduleName = null;
155.1100 + if (context != null) {
155.1101 + moduleName = PythonUtils.getModuleName(context.getSnapshot().getSource().getFileObject());
155.1102 + modules.add(moduleName);
155.1103 + }
155.1104 +
155.1105 + modules.addAll(BUILTIN_MODULES);
155.1106 +
155.1107 + addImportedElements(prefix, kind, modules, elements, null);
155.1108 +
155.1109 + return elements;
155.1110 + }
155.1111 + public Set<String> getImportedFromWildcards(List<ImportFrom> importsFrom) {
155.1112 + Set<String> symbols = new HashSet<>(100);
155.1113 +
155.1114 + // Look up the imports and compute all the symbols we get from the import
155.1115 + Set<String> modules = new HashSet<>();
155.1116 +
155.1117 + // ImportsFrom require no index lookup
155.1118 + for (ImportFrom from : importsFrom) {
155.1119 + List<alias> names = from.getInternalNames();
155.1120 + if (names != null) {
155.1121 + for (alias at : names) {
155.1122 + if ("*".equals(at.getInternalName())) { // NOI18N
155.1123 + modules.add(from.getInternalModule());
155.1124 + }
155.1125 + }
155.1126 + }
155.1127 + }
155.1128 +
155.1129 + String[] terms = { PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MODULE_NAME };
155.1130 +
155.1131 + // Look up all symbols
155.1132 + for (String module : modules) {
155.1133 + // TODO - cache builtins?
155.1134 + Set<String> moduleSymbols = symbols;
155.1135 + boolean isSystem = isSystemModule(module);
155.1136 + if (isSystem) {
155.1137 + Set<String> s = wildcardImports.get(module);
155.1138 + if (s != null) {
155.1139 + symbols.addAll(s);
155.1140 + continue;
155.1141 + } else {
155.1142 + moduleSymbols = new HashSet<>(100);
155.1143 + }
155.1144 + }
155.1145 +
155.1146 +
155.1147 + final Set<IndexResult> result = new HashSet<>();
155.1148 + // TODO - handle case sensitivity better...
155.1149 +
155.1150 + search(PythonIndexer.FIELD_MODULE_NAME, module, QuerySupport.Kind.EXACT, result, terms);
155.1151 +
155.1152 + for (IndexResult map : result) {
155.1153 + String[] items = map.getValues(PythonIndexer.FIELD_ITEM);
155.1154 + if (items != null) {
155.1155 + for (String signature : items) {
155.1156 + int semi = signature.indexOf(';');
155.1157 + assert semi != -1;
155.1158 + int flags = IndexedElement.decode(signature, semi + 3, 0);
155.1159 + if ((flags & IndexedElement.PRIVATE) != 0) {
155.1160 + // Skip private symbols - can't import those
155.1161 + continue;
155.1162 + }
155.1163 +
155.1164 + String name = signature.substring(0, semi);
155.1165 + moduleSymbols.add(name);
155.1166 + }
155.1167 + }
155.1168 + }
155.1169 +
155.1170 + if (isSystem) {
155.1171 + assert moduleSymbols != symbols;
155.1172 + symbols.addAll(moduleSymbols);
155.1173 + wildcardImports.put(module, moduleSymbols);
155.1174 + }
155.1175 + }
155.1176 +
155.1177 + return symbols;
155.1178 + }
155.1179 +
155.1180 + public Set<IndexedElement> getImportedElements(String prefix, QuerySupport.Kind kind, Set<String> modules, Set<String> systemModuleHolder) {
155.1181 + Set<IndexedElement> elements = new HashSet<>();
155.1182 +
155.1183 + addImportedElements(prefix, kind, modules, elements, systemModuleHolder);
155.1184 +
155.1185 + return elements;
155.1186 + }
155.1187 +
155.1188 + public boolean isSystemModule(String module) {
155.1189 + if (systemModules == null) {
155.1190 + systemModules = new HashSet<>(800); // measured: 623
155.1191 + String[] terms = { PythonIndexer.FIELD_MODULE_ATTR_NAME,
155.1192 + PythonIndexer.FIELD_MODULE_NAME };
155.1193 + final Set<IndexResult> result = new HashSet<>();
155.1194 +
155.1195 + // This doesn't work because the attrs field isn't searchable:
155.1196 + //search(PythonIndexer.FIELD_MODULE_ATTR_NAME, "S", QuerySupport.Kind.PREFIX, result, ALL_SCOPE, terms);
155.1197 + //for (IndexResult map : result) {
155.1198 + // assert map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME).indexOf("S") != -1;
155.1199 + // systemModules.add(map.getValue(PythonIndexer.FIELD_MODULE_NAME));
155.1200 + //}
155.1201 +
155.1202 + search(PythonIndexer.FIELD_MODULE_NAME, "", QuerySupport.Kind.PREFIX, result, terms);
155.1203 +
155.1204 + for (IndexResult map : result) {
155.1205 + String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
155.1206 + if (attrs != null && attrs.indexOf('S') != -1) {
155.1207 + String mod = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
155.1208 + systemModules.add(mod);
155.1209 + }
155.1210 + }
155.1211 + }
155.1212 +
155.1213 + return systemModules.contains(module);
155.1214 + }
155.1215 +
155.1216 + public boolean isLowercaseClassName(String clz) {
155.1217 + if (availableClasses == null) {
155.1218 + availableClasses = new HashSet<>(300); // measured: 193
155.1219 + final Set<IndexResult> result = new HashSet<>();
155.1220 +
155.1221 + search(PythonIndexer.FIELD_CLASS_NAME, "", QuerySupport.Kind.PREFIX, result, PythonIndexer.FIELD_CLASS_NAME);
155.1222 +
155.1223 + for (IndexResult map : result) {
155.1224 + String c = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.1225 + if (c != null && !Character.isUpperCase(c.charAt(0))) {
155.1226 + availableClasses.add(c);
155.1227 + }
155.1228 + }
155.1229 + }
155.1230 +
155.1231 + return availableClasses.contains(clz);
155.1232 + }
155.1233 +
155.1234 + public void addImportedElements(String prefix, QuerySupport.Kind kind, Set<String> modules, Set<IndexedElement> elements, Set<String> systemModuleHolder) {
155.1235 +
155.1236 + String[] terms = { PythonIndexer.FIELD_ITEM,
155.1237 + PythonIndexer.FIELD_MODULE_ATTR_NAME,
155.1238 + PythonIndexer.FIELD_MODULE_NAME };
155.1239 +
155.1240 + // Look up all symbols
155.1241 + for (String module : modules) {
155.1242 + boolean isBuiltin = isBuiltinModule(module);
155.1243 + boolean isSystem = isBuiltin;
155.1244 +
155.1245 + final Set<IndexResult> result = new HashSet<>();
155.1246 + // TODO - handle case sensitivity better...
155.1247 +
155.1248 + search(PythonIndexer.FIELD_MODULE_NAME, module, QuerySupport.Kind.EXACT, result, terms);
155.1249 + int prefixLength = prefix.length();
155.1250 +
155.1251 + for (IndexResult map : result) {
155.1252 + String url = map.getUrl().toExternalForm();
155.1253 + String[] items = map.getValues(PythonIndexer.FIELD_ITEM);
155.1254 + if (items != null) {
155.1255 + String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
155.1256 + if (attrs != null && attrs.indexOf('S') != -1) {
155.1257 + isSystem = true;
155.1258 + }
155.1259 + for (String signature : items) {
155.1260 + if (signature.startsWith(prefix)) {
155.1261 + if (kind == QuerySupport.Kind.EXACT) {
155.1262 + if (signature.charAt(prefixLength) != ';') {
155.1263 + continue;
155.1264 + }
155.1265 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, prefix, 0, prefix.length())) {
155.1266 + continue;
155.1267 + } else {
155.1268 + // REGEXP, CAMELCASE filtering etc. not supported here
155.1269 + assert (kind == QuerySupport.Kind.PREFIX) ||
155.1270 + (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
155.1271 + }
155.1272 +
155.1273 + IndexedElement element = IndexedElement.create(signature, module, url, null);
155.1274 + if (element.isPrivate()) {
155.1275 + continue;
155.1276 + }
155.1277 + if (isBuiltin) {
155.1278 + element.setRhs("<i>builtin</i>");
155.1279 + } else {
155.1280 + element.setSmart(true);
155.1281 + }
155.1282 + element.setInherited(true);
155.1283 + elements.add(element);
155.1284 + }
155.1285 + }
155.1286 + }
155.1287 + }
155.1288 +
155.1289 + if (systemModuleHolder != null && isSystem) {
155.1290 + systemModuleHolder.add(module);
155.1291 + }
155.1292 + }
155.1293 + }
155.1294 +
155.1295 + public Set<IndexedElement> getExceptions(String prefix, QuerySupport.Kind kind) {
155.1296 + final Set<IndexResult> result = new HashSet<>();
155.1297 + String[] terms = { PythonIndexer.FIELD_EXTENDS_NAME,
155.1298 + PythonIndexer.FIELD_CLASS_NAME,
155.1299 + PythonIndexer.FIELD_CLASS_ATTR_NAME,
155.1300 + PythonIndexer.FIELD_IN };
155.1301 + search(PythonIndexer.FIELD_EXTENDS_NAME, "", QuerySupport.Kind.PREFIX, result, terms); // NOI18N
155.1302 + Map<String, String> extendsMap = new HashMap<>(100);
155.1303 + // First iteration: Compute inheritance hierarchy
155.1304 + for (IndexResult map : result) {
155.1305 +
155.1306 + String superClass = map.getValue(PythonIndexer.FIELD_EXTENDS_NAME);
155.1307 + if (superClass != null) {
155.1308 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.1309 + if (clz != null) {
155.1310 + extendsMap.put(clz, superClass);
155.1311 + }
155.1312 + }
155.1313 + }
155.1314 +
155.1315 + // Compute set of classes that extend Exception
155.1316 +
155.1317 + Set<String> exceptionClasses = new HashSet<>();
155.1318 + Set<String> notExceptionClasses = new HashSet<>();
155.1319 + exceptionClasses.add("Exception"); // NOI18N
155.1320 + Outer:
155.1321 + for (String cls : extendsMap.keySet()) {
155.1322 + if (notExceptionClasses.contains(cls)) {
155.1323 + continue;
155.1324 + } else if (!exceptionClasses.contains(cls)) {
155.1325 + // See if this extends exception:
155.1326 + String c = cls;
155.1327 + int depth = 0;
155.1328 + while (c != null) {
155.1329 + c = extendsMap.get(c);
155.1330 + String prev = null;
155.1331 + if (c != null) {
155.1332 + if (exceptionClasses.contains(c)) {
155.1333 + exceptionClasses.add(cls);
155.1334 + continue Outer;
155.1335 + }
155.1336 + depth++;
155.1337 + if (depth == 15) {
155.1338 + // we're probably going in circles, perhaps a extends b extends a.
155.1339 + // This doesn't really happen in Python, but can happen when there
155.1340 + // are unrelated classes with the same name getting treated as one here -
155.1341 + // class a in library X, and class a in library Y,
155.1342 + break;
155.1343 + }
155.1344 + } else if (prev != null) {
155.1345 + notExceptionClasses.add(prev);
155.1346 + break;
155.1347 + }
155.1348 + }
155.1349 + notExceptionClasses.add(cls);
155.1350 + }
155.1351 + }
155.1352 +
155.1353 + // Next add elements for all the exceptions
155.1354 + final Set<IndexedElement> classes = new HashSet<>();
155.1355 + for (IndexResult map : result) {
155.1356 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.1357 + if (clz == null || !exceptionClasses.contains(clz)) {
155.1358 + continue;
155.1359 + }
155.1360 +
155.1361 + if ((kind == QuerySupport.Kind.PREFIX) && !clz.startsWith(prefix)) {
155.1362 + continue;
155.1363 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !clz.regionMatches(true, 0, prefix, 0, prefix.length())) {
155.1364 + continue;
155.1365 + } else if (kind == QuerySupport.Kind.EXACT && !clz.equals(prefix)) {
155.1366 + continue;
155.1367 + }
155.1368 +
155.1369 + String url = map.getUrl().toExternalForm();
155.1370 + String module = map.getValue(PythonIndexer.FIELD_IN);
155.1371 + IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
155.1372 + String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
155.1373 + if (attrs != null) {
155.1374 + int flags = IndexedElement.decode(attrs, 0, 0);
155.1375 + element.setFlags(flags);
155.1376 + }
155.1377 + classes.add(element);
155.1378 + }
155.1379 +
155.1380 + return classes;
155.1381 + }
155.1382 +
155.1383 + /** Find the subclasses of the given class name, with the POSSIBLE fqn from the
155.1384 + * context of the usage. */
155.1385 + public Set<IndexedElement> getSubClasses(String fqn, String possibleFqn, String name, boolean directOnly) {
155.1386 + //String field = PythonIndexer.FIELD_FQN_NAME;
155.1387 + Set<IndexedElement> classes = new HashSet<>();
155.1388 + Set<String> scannedClasses = new HashSet<>();
155.1389 + Set<String> seenClasses = new HashSet<>();
155.1390 +
155.1391 + if (fqn != null) {
155.1392 + addSubclasses(fqn, classes, seenClasses, scannedClasses, directOnly);
155.1393 + } else {
155.1394 + fqn = possibleFqn;
155.1395 + if (name.equals(possibleFqn)) {
155.1396 + fqn = null;
155.1397 + }
155.1398 +
155.1399 + // Try looking at the libraries too
155.1400 + while ((classes.size() == 0) && (fqn != null && fqn.length() > 0)) {
155.1401 + // TODO - use the boolvalue from addclasses instead!
155.1402 + boolean found = addSubclasses(fqn + "::" + name, classes, seenClasses, scannedClasses, directOnly);
155.1403 + if (found) {
155.1404 + return classes;
155.1405 + }
155.1406 +
155.1407 + int f = fqn.lastIndexOf("::");
155.1408 +
155.1409 + if (f == -1) {
155.1410 + break;
155.1411 + } else {
155.1412 + fqn = fqn.substring(0, f);
155.1413 + }
155.1414 + }
155.1415 +
155.1416 + if (classes.size() == 0) {
155.1417 + addSubclasses(name, classes, seenClasses, scannedClasses, directOnly);
155.1418 + }
155.1419 + }
155.1420 +
155.1421 + return classes;
155.1422 + }
155.1423 +
155.1424 + private boolean addSubclasses(String classFqn, Set<IndexedElement> classes, Set<String> seenClasses, Set<String> scannedClasses, boolean directOnly) {
155.1425 + // Prevent problems with circular includes or redundant includes
155.1426 + if (scannedClasses.contains(classFqn)) {
155.1427 + return false;
155.1428 + }
155.1429 +
155.1430 + scannedClasses.add(classFqn);
155.1431 +
155.1432 + String searchField = PythonIndexer.FIELD_EXTENDS_NAME;
155.1433 +
155.1434 + Set<IndexResult> result = new HashSet<>();
155.1435 +
155.1436 + String[] terms = { PythonIndexer.FIELD_IN,
155.1437 + PythonIndexer.FIELD_EXTENDS_NAME,
155.1438 + PythonIndexer.FIELD_CLASS_ATTR_NAME,
155.1439 + PythonIndexer.FIELD_CLASS_NAME };
155.1440 +
155.1441 + search(searchField, classFqn, QuerySupport.Kind.EXACT, result, terms);
155.1442 +
155.1443 + boolean foundIt = result.size() > 0;
155.1444 +
155.1445 + // If this is a bogus class entry (no search rsults) don't continue
155.1446 + if (!foundIt) {
155.1447 + return foundIt;
155.1448 + }
155.1449 +
155.1450 + for (IndexResult map : result) {
155.1451 + String className = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
155.1452 + if (className != null && !seenClasses.contains(className)) {
155.1453 + String url = map.getUrl().toExternalForm();
155.1454 + String module = map.getValue(PythonIndexer.FIELD_IN);
155.1455 + IndexedElement clz = new IndexedElement(className, ElementKind.CLASS, url, module, null, null);
155.1456 + String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
155.1457 + if (attrs != null) {
155.1458 + int flags = IndexedElement.decode(attrs, 0, 0);
155.1459 + clz.setFlags(flags);
155.1460 + }
155.1461 + classes.add(clz);
155.1462 +
155.1463 + seenClasses.add(className);
155.1464 +
155.1465 + if (!directOnly) {
155.1466 + addSubclasses(className, classes, seenClasses, scannedClasses, directOnly);
155.1467 + }
155.1468 + }
155.1469 + }
155.1470 +
155.1471 + return foundIt;
155.1472 + }
155.1473 +}
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
156.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndexSearcher.java Mon Sep 21 13:01:16 2015 +0200
156.3 @@ -0,0 +1,252 @@
156.4 +/*
156.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
156.6 + *
156.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
156.8 + *
156.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
156.10 + * Other names may be trademarks of their respective owners.
156.11 + *
156.12 + * The contents of this file are subject to the terms of either the GNU
156.13 + * General Public License Version 2 only ("GPL") or the Common
156.14 + * Development and Distribution License("CDDL") (collectively, the
156.15 + * "License"). You may not use this file except in compliance with the
156.16 + * License. You can obtain a copy of the License at
156.17 + * http://www.netbeans.org/cddl-gplv2.html
156.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
156.19 + * specific language governing permissions and limitations under the
156.20 + * License. When distributing the software, include this License Header
156.21 + * Notice in each file and include the License file at
156.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
156.23 + * particular file as subject to the "Classpath" exception as provided
156.24 + * by Oracle in the GPL Version 2 section of the License file that
156.25 + * accompanied this code. If applicable, add the following below the
156.26 + * License Header, with the fields enclosed by brackets [] replaced by
156.27 + * your own identifying information:
156.28 + * "Portions Copyrighted [year] [name of copyright owner]"
156.29 + *
156.30 + * Contributor(s):
156.31 + *
156.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
156.33 + */
156.34 +package org.netbeans.modules.python.source;
156.35 +
156.36 +import java.awt.Toolkit;
156.37 +import java.util.HashSet;
156.38 +import java.util.Set;
156.39 +import java.util.logging.Logger;
156.40 +import javax.swing.Icon;
156.41 +import org.netbeans.modules.python.source.elements.IndexedElement;
156.42 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
156.43 +import org.netbeans.api.project.FileOwnerQuery;
156.44 +import org.netbeans.api.project.Project;
156.45 +import org.netbeans.api.project.ProjectInformation;
156.46 +import org.netbeans.api.project.ProjectUtils;
156.47 +import org.netbeans.modules.csl.api.ElementHandle;
156.48 +import org.netbeans.modules.csl.api.IndexSearcher;
156.49 +import org.netbeans.modules.csl.api.IndexSearcher.Descriptor;
156.50 +import org.netbeans.modules.csl.api.IndexSearcher.Helper;
156.51 +import org.netbeans.modules.csl.spi.GsfUtilities;
156.52 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
156.53 +import org.openide.filesystems.FileObject;
156.54 +import org.openide.util.ImageUtilities;
156.55 +import org.python.antlr.PythonTree;
156.56 +
156.57 +/**
156.58 + *
156.59 + * @author Tor Norbye
156.60 + */
156.61 +public class PythonIndexSearcher implements IndexSearcher {
156.62 +
156.63 + @Override
156.64 + public Set<? extends Descriptor> getTypes(Project prjct, String textForQuery, QuerySupport.Kind kind, Helper helper) {
156.65 + PythonIndex index = PythonIndex.get(prjct);
156.66 + Set<PythonSymbol> result = new HashSet<>();
156.67 + Set<? extends IndexedElement> elements;
156.68 +
156.69 + // TODO - do some filtering if you use ./#
156.70 + // int dot = textForQuery.lastIndexOf('.');
156.71 + // if (dot != -1 && (kind == QuerySupport.Kind.PREFIX || kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX)) {
156.72 + // String prefix = textForQuery.substring(dot+1);
156.73 + // String in = textForQuery.substring(0, dot);
156.74 +
156.75 + elements = index.getClasses(textForQuery, kind, null, true);
156.76 + for (IndexedElement element : elements) {
156.77 + result.add(new PythonSymbol(element, helper));
156.78 + }
156.79 +
156.80 + return result;
156.81 + }
156.82 +
156.83 + @Override
156.84 + public Set<? extends Descriptor> getSymbols(Project prjct, String textForQuery, QuerySupport.Kind kind, Helper helper) {
156.85 + PythonIndex index = PythonIndex.get(prjct);
156.86 + Set<PythonSymbol> result = new HashSet<>();
156.87 + Set<? extends IndexedElement> elements;
156.88 +
156.89 + // TODO - do some filtering if you use ./#
156.90 + // int dot = textForQuery.lastIndexOf('.');
156.91 + // if (dot != -1 && (kind == QuerySupport.Kind.PREFIX || kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX)) {
156.92 + // String prefix = textForQuery.substring(dot+1);
156.93 + // String in = textForQuery.substring(0, dot);
156.94 +
156.95 + elements = index.getAllMembers(textForQuery, kind, null, true);
156.96 + for (IndexedElement element : elements) {
156.97 + result.add(new PythonSymbol(element, helper));
156.98 + }
156.99 + elements = index.getClasses(textForQuery, kind, null, true);
156.100 + for (IndexedElement element : elements) {
156.101 + result.add(new PythonSymbol(element, helper));
156.102 + }
156.103 + elements = index.getModules(textForQuery, kind);
156.104 + for (IndexedElement element : elements) {
156.105 + result.add(new PythonSymbol(element, helper));
156.106 + }
156.107 +
156.108 + return result;
156.109 + }
156.110 +
156.111 + private class PythonSymbol extends Descriptor {
156.112 + private final IndexedElement element;
156.113 + private String projectName;
156.114 + private Icon projectIcon;
156.115 + private final Helper helper;
156.116 + private boolean isLibrary;
156.117 + private static final String ICON_PATH = "org/netbeans/modules/python/editor/resources/pyc_16.png"; //NOI18N
156.118 +
156.119 + public PythonSymbol(IndexedElement element, Helper helper) {
156.120 + this.element = element;
156.121 + this.helper = helper;
156.122 + }
156.123 +
156.124 + @Override
156.125 + public Icon getIcon() {
156.126 + if (projectName == null) {
156.127 + initProjectInfo();
156.128 + }
156.129 + //if (isLibrary) {
156.130 + // return new ImageIcon(org.openide.util.ImageUtilities.loadImage(PYTHON_KEYWORD));
156.131 + //}
156.132 + return helper.getIcon(element);
156.133 + }
156.134 +
156.135 + @Override
156.136 + public String getTypeName() {
156.137 + return element.getName();
156.138 + }
156.139 +
156.140 + @Override
156.141 + public String getProjectName() {
156.142 + if (projectName == null) {
156.143 + initProjectInfo();
156.144 + }
156.145 + return projectName;
156.146 + }
156.147 +
156.148 + private void initProjectInfo() {
156.149 + FileObject fo = element.getFileObject();
156.150 + if (fo != null) {
156.151 +// File f = FileUtil.toFile(fo);
156.152 + Project p = FileOwnerQuery.getOwner(fo);
156.153 + if (p != null) {
156.154 +// JsPlatform platform = JsPlatform.platformFor(p);
156.155 +// if (platform != null) {
156.156 +// String lib = platform.getLib();
156.157 +// if (lib != null && f.getPath().startsWith(lib)) {
156.158 +// projectName = "Js Library";
156.159 +// isLibrary = true;
156.160 +// }
156.161 +// } else {
156.162 + ProjectInformation pi = ProjectUtils.getInformation(p);
156.163 + projectName = pi.getDisplayName();
156.164 + projectIcon = pi.getIcon();
156.165 +// }
156.166 + }
156.167 + } else {
156.168 + isLibrary = true;
156.169 + Logger.getLogger(PythonIndexSearcher.class.getName()).fine("No fileobject for " + element.toString() + " with fileurl=" + element.getFilenameUrl());
156.170 + }
156.171 + if (projectName == null) {
156.172 + projectName = "";
156.173 + }
156.174 + }
156.175 +
156.176 + @Override
156.177 + public Icon getProjectIcon() {
156.178 + if (projectName == null) {
156.179 + initProjectInfo();
156.180 + }
156.181 + if (isLibrary) {
156.182 + return ImageUtilities.loadImageIcon(ICON_PATH, false);
156.183 + }
156.184 + return projectIcon;
156.185 + }
156.186 +
156.187 + @Override
156.188 + public FileObject getFileObject() {
156.189 + return element.getFileObject();
156.190 + }
156.191 +
156.192 + @Override
156.193 + public void open() {
156.194 + PythonParserResult[] parserResultRet = new PythonParserResult[1];
156.195 + PythonTree node = PythonAstUtils.getForeignNode(element, parserResultRet);
156.196 +
156.197 + if (node != null) {
156.198 + int astOffset = PythonAstUtils.getRange(node).getStart();
156.199 + int lexOffset = PythonLexerUtils.getLexerOffset(parserResultRet[0], astOffset);
156.200 + if (lexOffset == -1) {
156.201 + lexOffset = 0;
156.202 + }
156.203 + GsfUtilities.open(element.getFileObject(), lexOffset, element.getName());
156.204 + return;
156.205 + }
156.206 +
156.207 + FileObject fileObject = element.getFileObject();
156.208 + if (fileObject == null) {
156.209 + // This should no longer be needed - we perform auto deletion in GSF
156.210 + Toolkit.getDefaultToolkit().beep();
156.211 + return;
156.212 + }
156.213 +
156.214 + helper.open(fileObject, element);
156.215 + }
156.216 +
156.217 + @Override
156.218 + public String getContextName() {
156.219 + // XXX This is lame - move formatting logic to the goto action!
156.220 +// StringBuilder sb = new StringBuilder();
156.221 +// String require = element.getRequire();
156.222 +// String fqn = element.getFqn();
156.223 + String fqn = element.getIn() != null ? element.getIn() + "." + element.getName() : element.getName();
156.224 + if (element.getName().equals(fqn)) {
156.225 + fqn = null;
156.226 + String url = element.getFilenameUrl();
156.227 + if (url != null) {
156.228 + return url.substring(url.lastIndexOf('/') + 1);
156.229 + }
156.230 + }
156.231 +
156.232 + return fqn;
156.233 + }
156.234 +
156.235 + @Override
156.236 + public ElementHandle getElement() {
156.237 + return element;
156.238 + }
156.239 +
156.240 + @Override
156.241 + public int getOffset() {
156.242 + throw new UnsupportedOperationException("Not supported yet.");
156.243 + }
156.244 +
156.245 + @Override
156.246 + public String getSimpleName() {
156.247 + return element.getName();
156.248 + }
156.249 +
156.250 + @Override
156.251 + public String getOuterName() {
156.252 + return null;
156.253 + }
156.254 + }
156.255 +}
157.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
157.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndexer.java Mon Sep 21 13:01:16 2015 +0200
157.3 @@ -0,0 +1,1399 @@
157.4 +/*
157.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
157.6 + *
157.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
157.8 + *
157.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
157.10 + * Other names may be trademarks of their respective owners.
157.11 + *
157.12 + * The contents of this file are subject to the terms of either the GNU
157.13 + * General Public License Version 2 only ("GPL") or the Common
157.14 + * Development and Distribution License("CDDL") (collectively, the
157.15 + * "License"). You may not use this file except in compliance with the
157.16 + * License. You can obtain a copy of the License at
157.17 + * http://www.netbeans.org/cddl-gplv2.html
157.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
157.19 + * specific language governing permissions and limitations under the
157.20 + * License. When distributing the software, include this License Header
157.21 + * Notice in each file and include the License file at
157.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
157.23 + * particular file as subject to the "Classpath" exception as provided
157.24 + * by Oracle in the GPL Version 2 section of the License file that
157.25 + * accompanied this code. If applicable, add the following below the
157.26 + * License Header, with the fields enclosed by brackets [] replaced by
157.27 + * your own identifying information:
157.28 + * "Portions Copyrighted [year] [name of copyright owner]"
157.29 + *
157.30 + * Contributor(s):
157.31 + *
157.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
157.33 + */
157.34 +package org.netbeans.modules.python.source;
157.35 +
157.36 +import java.io.File;
157.37 +import java.io.IOException;
157.38 +import java.net.MalformedURLException;
157.39 +import java.net.URL;
157.40 +import java.util.ArrayList;
157.41 +import java.util.Collections;
157.42 +import java.util.HashMap;
157.43 +import java.util.List;
157.44 +import java.util.Map;
157.45 +import java.util.logging.Level;
157.46 +import java.util.logging.Logger;
157.47 +import java.util.regex.Matcher;
157.48 +import java.util.regex.Pattern;
157.49 +import javax.swing.text.BadLocationException;
157.50 +import org.netbeans.editor.BaseDocument;
157.51 +import org.netbeans.modules.csl.spi.GsfUtilities;
157.52 +import org.netbeans.modules.csl.spi.ParserResult;
157.53 +import org.netbeans.modules.parsing.api.Snapshot;
157.54 +import org.netbeans.modules.parsing.spi.Parser;
157.55 +import org.netbeans.modules.parsing.spi.indexing.Context;
157.56 +import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer;
157.57 +import org.netbeans.modules.parsing.spi.indexing.Indexable;
157.58 +import org.netbeans.modules.parsing.spi.indexing.support.IndexDocument;
157.59 +import org.netbeans.modules.parsing.spi.indexing.support.IndexingSupport;
157.60 +import org.netbeans.modules.python.api.PythonPlatform;
157.61 +import org.netbeans.modules.python.api.PythonPlatformManager;
157.62 +import org.netbeans.modules.python.source.elements.IndexedElement;
157.63 +import org.netbeans.modules.python.source.scopes.ScopeConstants;
157.64 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
157.65 +import org.netbeans.modules.python.source.scopes.SymbolTable;
157.66 +import org.netbeans.modules.python.source.scopes.SymInfo;
157.67 +import org.netbeans.modules.python.source.queries.DeprecationQuery;
157.68 +import org.openide.filesystems.FileObject;
157.69 +import org.openide.filesystems.FileUtil;
157.70 +import org.openide.filesystems.URLMapper;
157.71 +import org.openide.util.Exceptions;
157.72 +import org.python.antlr.PythonTree;
157.73 +import org.python.antlr.ast.ClassDef;
157.74 +import org.python.antlr.ast.FunctionDef;
157.75 +import org.python.antlr.ast.Module;
157.76 +import org.python.antlr.ast.Name;
157.77 +import org.python.antlr.base.expr;
157.78 +
157.79 +/**
157.80 + *
157.81 + * @todo Store information about all symbols exported by a module.
157.82 + * I can use that to provide "unused import" help.
157.83 + * @todo Clean this stuff up: store data, functions, etc.
157.84 + * @todo Improve detection of builtins. Perhaps run from within Python,
157.85 + * something like this:
157.86 +>>> dir(__builtins__)
157.87 +['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', 'abs', 'all', 'any', 'apply', 'basestring', 'bool', 'buffer', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
157.88 + *
157.89 + * My code for scanning for functions has to be smarter:
157.90 +.. function:: ljust(s, width)
157.91 +rjust(s, width)
157.92 +center(s, width)
157.93 + * Here I need to pick up all 3 signatures!
157.94 + * @author Tor Norbye
157.95 + */
157.96 +public class PythonIndexer extends EmbeddingIndexer {
157.97 + public static final String NAME = "PythonIndexer";
157.98 + public static final int VERSION = 1;
157.99 + public static boolean PREINDEXING = Boolean.getBoolean("gsf.preindexing"); // NOI18N
157.100 + public static final String FIELD_MEMBER = "member"; //NOI18N
157.101 + public static final String FIELD_MODULE_NAME = "module"; //NOI18N
157.102 + public static final String FIELD_MODULE_ATTR_NAME = "modattrs"; //NOI18N
157.103 + public static final String FIELD_CLASS_ATTR_NAME = "clzattrs"; //NOI18N
157.104 + public static final String FIELD_EXTENDS_NAME = "extends"; //NOI18N
157.105 + public static final String FIELD_ITEM = "item"; //NOI18N
157.106 + public static final String FIELD_IN = "in"; //NOI18N
157.107 + public static final String FIELD_CLASS_NAME = "class"; //NOI18N
157.108 + public static final String FIELD_CASE_INSENSITIVE_CLASS_NAME = "class-ig"; //NOI18N
157.109 + private FileObject prevParent;
157.110 + private boolean prevResult;
157.111 +
157.112 + public static boolean isIndexable(Indexable indexable, Snapshot snapshot) {
157.113 + FileObject fo = snapshot.getSource().getFileObject();
157.114 + String extension = fo.getExt();
157.115 + if ("py".equals(extension)) { // NOI18N
157.116 + return true;
157.117 + }
157.118 +
157.119 + if ("rst".equals(extension)) { // NOI18N
157.120 + // Index restructured text if it looks like it contains Python library
157.121 + // definitions
157.122 + return true;
157.123 + }
157.124 +
157.125 + if ("egg".equals(extension)) { // NOI18N
157.126 + return true;
157.127 + }
157.128 +
157.129 + return false;
157.130 + }
157.131 +
157.132 +
157.133 + public boolean isIndexable(Snapshot file) {
157.134 + FileObject fo = file.getSource().getFileObject();
157.135 + String extension = fo.getExt();
157.136 + if ("py".equals(extension)) { // NOI18N
157.137 +
157.138 + // Skip "test" folders under lib... Lots of weird files there
157.139 + // and we don't want to pollute the index with them
157.140 + FileObject parent = fo.getParent();
157.141 +
157.142 + if (parent != null && parent.getName().equals("test")) { // NOI18N
157.143 + // Make sure it's really a lib folder, we want to include the
157.144 + // user's files
157.145 +
157.146 + // Avoid double-indexing files that have multiple versions - e.g. foo.js and foo-min.js
157.147 + // or foo.uncompressed
157.148 + FileObject parentFo = fo.getParent();
157.149 + if (prevParent == parentFo) {
157.150 + return prevResult;
157.151 + }
157.152 + prevResult = true;
157.153 + prevParent = parentFo;
157.154 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
157.155 + Platforms:
157.156 + for (String name : manager.getPlatformList()) {
157.157 + PythonPlatform platform = manager.getPlatform(name);
157.158 + if (platform != null) {
157.159 + for (FileObject root : platform.getLibraryRoots()) {
157.160 + if (FileUtil.isParentOf(root, parentFo)) {
157.161 + prevResult = false;
157.162 + break Platforms;
157.163 + }
157.164 + }
157.165 + }
157.166 + }
157.167 + }
157.168 +
157.169 + return true;
157.170 + }
157.171 +
157.172 + if ("rst".equals(extension)) { // NOI18N
157.173 + // Index restructured text if it looks like it contains Python library
157.174 + // definitions
157.175 + return true;
157.176 + }
157.177 +
157.178 + if ("egg".equals(extension)) { // NOI18N
157.179 + return true;
157.180 + }
157.181 +
157.182 + return false;
157.183 + }
157.184 +
157.185 + @Override
157.186 + protected void index(Indexable indexable, Parser.Result result, Context context) {
157.187 + PythonParserResult parseResult = (PythonParserResult)result;
157.188 + if (parseResult == null) {
157.189 + return;
157.190 + }
157.191 +
157.192 + IndexingSupport support;
157.193 + try {
157.194 + support = IndexingSupport.getInstance(context);
157.195 + } catch (IOException ioe) {
157.196 + LOG.log(Level.WARNING, null, ioe);
157.197 + return;
157.198 + }
157.199 +
157.200 + support.removeDocuments(indexable);
157.201 +
157.202 + FileObject fileObject = result.getSnapshot().getSource().getFileObject();
157.203 + String extension = fileObject.getNameExt();
157.204 +
157.205 + if (extension.endsWith(".rst")) { // NOI18N
157.206 + scanRst(fileObject, indexable, support, null);
157.207 + } else if (extension.endsWith(".egg")) { // NOI18N
157.208 + scanEgg(fileObject, indexable, parseResult, support);
157.209 + } else {
157.210 + // Normal python file
157.211 + new IndexTask(parseResult, support).scan();
157.212 + }
157.213 + }
157.214 + private static final Logger LOG = Logger.getLogger(PythonIndexer.class.getName());
157.215 +
157.216 + public boolean acceptQueryPath(String url) {
157.217 + return !url.contains("jsstubs"); // NOI18N
157.218 + }
157.219 +
157.220 + public String getPersistentUrl(File file) {
157.221 + String url;
157.222 + try {
157.223 + url = file.toURI().toURL().toExternalForm();
157.224 +
157.225 + // Make relative URLs for urls in the libraries
157.226 + return PythonIndex.getPreindexUrl(url);
157.227 + } catch (MalformedURLException ex) {
157.228 + Exceptions.printStackTrace(ex);
157.229 + return file.getPath();
157.230 + }
157.231 + }
157.232 +
157.233 + public String getIndexVersion() {
157.234 + return "0.123"; // NOI18N
157.235 + }
157.236 +
157.237 + public String getIndexerName() {
157.238 + return "python"; // NOI18N
157.239 + }
157.240 +
157.241 + public FileObject getPreindexedDb() {
157.242 + return null;
157.243 + }
157.244 +
157.245 + private static void appendFlags(StringBuilder sb, char c, SymInfo sym, int flags) {
157.246 + sb.append(';');
157.247 + sb.append(c);
157.248 + sb.append(';');
157.249 +
157.250 + if (sym.isPrivate()) {
157.251 + flags |= IndexedElement.PRIVATE;
157.252 + }
157.253 + if (c == 'c') {
157.254 + flags |= IndexedElement.CONSTRUCTOR;
157.255 + }
157.256 +
157.257 + sb.append(IndexedElement.encode(flags));
157.258 + sb.append(';');
157.259 + }
157.260 + private static final int DEFAULT_DOC_SIZE = 40; // TODO Measure
157.261 +
157.262 + private static class IndexTask {
157.263 + private PythonParserResult result;
157.264 + private FileObject file;
157.265 + private IndexingSupport support;
157.266 + private List<IndexDocument> documents = new ArrayList<>();
157.267 + private String url;
157.268 + private String module;
157.269 + private SymbolTable symbolTable;
157.270 + private String overrideUrl;
157.271 +
157.272 + private IndexTask(PythonParserResult result, IndexingSupport support) {
157.273 + this.result = result;
157.274 + this.file = result.getSnapshot().getSource().getFileObject();
157.275 + this.support = support;
157.276 +
157.277 + module = PythonUtils.getModuleName(file);
157.278 + //PythonTree root = PythonAstUtils.getRoot(result);
157.279 + //if (root instanceof Module) {
157.280 + // Str moduleDoc = PythonAstUtils.getDocumentationNode(root);
157.281 + // if (moduleDoc != null) {
157.282 + // moduleAttributes = "d(" + moduleDoc.getCharStartIndex() + ")";
157.283 + // }
157.284 + //}
157.285 + }
157.286 +
157.287 + private IndexTask(PythonParserResult result, IndexingSupport support, String overrideUrl) {
157.288 + this(result, support);
157.289 + this.overrideUrl = overrideUrl;
157.290 + }
157.291 +
157.292 + public List<IndexDocument> scan() {
157.293 + url = file.toURL().toExternalForm();
157.294 + // Make relative URLs for urls in the libraries
157.295 + url = PythonIndex.getPreindexUrl(url);
157.296 +
157.297 + IndexDocument doc = createDocument();
157.298 + doc.addPair(FIELD_MODULE_NAME, module, true, true);
157.299 +
157.300 + String moduleAttrs = null;
157.301 + if (url.startsWith(PythonIndex.CLUSTER_URL) || url.startsWith(PythonIndex.PYTHONHOME_URL)) {
157.302 + moduleAttrs = "S"; // NOI18N
157.303 + } else if (PREINDEXING) {
157.304 + String prj = System.getProperty("gsf.preindexing.projectpath");
157.305 + if (prj != null && !url.contains(prj)) {
157.306 + System.err.println("WARNING -- not marking url " + url + " from " + file + " as a system library!");
157.307 + }
157.308 + }
157.309 + if (DeprecationQuery.isDeprecatedModule(module)) {
157.310 + if (moduleAttrs == null) {
157.311 + moduleAttrs = "D"; // NOI18N
157.312 + } else {
157.313 + moduleAttrs += "D"; // NOI18N
157.314 + }
157.315 + }
157.316 + if (moduleAttrs != null) {
157.317 + doc.addPair(FIELD_MODULE_ATTR_NAME, moduleAttrs, false, true);
157.318 + }
157.319 +
157.320 + PythonTree root = PythonAstUtils.getRoot(result);
157.321 + if (root == null) {
157.322 + return documents;
157.323 + }
157.324 + if (!(root instanceof Module)) {
157.325 + // Unexpected... http://netbeans.org/bugzilla/show_bug.cgi?id=165756
157.326 + // Maybe some kind of top level error node?
157.327 + System.err.println("WARNING - top level AST node type was " + root + " of type " + root.getClass().getName());
157.328 + return documents;
157.329 + }
157.330 + symbolTable = result.getSymbolTable();
157.331 + ScopeInfo scopeInfo = symbolTable.getScopeInfo(root);
157.332 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
157.333 + String name = entry.getKey();
157.334 + SymInfo sym = entry.getValue();
157.335 +
157.336 + if (sym.isClass()) {
157.337 + StringBuilder sig = new StringBuilder();
157.338 + sig.append(name);
157.339 + appendFlags(sig, 'C', sym, 0);
157.340 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
157.341 +
157.342 + if (sym.node instanceof ClassDef) {
157.343 + assert sym.node instanceof ClassDef : sym.node;
157.344 + indexClass(name, sym, (ClassDef)sym.node);
157.345 + } else {
157.346 + // Could be a symbol defined both as a class and a function
157.347 + // (conditionally) such as _Environ in minicompat.py,
157.348 + // and another trigger in socket.py.
157.349 + }
157.350 + } else if (sym.isFunction()) {
157.351 + if (sym.node instanceof Name) {
157.352 + assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
157.353 + }
157.354 + assert sym.node instanceof FunctionDef : sym.node;
157.355 + FunctionDef def = (FunctionDef)sym.node;
157.356 + String sig = computeFunctionSig(name, def, sym);
157.357 + doc.addPair(FIELD_ITEM, sig, true, true);
157.358 + } else if (sym.isImported()) {
157.359 + if (!"*".equals(name)) { // NOI18N
157.360 + StringBuilder sig = new StringBuilder();
157.361 + sig.append(name);
157.362 + appendFlags(sig, 'I', sym, 0);
157.363 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
157.364 + }
157.365 + } else if (sym.isGeneratorExp()) {
157.366 + StringBuilder sig = new StringBuilder();
157.367 + sig.append(name);
157.368 + appendFlags(sig, 'G', sym, 0);
157.369 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
157.370 + } else if (sym.isData()) {
157.371 + StringBuilder sig = new StringBuilder();
157.372 + sig.append(name);
157.373 + appendFlags(sig, 'D', sym, 0);
157.374 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
157.375 + } else {
157.376 + // XXX what the heck is this??
157.377 + }
157.378 + }
157.379 +
157.380 + return documents;
157.381 + }
157.382 +
157.383 + private void indexClass(String className, SymInfo classSym, ClassDef clz) {
157.384 + IndexDocument classDocument = createDocument();
157.385 + classDocument.addPair(FIELD_IN, module, true, true);
157.386 +
157.387 + // Superclass
157.388 + List<expr> bases = clz.getInternalBases();
157.389 + if (bases != null) {
157.390 + for (expr base : bases) {
157.391 + String extendsName = PythonAstUtils.getExprName(base);
157.392 + if (extendsName != null) {
157.393 + classDocument.addPair(FIELD_EXTENDS_NAME, extendsName, true, true);
157.394 + }
157.395 + }
157.396 + }
157.397 +
157.398 + classDocument.addPair(FIELD_CLASS_NAME, className, true, true);
157.399 +
157.400 + if (classSym.isPrivate()) {
157.401 + // TODO - store Documented, Deprecated, DocOnly, etc.
157.402 + classDocument.addPair(FIELD_CLASS_ATTR_NAME, IndexedElement.encode(IndexedElement.PRIVATE), false, true);
157.403 + }
157.404 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, className.toLowerCase(), true, true);
157.405 +
157.406 + //Str doc = PythonAstUtils.getDocumentationNode(clz);
157.407 + //if (doc != null) {
157.408 + // StringBuilder sb = new StringBuilder();
157.409 + // sb.append("d("); // NOI18N
157.410 + // sb.append(doc.getCharStartIndex());
157.411 + // sb.append(")"); // NOI18N
157.412 + // classDocument.addPair(FIELD_CLASS_ATTRS, sb.toString(), false);
157.413 + //}
157.414 +
157.415 + ScopeInfo scopeInfo = symbolTable.getScopeInfo(clz);
157.416 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
157.417 + String name = entry.getKey();
157.418 + SymInfo sym = entry.getValue();
157.419 +
157.420 +// int flags = sym.flags;
157.421 +// assert !sym.isClass() : "found a class " + name + " of type " + sym.dumpFlags(scopeInfo) + " within class " + className + " in module " + module;
157.422 +// if (!(sym.isFunction() || sym.isMember() || sym.isData())) {
157.423 +// }
157.424 +// assert sym.isFunction() || sym.isMember() || sym.isData() : name + ";" + sym.toString();
157.425 +
157.426 + if (sym.isClass()) {
157.427 + // Triggers in httplib _socket_close inside FakeSocket
157.428 + StringBuilder sig = new StringBuilder();
157.429 + sig.append(name);
157.430 + appendFlags(sig, 'C', sym, 0);
157.431 + classDocument.addPair(FIELD_ITEM, sig.toString(), true, true);
157.432 +
157.433 + } else if (sym.isFunction() && sym.node instanceof FunctionDef) {
157.434 + if (sym.node instanceof Name) {
157.435 + assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
157.436 + }
157.437 + FunctionDef def = (FunctionDef)sym.node;
157.438 + String sig = computeFunctionSig(name, def, sym);
157.439 + classDocument.addPair(FIELD_MEMBER, sig, true, true);
157.440 + } else if (sym.isData()) {
157.441 + StringBuilder sig = new StringBuilder();
157.442 + sig.append(name);
157.443 + appendFlags(sig, 'D', sym, 0);
157.444 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
157.445 + } else if (sym.isMember()) {
157.446 + StringBuilder sig = new StringBuilder();
157.447 + sig.append(name);
157.448 + appendFlags(sig, 'A', sym, 0);
157.449 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
157.450 + } else if (!sym.isBound()) {
157.451 + continue;
157.452 + } else {
157.453 + // XXX what the heck is this??
157.454 + assert false : className + "::" + name + " : " + sym.dumpFlags(scopeInfo);
157.455 + }
157.456 + }
157.457 +
157.458 + if (scopeInfo.attributes.size() > 0) {
157.459 + for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
157.460 + String name = entry.getKey();
157.461 + SymInfo sym = entry.getValue();
157.462 +
157.463 + if (sym.isClass()) {
157.464 + // Triggers in httplib _socket_close inside FakeSocket
157.465 + StringBuilder sig = new StringBuilder();
157.466 + sig.append(name);
157.467 + appendFlags(sig, 'C', sym, 0);
157.468 + classDocument.addPair(FIELD_ITEM, sig.toString(), true, true);
157.469 +
157.470 + } else if (sym.isFunction() && sym.node instanceof FunctionDef) {
157.471 + if (sym.node instanceof Name) {
157.472 + assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
157.473 + }
157.474 + FunctionDef def = (FunctionDef)sym.node;
157.475 + String sig = computeFunctionSig(name, def, sym);
157.476 + classDocument.addPair(FIELD_MEMBER, sig, true, true);
157.477 + } else if (sym.isData()) {
157.478 + StringBuilder sig = new StringBuilder();
157.479 + sig.append(name);
157.480 + appendFlags(sig, 'D', sym, 0);
157.481 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
157.482 + } else if (sym.isMember()) {
157.483 + StringBuilder sig = new StringBuilder();
157.484 + sig.append(name);
157.485 + appendFlags(sig, 'A', sym, 0);
157.486 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
157.487 + } else if (!sym.isBound()) {
157.488 + continue;
157.489 + } else {
157.490 + // XXX what the heck is this??
157.491 + assert false : className + "::" + name + " : " + sym.dumpFlags(scopeInfo);
157.492 + }
157.493 + }
157.494 + }
157.495 + }
157.496 +
157.497 +
157.498 +// TODO - what about nested functions?
157.499 + private IndexDocument createDocument() {
157.500 + IndexDocument doc = support.createDocument(file);
157.501 + documents.add(doc);
157.502 +
157.503 + return doc;
157.504 + }
157.505 + }
157.506 +
157.507 + public static String computeClassSig(ClassDef def, SymInfo sym) {
157.508 + StringBuilder sig = new StringBuilder();
157.509 + sig.append(def.getInternalName());
157.510 + appendFlags(sig, 'C', sym, 0);
157.511 +
157.512 + return sig.toString();
157.513 + }
157.514 +
157.515 + public static String computeFunctionSig(String name, FunctionDef def, SymInfo sym) {
157.516 + StringBuilder sb = new StringBuilder();
157.517 + sb.append(name);
157.518 + char type;
157.519 + int flags = 0;
157.520 + if ("__init__".equals(name)) { // NOI18N
157.521 + type = 'c';
157.522 + } else {
157.523 + type = 'F';
157.524 +
157.525 + List<expr> decorators = def.getInternalDecorator_list();
157.526 + if (decorators != null && decorators.size() > 0) {
157.527 + for (expr decorator : decorators) {
157.528 + String decoratorName = PythonAstUtils.getExprName(decorator);
157.529 + if ("property".equals(decoratorName)) { // NOI18N
157.530 + type = 'A';
157.531 + } else if ("classmethod".equals(decoratorName)) { // NOI18N
157.532 + // Classmethods seem to be used mostly for constructors/inherited factories
157.533 + type = 'c';
157.534 + flags |= IndexedElement.CONSTRUCTOR | IndexedElement.STATIC;
157.535 + } else if ("staticmethod".equals(decoratorName)) { // NOI18N
157.536 + flags |= IndexedElement.STATIC;
157.537 + }
157.538 + }
157.539 + }
157.540 + }
157.541 + appendFlags(sb, type, sym, flags);
157.542 +
157.543 + List<String> params = PythonAstUtils.getParameters(def);
157.544 + boolean first = true;
157.545 + for (String param : params) {
157.546 + if (first) {
157.547 + first = false;
157.548 + } else {
157.549 + sb.append(',');
157.550 + }
157.551 + sb.append(param);
157.552 + }
157.553 + sb.append(';');
157.554 + String sig = sb.toString();
157.555 + return sig;
157.556 + }
157.557 +
157.558 + private String cleanupSignature(String signature) {
157.559 + // Clean up signatures - remove [optional] areas, deal
157.560 + // with arg=Default.Value parameters,
157.561 + // or "literal" or (lit,er,al) default values.
157.562 + // See unit tests for details.
157.563 + boolean lastWasComma = false;
157.564 + StringBuilder sb = new StringBuilder();
157.565 + Loop:
157.566 + for (int i = 0, n = signature.length(); i < n; i++) {
157.567 + char c = signature.charAt(i);
157.568 + switch (c) {
157.569 + case ' ':
157.570 + case '[':
157.571 + case ']':
157.572 + case '\'':
157.573 + case '"':
157.574 + case '.':
157.575 + continue Loop;
157.576 + case '=': {
157.577 + int level = 0;
157.578 + for (i++; i < n; i++) {
157.579 + c = signature.charAt(i);
157.580 + if (c == '(') {
157.581 + level++;
157.582 + } else if (c == ')') {
157.583 + if (level == 0) {
157.584 + break;
157.585 + }
157.586 + level--;
157.587 + }
157.588 + if (c == ',' && level == 0) {
157.589 + break;
157.590 + }
157.591 + }
157.592 + i--; // compensate for loop-increment
157.593 + continue Loop;
157.594 + }
157.595 + case ')':
157.596 + if (lastWasComma) {
157.597 + sb.setLength(sb.length() - 1);
157.598 + lastWasComma = false;
157.599 + }
157.600 + break;
157.601 + case ',':
157.602 + if (lastWasComma) {
157.603 + continue Loop;
157.604 + }
157.605 + lastWasComma = true;
157.606 + break;
157.607 + default:
157.608 + lastWasComma = false;
157.609 + }
157.610 + sb.append(c);
157.611 + }
157.612 +
157.613 + return sb.toString();
157.614 + }
157.615 +
157.616 + /**
157.617 + * Determine if the definition beginning on lines[lineno] is deprecated.
157.618 + */
157.619 + private boolean isDeprecated(String[] lines, int lineno) {
157.620 + int firstIndent = RstFormatter.getIndentation(lines[lineno], 0);
157.621 + for (int i = lineno + 1; i < lines.length; i++) {
157.622 + String line = lines[i];
157.623 + int indent = RstFormatter.getIndentation(line, 0);
157.624 + if (indent == -1) { // empty line
157.625 + continue;
157.626 + }
157.627 + if (line.contains(":deprecated:") || line.contains(".. deprecated::")) { // NOI18N
157.628 + return true;
157.629 + }
157.630 + // Note - we checked for ::deprecated BEFORE bailing on the next
157.631 + // same-indent line, because in some cases, these appear on the same
157.632 + // level as the deprecated element (for exampe, modules)
157.633 + if (indent <= firstIndent) {
157.634 + return false;
157.635 + }
157.636 +
157.637 + // For classes we can have embedded definitions of functions/data/methods --
157.638 + // a deprecated note for these should not be considered a deprecation of
157.639 + // the whole class! See the unit test for bz2.zip for example.
157.640 + if (line.startsWith(".. attribute::", indent) || // NOI18N
157.641 + line.startsWith(".. data::", indent) || // NOI18N
157.642 + line.startsWith(".. function::", indent) || // NOI18N
157.643 + line.startsWith(".. method::", indent)) { // NOI18N
157.644 + return false;
157.645 + }
157.646 + }
157.647 +
157.648 + return false;
157.649 + }
157.650 +
157.651 + private static class CachedIndexDocument {
157.652 + private List<CachedIndexDocumentEntry> entries = new ArrayList<>(DEFAULT_DOC_SIZE);
157.653 +
157.654 + private void addPair(String key, String value, boolean index) {
157.655 + entries.add(new CachedIndexDocumentEntry(key, value, index));
157.656 + }
157.657 + }
157.658 +
157.659 + private static class CachedIndexDocumentEntry {
157.660 + private String key;
157.661 + private String value;
157.662 + private boolean index;
157.663 +
157.664 + public CachedIndexDocumentEntry(String key, String value, boolean index) {
157.665 + this.key = key;
157.666 + this.value = value;
157.667 + this.index = index;
157.668 + }
157.669 + }
157.670 +
157.671 + private List<IndexDocument> scanRst(FileObject fo, Indexable indexable, IndexingSupport support, String overrideUrl) {
157.672 + List<CachedIndexDocument> documents = new ArrayList<>();
157.673 +
157.674 + List<IndexDocument> docs = new ArrayList<>();
157.675 +
157.676 + if (fo != null) {
157.677 + String module = fo.getNameExt();
157.678 + assert module.endsWith(".rst"); // NOI18N
157.679 + module = module.substring(0, module.length() - 4);
157.680 +
157.681 + // Skip files that are already in the standard Python libraries (as .py files).
157.682 + // For these, normal scanning applies
157.683 + // (I should consider checking that they are consistent with the official
157.684 + // documentation, at least during preindexing)
157.685 + if (PREINDEXING) {
157.686 + // XXX This doesn't work right for anything but the builtin Jython interpreter....
157.687 + // OTOH that's the only thing we're preindexing at this point
157.688 + FileObject lib = getLibDir();
157.689 + if (lib != null) {
157.690 + String path = module.replace('.', '/');
157.691 + FileObject py = lib.getFileObject(path); // Look for package dir
157.692 + if (py == null) {
157.693 + py = lib.getFileObject(path + ".py"); // NOI18N
157.694 + }
157.695 + if (py != null) {
157.696 + System.err.println("DELETE " + FileUtil.getFileDisplayName(fo) + " because there is a corresponding " + FileUtil.getFileDisplayName(py)); // NOI18N
157.697 + // No - it's in a zip archive now
157.698 + //try {
157.699 + // // Delete it!
157.700 + // fo.delete();
157.701 + //} catch (IOException ex) {
157.702 + // Exceptions.printStackTrace(ex);
157.703 + //}
157.704 + return Collections.emptyList();
157.705 + }
157.706 + }
157.707 + }
157.708 +
157.709 + String name = fo.getName();
157.710 +
157.711 + // Skip some really obsolete libraries -- IRIX only etc
157.712 + if (name.equals("gl") || name.equals("cd") || // NOI18N
157.713 + name.equals("al") || name.equals("fm") ||
157.714 + name.equals("fl") || name.equals("imgfile") || // NOI18N
157.715 + name.equals("jpeg") || // NOI18N
157.716 + name.equals("sunau") || name.equals("sunaudio")) { // NOI!8N
157.717 + return Collections.emptyList();
157.718 + }
157.719 +
157.720 + Pattern PATTERN = Pattern.compile("\\s*\\.\\.\\s+(.*)::\\s*(.+)\\s*"); // NOI18N
157.721 +
157.722 + BaseDocument doc = GsfUtilities.getDocument(fo, true);
157.723 + if (doc != null) {
157.724 + Map<String, CachedIndexDocument> classDocs = new HashMap<>();
157.725 + CachedIndexDocument document = null;
157.726 + try {
157.727 + String text = doc.getText(0, doc.getLength());
157.728 + String[] lines = text.split("\n");
157.729 + String currentClass = null;
157.730 +
157.731 + for (int lineno = 0, maxLines = lines.length; lineno < maxLines; lineno++) {
157.732 + String line = lines[lineno];
157.733 + if (!line.startsWith(".. ") && !line.contains(" .. ")) { // NOI18N
157.734 + continue;
157.735 + }
157.736 +
157.737 + Matcher m = PATTERN.matcher(line);
157.738 + if (m.matches()) {
157.739 + String key = m.group(1);
157.740 +
157.741 + if (key.equals("attribute") || // NOI18N
157.742 + key.equals("currentmodule") || // NOI18N
157.743 + key.equals("class") || // NOI18N
157.744 + key.equals("exception") || // NOI18N
157.745 + key.equals("function") || // NOI18N
157.746 + key.equals("method") || // NOI18N
157.747 + key.equals("data") || // NOI18N
157.748 + key.equals("module")) { // NOI18N
157.749 +
157.750 +
157.751 + if (key.equals("module") || key.equals("currentmodule")) { // NOI18N
157.752 + // TODO - determine package name
157.753 + module = m.group(2);
157.754 + document = new CachedIndexDocument();
157.755 + documents.add(document);
157.756 + document.addPair(FIELD_MODULE_NAME, module, true);
157.757 + String moduleAttrs = "S";
157.758 + if (isDeprecated(lines, lineno)) {
157.759 + moduleAttrs = "SD";
157.760 + }
157.761 + document.addPair(FIELD_MODULE_ATTR_NAME, moduleAttrs, false); // NOI18N
157.762 + } else {
157.763 + // Methods described in an rst without an actual module definition...
157.764 + if (document == null) {
157.765 + document = new CachedIndexDocument();
157.766 + documents.add(document);
157.767 + document.addPair(FIELD_MODULE_NAME, module, true);
157.768 + document.addPair(FIELD_MODULE_ATTR_NAME, "S", false); // NOI18N
157.769 + }
157.770 + if (key.equals("method") || key.equals("attribute")) { // NOI18N) { // NOI18N
157.771 + String signature = m.group(2);
157.772 +
157.773 + if ("string.template".equals(signature)) { // NOI18N
157.774 + // Wrong - ignore this one (ends up on the String class)
157.775 + continue;
157.776 + }
157.777 + if (signature.startsWith("somenamedtuple.")) {
157.778 + // Ditto
157.779 + continue;
157.780 + }
157.781 + // Error in mailbox.rst - Python 2.6
157.782 + if (".et_folder(folder)".equals(signature)) {
157.783 + signature = "get_folder(folder)";
157.784 + }
157.785 +
157.786 + int dot = signature.indexOf('.');
157.787 + if (dot != -1) {
157.788 + int paren = signature.indexOf('(');
157.789 + if (paren == -1 || paren > dot) {
157.790 + assert signature.matches("\\w+\\.\\w+.*") : signature;
157.791 + String dottedName = signature.substring(0, dot);
157.792 + CachedIndexDocument dottedDoc = classDocs.get(dottedName);
157.793 + if (dottedDoc != null) {
157.794 + currentClass = dottedName;
157.795 + } else /*if (currentClass == null)*/ {
157.796 + currentClass = dottedName;
157.797 + // New class without class:: declaration first.
157.798 + CachedIndexDocument classDocument = new CachedIndexDocument();
157.799 + documents.add(classDocument);
157.800 + classDocs.put(currentClass, classDocument);
157.801 + classDocument.addPair(FIELD_IN, module, true);
157.802 +
157.803 + classDocument.addPair(FIELD_CLASS_NAME, currentClass, true);
157.804 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, currentClass.toLowerCase(), true);
157.805 + }
157.806 + signature = signature.substring(dot + 1);
157.807 + }
157.808 + }
157.809 +
157.810 +
157.811 + CachedIndexDocument classDocument = classDocs.get(currentClass);
157.812 + assert classDocs != null;
157.813 +
157.814 + if (key.equals("method")) {
157.815 + signature = cleanupSignature(signature);
157.816 + if (signature.indexOf('(') == -1) {
157.817 + signature = signature + "()";
157.818 + }
157.819 +
157.820 + assert signature.indexOf('(') != -1 && signature.indexOf(')') != -1 &&
157.821 + signature.indexOf(')') > signature.indexOf('(') : signature;
157.822 + int lparen = signature.indexOf('(');
157.823 + int rparen = signature.indexOf(')', lparen + 1);
157.824 + if (lparen != -1 && rparen != -1) {
157.825 + String methodName = signature.substring(0, lparen);
157.826 + String args = signature.substring(lparen + 1, rparen);
157.827 + char type;
157.828 + if (methodName.equals("__init__")) { // NOI18N
157.829 + type = 'c';
157.830 + } else {
157.831 + type = 'F';
157.832 + }
157.833 + StringBuilder sig = new StringBuilder();
157.834 + sig.append(methodName);
157.835 +
157.836 + int symFlags = 0;
157.837 + if (NameStyle.isPrivateName(methodName)) {
157.838 + symFlags |= ScopeConstants.PRIVATE;
157.839 + }
157.840 + // TODO - look up deprecated etc.
157.841 + SymInfo fakeSym = new SymInfo(symFlags);
157.842 +
157.843 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
157.844 + if (isDeprecated(lines, lineno)) {
157.845 + flags |= IndexedElement.DEPRECATED;
157.846 + }
157.847 +
157.848 + appendFlags(sig, type, fakeSym, flags);
157.849 + sig.append(args);
157.850 + sig.append(';');
157.851 +
157.852 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
157.853 + }
157.854 + } else {
157.855 + assert key.equals("attribute");
157.856 +
157.857 + StringBuilder sig = new StringBuilder();
157.858 + sig.append(signature);
157.859 + int symFlags = 0;
157.860 + if (NameStyle.isPrivateName(signature)) {
157.861 + symFlags |= ScopeConstants.PRIVATE;
157.862 + }
157.863 + // TODO - look up deprecated etc.
157.864 + SymInfo fakeSym = new SymInfo(symFlags);
157.865 +
157.866 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
157.867 + if (isDeprecated(lines, lineno)) {
157.868 + flags |= IndexedElement.DEPRECATED;
157.869 + }
157.870 +
157.871 +
157.872 + appendFlags(sig, 'A', fakeSym, flags);
157.873 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
157.874 + }
157.875 + } else if (key.equals("class") || key.equals("exception")) { // NOI18N
157.876 + assert module != null;
157.877 + String cls = m.group(2);
157.878 +
157.879 + int paren = cls.indexOf('(');
157.880 + String constructor = null;
157.881 + if (paren != -1) {
157.882 + // Some documents specify a constructor here
157.883 + constructor = cleanupSignature(cls);
157.884 + cls = cls.substring(0, paren);
157.885 + }
157.886 + currentClass = cls;
157.887 +
157.888 + CachedIndexDocument classDocument = new CachedIndexDocument();
157.889 + classDocs.put(currentClass, classDocument);
157.890 + documents.add(classDocument);
157.891 + classDocument.addPair(FIELD_IN, module, true);
157.892 +
157.893 + if (key.equals("exception") && !"Exception".equals(cls)) { // NOI18N
157.894 + classDocument.addPair(FIELD_EXTENDS_NAME, "Exception", true); // NOI18N
157.895 + }
157.896 +
157.897 + classDocument.addPair(FIELD_CLASS_NAME, cls, true);
157.898 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY | IndexedElement.CONSTRUCTOR;
157.899 + if (isDeprecated(lines, lineno)) {
157.900 + flags |= IndexedElement.DEPRECATED;
157.901 + }
157.902 + if (flags != 0) {
157.903 + // TODO - store Documented, Deprecated, DocOnly, etc.
157.904 + classDocument.addPair(FIELD_CLASS_ATTR_NAME, IndexedElement.encode(flags), false);
157.905 + }
157.906 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, cls.toLowerCase(), true);
157.907 +
157.908 + // TODO - determine extends
157.909 + //document.addPair(FIELD_EXTENDS_NAME, superClass, true);
157.910 +
157.911 + if (constructor != null) {
157.912 + assert constructor.indexOf('(') != -1 && constructor.indexOf(')') != -1 &&
157.913 + constructor.indexOf(')') > constructor.indexOf('(') : constructor;
157.914 +
157.915 + String signature = constructor;
157.916 + int lparen = signature.indexOf('(');
157.917 + int rparen = signature.indexOf(')', lparen + 1);
157.918 + if (lparen != -1 && rparen != -1) {
157.919 + //String methodName = signature.substring(0, lparen);
157.920 + String methodName = "__init__"; // The constructor is always __init__ !
157.921 + String args = signature.substring(lparen + 1, rparen);
157.922 + StringBuilder sig = new StringBuilder();
157.923 + sig.append(methodName);
157.924 + int symFlags = 0;
157.925 + if (NameStyle.isPrivateName(methodName)) {
157.926 + symFlags |= ScopeConstants.PRIVATE;
157.927 + }
157.928 + // TODO - look up deprecated etc.
157.929 + SymInfo fakeSym = new SymInfo(symFlags);
157.930 +
157.931 + flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY | IndexedElement.CONSTRUCTOR;
157.932 + if (isDeprecated(lines, lineno)) {
157.933 + flags |= IndexedElement.DEPRECATED;
157.934 + }
157.935 +
157.936 + appendFlags(sig, 'c', fakeSym, flags);
157.937 + sig.append(args);
157.938 + sig.append(';');
157.939 +
157.940 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
157.941 + }
157.942 +
157.943 + }
157.944 + } else if (key.equals("function") || (key.equals("data") && m.group(2).contains("("))) { // NOI18N
157.945 + // constants.rst for example registers a data item for "quit" which is really a function
157.946 +
157.947 + String signature = m.group(2);
157.948 + indexRstFunction(signature, lines, lineno, document);
157.949 +
157.950 + // See if we have any additional lines with signatures
157.951 + for (int lookahead = lineno + 1; lookahead < maxLines; lookahead++) {
157.952 + String l = lines[lookahead];
157.953 + String trimmed = l.trim();
157.954 + if (trimmed.length() == 0 || trimmed.startsWith(":")) { // NOI18N
157.955 + break;
157.956 + }
157.957 + lineno++;
157.958 +
157.959 + indexRstFunction(trimmed, lines, lookahead, document);
157.960 + }
157.961 +
157.962 + } else if (key.equals("data")) { // NOI18N
157.963 + String data = m.group(2);
157.964 +
157.965 + StringBuilder sig = new StringBuilder();
157.966 + sig.append(data);
157.967 + int symFlags = 0;
157.968 + if (NameStyle.isPrivateName(data)) {
157.969 + symFlags |= ScopeConstants.PRIVATE;
157.970 + }
157.971 + // TODO - look up deprecated etc.
157.972 + SymInfo fakeSym = new SymInfo(symFlags);
157.973 +
157.974 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
157.975 + if (isDeprecated(lines, lineno)) {
157.976 + flags |= IndexedElement.DEPRECATED;
157.977 + }
157.978 +
157.979 + appendFlags(sig, 'D', fakeSym, flags);
157.980 +
157.981 + document.addPair(FIELD_ITEM, sig.toString(), true);
157.982 + } else {
157.983 + // TODO Handle deprecated attribute!
157.984 +
157.985 + // currentmodule::
157.986 + // deprecated::
157.987 + // doctest::
157.988 + // envvar::
157.989 + // epigraph::
157.990 + // highlight::
157.991 + // highlightlang::
157.992 + // index::
157.993 + // literalinclude::
157.994 + // moduleauthor::
157.995 + // note::
157.996 + // opcode::
157.997 + // productionlist::
157.998 + // rubric::
157.999 + // sectionauthor::
157.1000 + // seealso::
157.1001 + // testcode::
157.1002 + // testsetup::
157.1003 + // toctree::
157.1004 + // versionadded::
157.1005 + // versionchanged::
157.1006 + // warning::
157.1007 + }
157.1008 + }
157.1009 + }
157.1010 + } else if (line.startsWith(".. _bltin-file-objects:") || line.startsWith(".. _string-methods:")) { // NOI18N
157.1011 + if (currentClass != null) {
157.1012 + currentClass = null;
157.1013 + }
157.1014 + }
157.1015 + }
157.1016 +
157.1017 + for (String clz : classDocs.keySet()) {
157.1018 + StringBuilder sig = new StringBuilder();
157.1019 + sig.append(clz);
157.1020 + int symFlags = 0;
157.1021 + if (NameStyle.isPrivateName(clz)) {
157.1022 + symFlags |= ScopeConstants.PRIVATE;
157.1023 + }
157.1024 + // TODO - look up deprecated etc.
157.1025 + SymInfo fakeSym = new SymInfo(symFlags);
157.1026 + appendFlags(sig, 'C', fakeSym, IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY);
157.1027 +
157.1028 + document.addPair(FIELD_ITEM, sig.toString(), true);
157.1029 + }
157.1030 +
157.1031 + } catch (BadLocationException ex) {
157.1032 + Exceptions.printStackTrace(ex);
157.1033 + }
157.1034 +
157.1035 + // Post processing: Add missing attributes not found in the .rst files
157.1036 + // but introspected using dir() in a python console
157.1037 + if (document != null) {
157.1038 + if ("operator".equals(module)) { // Fill in missing operators!
157.1039 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1040 + new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
157.1041 + document, classDocs, "int", documents, module, false, true);
157.1042 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1043 + new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
157.1044 + document, classDocs, "long", documents, module, false, true);
157.1045 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1046 + new String[] { "__abs__", "__add__", "__div__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__pos__", "__pow__", "__sub__", "__truediv__" },
157.1047 + document, classDocs, "float", documents, module, false, true);
157.1048 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1049 + new String[] { "__abs__", "__add__", "__div__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__pos__", "__pow__", "__sub__", "__truediv__" },
157.1050 + document, classDocs, "complex", documents, module, false, true);
157.1051 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1052 + new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
157.1053 + document, classDocs, "bool", documents, module, false, true);
157.1054 +
157.1055 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1056 + new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "index" },
157.1057 + document, classDocs, "str", documents, module, false, true);
157.1058 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1059 + new String[] { "__add__", "__contains__", "__delitem__", "__delslice__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__iadd__", "__imul__", "__le__", "__lt__", "__mul__", "__ne__", "__setitem__", "__setslice__", "index" },
157.1060 + document, classDocs, "list", documents, module, false, true);
157.1061 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1062 + new String[] { "__contains__", "__delitem__", "__eq__", "__ge__", "__getitem__", "__gt__", "__le__", "__lt__", "__ne__", "__setitem__" },
157.1063 + document, classDocs, "dict", documents, module, false, true);
157.1064 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1065 + new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mul__", "__ne__", "index" },
157.1066 + document, classDocs, "tuple", documents, module, false, true);
157.1067 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1068 + new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "index" },
157.1069 + document, classDocs, "unicode", documents, module, false, true);
157.1070 +// } else if ("stdtypes".equals(module)) {
157.1071 +// // Found no definitions for these puppies
157.1072 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1073 +// new String[] { "__class__", "__cmp__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__hex__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__oct__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "denominator", "imag", "numerator", "real" },
157.1074 +// document, classDocs, "int", documents, module, true, false);
157.1075 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1076 +// new String[] { "__class__", "__cmp__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__hex__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__oct__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "denominator", "imag", "numerator", "real" },
157.1077 +// document, classDocs, "long", documents, module, true, false);
157.1078 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1079 +// new String[] { "__class__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getformat__", "__getnewargs__", "__hash__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__radd__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rmod__", "__rmul__", "__rpow__", "__rsub__", "__rtruediv__", "__setattr__", "__setformat__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "imag", "is_integer", "real" },
157.1080 +// document, classDocs, "float", documents, module, true, false);
157.1081 +//
157.1082 +//
157.1083 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1084 +// new String[] { "__class__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__radd__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rmod__", "__rmul__", "__rpow__", "__rsub__", "__rtruediv__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "conjugate", "imag", "real" },
157.1085 +// document, classDocs, "complex", documents, module, true, false);
157.1086 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1087 +// new String[] { "__class__", "__cmp__", "__coerce__", "__delattr__", "__divmod__", "__doc__", "__float__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__hex__", "__init__", "__int__", "__long__", "__new__", "__nonzero__", "__oct__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__trunc__", "conjugate", "denominator", "imag", "numerator", "real" },
157.1088 +// document, classDocs, "bool", documents, module, true, false);
157.1089 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1090 +// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__len__", "__new__", "__repr__", "__rmod__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "_formatter_field_name_split", "_formatter_parser" },
157.1091 +// document, classDocs, "str", documents, module, true, false);
157.1092 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1093 +// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__hash__", "__init__", "__iter__", "__len__", "__new__", "__repr__", "__reversed__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "append", "count", "extend", "insert", "pop", "remove", "reverse", "sort" },
157.1094 +// document, classDocs, "list", documents, module, true, false);
157.1095 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1096 +// new String[] { "__class__", "__cmp__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__hash__", "__iter__", "__len__", "__new__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__" },
157.1097 +// document, classDocs, "dict", documents, module, true, false);
157.1098 +//
157.1099 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1100 +// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__iter__", "__len__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "count" },
157.1101 +// document, classDocs, "tuple", documents, module, true, false);
157.1102 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
157.1103 +// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__len__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__rmod__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "_formatter_field_name_split", "_formatter_parser", "capitalize", "center", "count", "decode", "encode", "endswith", "expandtabs", "find", "format", "isalnum", "isalpha", "isdecimal", "isdigit", "islower", "isnumeric", "isspace", "istitle", "isupper", "join", "ljust", "lower", "lstrip", "partition", "replace", "rfind", "rindex", "rjust", "rpartition", "rsplit", "rstrip", "split", "splitlines", "startswith", "strip", "swapcase", "title", "translate", "upper", "zfill" },
157.1104 +// document, classDocs, "unicode", documents, module, true, false);
157.1105 +//
157.1106 + }
157.1107 + }
157.1108 +
157.1109 + // And convert to a proper GSF search document. I didn't do this directly
157.1110 + // because I want to modify the documents after adding documents and pairs.
157.1111 + for (CachedIndexDocument cid : documents) {
157.1112 + List<CachedIndexDocumentEntry> entries = cid.entries;
157.1113 + IndexDocument indexedDoc = support.createDocument(indexable);
157.1114 +// IndexDocument indexedDoc = support.createDocument(entries.size(), overrideUrl);
157.1115 + docs.add(indexedDoc);
157.1116 + for (CachedIndexDocumentEntry entry : entries) {
157.1117 + indexedDoc.addPair(entry.key, entry.value, true, true); // XXX indexable and stored ???
157.1118 + }
157.1119 + }
157.1120 + }
157.1121 + }
157.1122 +
157.1123 + return docs;
157.1124 + }
157.1125 +
157.1126 + /** Add the given list of names, found in the given document with a given key, and add it
157.1127 + * to the specified class (possibly found in the classDocs list - if not, add one to the
157.1128 + * documents list)
157.1129 + */
157.1130 + private void addMissing(String key, String newKey, String[] names, CachedIndexDocument doc,
157.1131 + Map<String, CachedIndexDocument> classDocs, String clz, List<CachedIndexDocument> documents, String module,
157.1132 + boolean addUnknown, boolean search) {
157.1133 +
157.1134 + CachedIndexDocument classDocument = classDocs.get(clz);
157.1135 + if (classDocument == null) {
157.1136 + // New class without class:: declaration first.
157.1137 + classDocument = new CachedIndexDocument();
157.1138 + documents.add(classDocument);
157.1139 + classDocs.put(clz, classDocument);
157.1140 + classDocument.addPair(FIELD_IN, module, true);
157.1141 +
157.1142 + classDocument.addPair(FIELD_CLASS_NAME, clz, true);
157.1143 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, clz.toLowerCase(), true);
157.1144 + }
157.1145 +
157.1146 + assert classDocument != doc;
157.1147 +
157.1148 + List<String> namesFound = new ArrayList<>();
157.1149 + List<String> namesMissing = new ArrayList<>();
157.1150 + boolean noneFound = true;
157.1151 +
157.1152 + // Look for each of the given functions
157.1153 + Search:
157.1154 + for (String name : names) {
157.1155 + boolean found = false;
157.1156 + if (search) {
157.1157 + int nameLength = name.length();
157.1158 +
157.1159 + // DEBUGGING: Look to make sure I don't already have it in the class doc!
157.1160 + for (CachedIndexDocumentEntry entry : classDocument.entries) {
157.1161 + if (newKey.equals(entry.key)) {
157.1162 + if (entry.value.startsWith(name) &&
157.1163 + (entry.value.length() <= nameLength || entry.value.charAt(nameLength) == ';')) {
157.1164 + // Uh oh - what do I do here?
157.1165 + System.err.println("WARNING: I already have a definition for name " + name + " in class " + clz);
157.1166 + continue Search;
157.1167 + }
157.1168 + }
157.1169 + }
157.1170 +
157.1171 + for (CachedIndexDocumentEntry entry : doc.entries) {
157.1172 + if (key.equals(entry.key)) {
157.1173 + if (entry.value.startsWith(name) &&
157.1174 + (entry.value.length() <= nameLength || entry.value.charAt(nameLength) == ';')) {
157.1175 + // Found it!
157.1176 + classDocument.addPair(newKey, entry.value, entry.index);
157.1177 + found = true;
157.1178 + namesFound.add(name);
157.1179 + break;
157.1180 + }
157.1181 + }
157.1182 + }
157.1183 + }
157.1184 +
157.1185 + if (!found) {
157.1186 + if (addUnknown) {
157.1187 + // TODO - see if I can find a way to extract the signature too!
157.1188 + String args = "";
157.1189 + String signature = name + "()"; //
157.1190 +
157.1191 + assert signature.indexOf('(') != -1 && signature.indexOf(')') != -1 &&
157.1192 + signature.indexOf(')') > signature.indexOf('(') : signature;
157.1193 + char type;
157.1194 + if (name.equals("__init__")) { // NOI18N
157.1195 + type = 'c';
157.1196 + } else {
157.1197 + type = 'F';
157.1198 + }
157.1199 + StringBuilder sig = new StringBuilder();
157.1200 + sig.append(name);
157.1201 +
157.1202 + int symFlags = 0;
157.1203 + if (NameStyle.isPrivateName(name)) {
157.1204 + symFlags |= ScopeConstants.PRIVATE;
157.1205 + }
157.1206 + // TODO - look up deprecated etc.
157.1207 + SymInfo fakeSym = new SymInfo(symFlags);
157.1208 +
157.1209 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
157.1210 + appendFlags(sig, type, fakeSym, flags);
157.1211 + sig.append(args);
157.1212 + sig.append(';');
157.1213 +
157.1214 + classDocument.addPair(newKey, sig.toString(), true);
157.1215 + } else {
157.1216 + namesMissing.add(name);
157.1217 + }
157.1218 + } else {
157.1219 + noneFound = false;
157.1220 + }
157.1221 + }
157.1222 +
157.1223 + if (PREINDEXING) {
157.1224 + if (namesFound.size() > 0) {
157.1225 + StringBuilder sb = new StringBuilder();
157.1226 + sb.append("FOUND for ");
157.1227 + sb.append(clz);
157.1228 + sb.append(" in ");
157.1229 + sb.append(module);
157.1230 + sb.append(": ");
157.1231 + appendList(sb, namesFound);
157.1232 + System.err.println(sb.toString());
157.1233 + }
157.1234 +
157.1235 + if (noneFound && search) {
157.1236 + System.err.println("ERROR: NONE of the passed in names for " + clz + " were found!");
157.1237 + }
157.1238 +
157.1239 + if (namesMissing.size() > 0) {
157.1240 + StringBuilder sb = new StringBuilder();
157.1241 + sb.append("WARNING: Missing these names from ");
157.1242 + sb.append(module);
157.1243 + sb.append(" for use by class ");
157.1244 + sb.append(clz);
157.1245 + sb.append(" : ");
157.1246 + appendList(sb, namesMissing);
157.1247 + System.err.println(sb.toString());
157.1248 + }
157.1249 + }
157.1250 + }
157.1251 +
157.1252 + private static void appendList(StringBuilder sb, List<String> list) {
157.1253 + sb.append("{ ");
157.1254 + boolean first = true;
157.1255 + for (String m : list) {
157.1256 + if (first) {
157.1257 + first = false;
157.1258 + } else {
157.1259 + sb.append(", ");
157.1260 + }
157.1261 + sb.append('"');
157.1262 + sb.append(m);
157.1263 + sb.append('"');
157.1264 + }
157.1265 + sb.append(" }");
157.1266 + }
157.1267 +
157.1268 + private void indexRstFunction(String signature, String[] lines, int lineno, CachedIndexDocument document) {
157.1269 + int dot = signature.indexOf('.');
157.1270 + if (dot != -1) {
157.1271 + int paren = signature.indexOf('(');
157.1272 + if (paren == -1 || paren > dot) {
157.1273 + assert signature.matches("\\w+\\.\\w+.*") : signature; // NOI18N
157.1274 + signature = signature.substring(dot + 1);
157.1275 + }
157.1276 + }
157.1277 + signature = cleanupSignature(signature);
157.1278 + if (signature.indexOf('(') == -1) {
157.1279 + signature = signature + "()"; // NOI18N
157.1280 + } else if (signature.indexOf(')') == -1) {
157.1281 + //signature = signature + ")";
157.1282 + assert signature.indexOf(')') != -1;
157.1283 + }
157.1284 + int lparen = signature.indexOf('(');
157.1285 + int rparen = signature.indexOf(')', lparen + 1);
157.1286 + if (lparen != -1 && rparen != -1) {
157.1287 + String methodName = signature.substring(0, lparen);
157.1288 + String args = signature.substring(lparen + 1, rparen);
157.1289 + StringBuilder sig = new StringBuilder();
157.1290 + sig.append(methodName);
157.1291 + int symFlags = 0;
157.1292 + if (NameStyle.isPrivateName(methodName)) {
157.1293 + symFlags |= ScopeConstants.PRIVATE;
157.1294 + }
157.1295 + // TODO - look up deprecated etc.
157.1296 + SymInfo fakeSym = new SymInfo(symFlags);
157.1297 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
157.1298 + if (isDeprecated(lines, lineno)) {
157.1299 + flags |= IndexedElement.DEPRECATED;
157.1300 + }
157.1301 + appendFlags(sig, 'F', fakeSym, flags);
157.1302 + sig.append(args);
157.1303 + sig.append(';');
157.1304 +
157.1305 + document.addPair(FIELD_ITEM, sig.toString(), true);
157.1306 + }
157.1307 + }
157.1308 +
157.1309 + private List<IndexDocument> scanEgg(FileObject fo, Indexable indexable, ParserResult result, IndexingSupport support) {
157.1310 + List<IndexDocument> documents = new ArrayList<>();
157.1311 +
157.1312 + if (fo == null) {
157.1313 + return documents;
157.1314 + }
157.1315 +
157.1316 + try {
157.1317 + String s = fo.toURL().toExternalForm() + "!"; // NOI18N
157.1318 + URL u = new URL("jar:" + s); // NOI18N
157.1319 + FileObject root = URLMapper.findFileObject(u);
157.1320 + String rootUrl = PythonIndex.getPreindexUrl(u.toExternalForm());
157.1321 + indexScriptDocRecursively(support, documents, root, rootUrl);
157.1322 + } catch (MalformedURLException ex) {
157.1323 + Exceptions.printStackTrace(ex);
157.1324 + }
157.1325 +
157.1326 + return documents;
157.1327 + }
157.1328 +
157.1329 + /**
157.1330 + * Method which recursively indexes directory trees, such as the yui/ folder
157.1331 + * for example
157.1332 + */
157.1333 + private void indexScriptDocRecursively(IndexingSupport support, List<IndexDocument> documents, final FileObject fo, String url) {
157.1334 + if (fo.isFolder()) {
157.1335 + for (FileObject c : fo.getChildren()) {
157.1336 + indexScriptDocRecursively(support, documents, c, url + "/" + c.getNameExt()); // NOI18N
157.1337 + }
157.1338 + return;
157.1339 + }
157.1340 +
157.1341 + String ext = fo.getExt();
157.1342 +
157.1343 +// if ("py".equals(ext)) { // NOI18N
157.1344 +// DefaultParseListener listener = new DefaultParseListener();
157.1345 +// List<ParserFile> files = Collections.<ParserFile>singletonList(new DefaultParserFile(fo, null, false));
157.1346 +// SourceFileReader reader = new SourceFileReader() {
157.1347 +// public CharSequence read(ParserFile file) throws IOException {
157.1348 +// BaseDocument doc = GsfUtilities.getDocument(fo, true);
157.1349 +// if (doc != null) {
157.1350 +// try {
157.1351 +// return doc.getText(0, doc.getLength());
157.1352 +// } catch (BadLocationException ex) {
157.1353 +// Exceptions.printStackTrace(ex);
157.1354 +// }
157.1355 +// }
157.1356 +//
157.1357 +// return "";
157.1358 +// }
157.1359 +//
157.1360 +// public int getCaretOffset(ParserFile file) {
157.1361 +// return -1;
157.1362 +// }
157.1363 +// };
157.1364 +// Job job = new Job(files, listener, reader, null);
157.1365 +// new PythonParser().parseFiles(job);
157.1366 +// ParserResult parserResult = listener.getParserResult();
157.1367 +// if (parserResult != null && parserResult.isValid()) {
157.1368 +// documents.addAll(new IndexTask((PythonParserResult)parserResult, support, url).scan());
157.1369 +// }
157.1370 +// } else if ("rst".equals(ext)) { // NOI18N
157.1371 +// documents.addAll(scanRst(fo, support, url));
157.1372 +// }
157.1373 + }
157.1374 +
157.1375 + private FileObject getLibDir() {
157.1376 + // TODO - fetch from projects!!!!
157.1377 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
157.1378 + PythonPlatform platform = manager.getPlatform(manager.getDefaultPlatform());
157.1379 + if (platform != null) {
157.1380 + String cmd = platform.getInterpreterCommand();
157.1381 + File file = new File(cmd);
157.1382 + if (file.exists()) {
157.1383 + file = file.getAbsoluteFile();
157.1384 + File home = file.getParentFile().getParentFile();
157.1385 + if (home != null) {
157.1386 + // Look for Lib - Jython style
157.1387 + File lib = new File(home, "Lib"); // NOI18N
157.1388 + boolean exists = lib.exists();
157.1389 + if (!exists) { // Unix style
157.1390 + lib = new File(home, "lib" + File.separator + "python"); // NOI18N
157.1391 + exists = lib.exists();
157.1392 + }
157.1393 + if (exists) {
157.1394 + return FileUtil.toFileObject(lib);
157.1395 + }
157.1396 + }
157.1397 + }
157.1398 + }
157.1399 +
157.1400 + return null;
157.1401 + }
157.1402 +}
158.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
158.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndexerFactory.java Mon Sep 21 13:01:16 2015 +0200
158.3 @@ -0,0 +1,47 @@
158.4 +/*
158.5 + * To change this license header, choose License Headers in Project Properties.
158.6 + * To change this template file, choose Tools | Templates
158.7 + * and open the template in the editor.
158.8 + */
158.9 +package org.netbeans.modules.python.source;
158.10 +
158.11 +import org.netbeans.modules.parsing.api.Snapshot;
158.12 +import org.netbeans.modules.parsing.spi.indexing.Context;
158.13 +import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer;
158.14 +import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexerFactory;
158.15 +import org.netbeans.modules.parsing.spi.indexing.Indexable;
158.16 +
158.17 +/**
158.18 + *
158.19 + * @author Ralph Benjamin Ruijs
158.20 + */
158.21 +public class PythonIndexerFactory extends EmbeddingIndexerFactory {
158.22 +
158.23 + @Override
158.24 + public EmbeddingIndexer createIndexer(Indexable indexable, Snapshot snapshot) {
158.25 + if(PythonIndexer.isIndexable(indexable, snapshot)) {
158.26 + return new PythonIndexer();
158.27 + }
158.28 + return null;
158.29 + }
158.30 +
158.31 + @Override
158.32 + public void filesDeleted(Iterable<? extends Indexable> indexables, Context context) {
158.33 +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
158.34 + }
158.35 +
158.36 + @Override
158.37 + public void filesDirty(Iterable<? extends Indexable> arg0, Context arg1) {
158.38 +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
158.39 + }
158.40 +
158.41 + @Override
158.42 + public String getIndexerName() {
158.43 + return PythonIndexer.NAME;
158.44 + }
158.45 +
158.46 + @Override
158.47 + public int getIndexVersion() {
158.48 + return PythonIndexer.VERSION;
158.49 + }
158.50 +}
159.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
159.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonParser.java Mon Sep 21 13:01:16 2015 +0200
159.3 @@ -0,0 +1,760 @@
159.4 +/*
159.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
159.6 + *
159.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
159.8 + *
159.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
159.10 + * Other names may be trademarks of their respective owners.
159.11 + *
159.12 + * The contents of this file are subject to the terms of either the GNU
159.13 + * General Public License Version 2 only ("GPL") or the Common
159.14 + * Development and Distribution License("CDDL") (collectively, the
159.15 + * "License"). You may not use this file except in compliance with the
159.16 + * License. You can obtain a copy of the License at
159.17 + * http://www.netbeans.org/cddl-gplv2.html
159.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
159.19 + * specific language governing permissions and limitations under the
159.20 + * License. When distributing the software, include this License Header
159.21 + * Notice in each file and include the License file at
159.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
159.23 + * particular file as subject to the "Classpath" exception as provided
159.24 + * by Oracle in the GPL Version 2 section of the License file that
159.25 + * accompanied this code. If applicable, add the following below the
159.26 + * License Header, with the fields enclosed by brackets [] replaced by
159.27 + * your own identifying information:
159.28 + * "Portions Copyrighted [year] [name of copyright owner]"
159.29 + *
159.30 + * Contributor(s):
159.31 + *
159.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
159.33 + */
159.34 +package org.netbeans.modules.python.source;
159.35 +
159.36 +import java.io.InputStream;
159.37 +import java.io.InputStreamReader;
159.38 +import java.util.ArrayList;
159.39 +import java.util.List;
159.40 +import java.util.logging.Level;
159.41 +import java.util.logging.Logger;
159.42 +import javax.swing.event.ChangeListener;
159.43 +import javax.swing.text.BadLocationException;
159.44 +import org.netbeans.modules.csl.api.Severity;
159.45 +import org.netbeans.modules.csl.spi.DefaultError;
159.46 +import org.netbeans.modules.csl.api.Error;
159.47 +import org.netbeans.modules.csl.api.OffsetRange;
159.48 +import org.netbeans.modules.csl.spi.GsfUtilities;
159.49 +import org.netbeans.modules.parsing.api.Snapshot;
159.50 +import org.netbeans.modules.parsing.api.Task;
159.51 +import org.netbeans.modules.parsing.spi.Parser;
159.52 +import org.netbeans.modules.parsing.spi.SourceModificationEvent;
159.53 +import org.netbeans.modules.python.api.PythonFileEncodingQuery;
159.54 +import org.openide.filesystems.FileObject;
159.55 +import org.python.antlr.runtime.ANTLRStringStream;
159.56 +import org.python.antlr.runtime.BaseRecognizer;
159.57 +import org.python.antlr.runtime.BitSet;
159.58 +import org.python.antlr.runtime.CommonToken;
159.59 +import org.python.antlr.runtime.CommonTokenStream;
159.60 +import org.python.antlr.runtime.IntStream;
159.61 +import org.python.antlr.runtime.Lexer;
159.62 +import org.python.antlr.runtime.MismatchedTokenException;
159.63 +import org.python.antlr.runtime.RecognitionException;
159.64 +
159.65 +import org.openide.filesystems.FileUtil;
159.66 +import org.openide.util.Exceptions;
159.67 +import org.python.antlr.ListErrorHandler;
159.68 +import org.python.antlr.ParseException;
159.69 +import org.python.antlr.PythonLexer;
159.70 +import org.python.antlr.PythonTokenSource;
159.71 +import org.python.antlr.PythonTree;
159.72 +import org.python.antlr.PythonTreeAdaptor;
159.73 +import org.python.antlr.base.expr;
159.74 +import org.python.antlr.base.mod;
159.75 +import org.python.antlr.base.slice;
159.76 +import org.python.antlr.base.stmt;
159.77 +import org.python.antlr.runtime.ANTLRReaderStream;
159.78 +import org.python.antlr.runtime.CharStream;
159.79 +
159.80 +/**
159.81 + * Parser for Python. Wraps Jython.
159.82 + *
159.83 + * @author Frank Wierzbicki
159.84 + * @author Tor Norbye
159.85 + */
159.86 +public class PythonParser extends Parser {
159.87 + /** For unit tests such that they can make sure we didn't have a parser abort */
159.88 + static Throwable runtimeException;
159.89 +
159.90 + static {
159.91 + org.python.core.PySystemState.initialize();
159.92 + }
159.93 +
159.94 + private Result lastResult;
159.95 + private final PythonFileEncodingQuery fileEncodingQuery = new PythonFileEncodingQuery();
159.96 + private String headerCached = null;
159.97 + private String encodingCache = null;
159.98 +
159.99 + public mod file_input(CharStream charStream, String fileName) throws RecognitionException {
159.100 + ListErrorHandler eh = new ListErrorHandler();
159.101 + mod tree = null;
159.102 + PythonLexer lexer = new PythonLexer(charStream);
159.103 + lexer.setErrorHandler(eh);
159.104 + CommonTokenStream tokens = new CommonTokenStream(lexer);
159.105 + tokens.discardOffChannelTokens(true);
159.106 + PythonTokenSource indentedSource = new PythonTokenSource(tokens, fileName);
159.107 + tokens = new CommonTokenStream(indentedSource);
159.108 + org.python.antlr.PythonParser parser = new org.python.antlr.PythonParser(tokens);
159.109 + parser.setTreeAdaptor(new PythonTreeAdaptor());
159.110 + parser.setErrorHandler(eh);
159.111 + org.python.antlr.PythonParser.file_input_return r = parser.file_input();
159.112 + tree = (mod)r.getTree();
159.113 + return tree;
159.114 + }
159.115 +
159.116 + @Override
159.117 + public void addChangeListener(ChangeListener changeListener) {}
159.118 +
159.119 + @Override
159.120 + public void removeChangeListener(ChangeListener changeListener) {}
159.121 +
159.122 + public PythonTree parse(InputStream istream, String fileName) throws Exception {
159.123 + InputStreamReader reader = new InputStreamReader(istream, "ISO-8859-1");
159.124 + return file_input(new ANTLRReaderStream(reader), fileName);
159.125 + }
159.126 +
159.127 + @Override
159.128 + public final Result getResult(Task task) throws org.netbeans.modules.parsing.spi.ParseException {
159.129 + return lastResult;
159.130 + }
159.131 +
159.132 + private static final Logger LOG = Logger.getLogger(PythonParser.class.getName());
159.133 +
159.134 + @Override
159.135 + public void parse(Snapshot snapshot, Task task, SourceModificationEvent event) throws org.netbeans.modules.parsing.spi.ParseException {
159.136 + Context context = new Context();
159.137 + context.snapshot = snapshot;
159.138 + context.event = event;
159.139 + context.task = task;
159.140 + context.caretOffset = GsfUtilities.getLastKnownCaretOffset(snapshot, event);
159.141 + context.source = snapshot.getText().toString();
159.142 + context.file = snapshot.getSource().getFileObject();
159.143 + if(context.file == null) {
159.144 + return; // TODO: parse the source, not the file
159.145 + }
159.146 + /* Let's not sanitize ;-) Would be great if we could have a more robust parser
159.147 + if (context.caretOffset != -1) {
159.148 + context.sanitized = Sanitize.EDITED_DOT;
159.149 + }
159.150 + */
159.151 + lastResult = parse(context, context.sanitized);
159.152 + }
159.153 + public PythonParserResult parse(final Context context, Sanitize sanitizing) {
159.154 + boolean sanitizedSource = false;
159.155 + String sourceCode = context.source;
159.156 + if (!((sanitizing == Sanitize.NONE) || (sanitizing == Sanitize.NEVER))) {
159.157 + boolean ok = sanitizeSource(context, sanitizing);
159.158 +
159.159 + if (ok) {
159.160 + assert context.sanitizedSource != null;
159.161 + sanitizedSource = true;
159.162 + sourceCode = context.sanitizedSource;
159.163 + } else {
159.164 + // Try next trick
159.165 + return sanitize(context, sanitizing);
159.166 + }
159.167 + }
159.168 + final String source = sourceCode;
159.169 +
159.170 + if (sanitizing == Sanitize.NONE) {
159.171 + context.errorOffset = -1;
159.172 + }
159.173 +
159.174 + final List<Error> errors = new ArrayList<>();
159.175 + final FileObject file = context.file;
159.176 + try {
159.177 + String fileName = file.getNameExt();
159.178 + // TODO - sniff file headers etc. Frank's comment:
159.179 + // Longer term for Python compatibility, having NetBeans sniff the top two lines
159.180 + // for an encoding would be the right thing to do from a pure Python
159.181 + // compatibility standard (see http://www.python.org/dev/peps/pep-0263/) I
159.182 + // have pep-0263 code in Jython that I could probably extract for this
159.183 + // purpose down the road.
159.184 + //String charset = "ISO8859_1"; // NOI18N
159.185 + //String charset = "UTF-8"; // NOI18N
159.186 + //String charset = "iso8859_1"; // NOI18N
159.187 + // TODO: improve this check.
159.188 + int cache_len = sourceCode.length() >= 64 ? 64 : sourceCode.length();
159.189 + if (headerCached == null || cache_len != headerCached.length() || !headerCached.equals(sourceCode.substring(0, cache_len))) {
159.190 + headerCached = sourceCode.substring(0, cache_len);
159.191 + encodingCache = fileEncodingQuery.getPythonFileEncoding(sourceCode.split("\n", 2));
159.192 + }
159.193 + String charset = encodingCache;
159.194 +
159.195 + final boolean ignoreErrors = sanitizedSource;
159.196 + ListErrorHandler errorHandler = new ListErrorHandler() {
159.197 + @Override
159.198 + public void error(String message, PythonTree t) {
159.199 + errors.add(new DefaultError(null, message, null, file, t.getCharStartIndex(), t.getCharStopIndex(), Severity.ERROR));
159.200 + super.error(message, t);
159.201 + }
159.202 +
159.203 + @Override
159.204 + public expr errorExpr(PythonTree t) {
159.205 + return super.errorExpr(t);
159.206 + }
159.207 +
159.208 + @Override
159.209 + public mod errorMod(PythonTree t) {
159.210 + return super.errorMod(t);
159.211 + }
159.212 +
159.213 + @Override
159.214 + public slice errorSlice(PythonTree t) {
159.215 + return super.errorSlice(t);
159.216 + }
159.217 +
159.218 + @Override
159.219 + public stmt errorStmt(PythonTree t) {
159.220 + return super.errorStmt(t);
159.221 + }
159.222 +
159.223 + @Override
159.224 + public boolean mismatch(BaseRecognizer br, IntStream input, int ttype, BitSet follow) {
159.225 + return super.mismatch(br, input, ttype, follow);
159.226 + }
159.227 +
159.228 + @Override
159.229 + public Object recoverFromMismatchedToken(BaseRecognizer br, IntStream input, int ttype, BitSet follow) {
159.230 + MismatchedTokenException mt = new MismatchedTokenException(ttype, input);
159.231 + String message = br.getErrorMessage(mt, br.getTokenNames());
159.232 + if (mt.line >= 1) {
159.233 + int lineOffset = findLineOffset(context.source, mt.line-1);
159.234 + if (mt.charPositionInLine > 0) {
159.235 + lineOffset += mt.charPositionInLine;
159.236 + }
159.237 + int start = lineOffset;//t.getCharStartIndex();
159.238 + int stop = lineOffset;//t.getCharStopIndex();
159.239 + errors.add(new DefaultError(null, message, null, file, start, stop, Severity.ERROR));
159.240 + }
159.241 + return super.recoverFromMismatchedToken(br, input, ttype, follow);
159.242 + }
159.243 +
159.244 + @Override
159.245 + public void recover(Lexer lex, RecognitionException re) {
159.246 + super.recover(lex, re);
159.247 + }
159.248 +
159.249 + @Override
159.250 + public void recover(BaseRecognizer br, IntStream input, RecognitionException re) {
159.251 + super.recover(br, input, re);
159.252 + }
159.253 +
159.254 + @Override
159.255 + public void reportError(BaseRecognizer br, RecognitionException re) {
159.256 + if (!ignoreErrors) {
159.257 + String message = br.getErrorMessage(re, br.getTokenNames());
159.258 + if (message == null || message.length() == 0) {
159.259 + message = re.getMessage();
159.260 + }
159.261 + if (message == null) {
159.262 + //message = re.getUnexpectedType();
159.263 + message = re.toString();
159.264 + }
159.265 + int start = re.index;
159.266 +
159.267 + // Try to find the line offset. re.index doesn't do the trick.
159.268 + start = PythonUtils.getOffsetByLineCol(source, re.line - 1, 0); // -1: 0-based
159.269 + int end = start;
159.270 + if (re.charPositionInLine > 0) {
159.271 + try {
159.272 + end = GsfUtilities.getRowLastNonWhite(source, start) + 1;
159.273 + start += re.charPositionInLine;
159.274 + if (end < start) {
159.275 + end = start;
159.276 + }
159.277 + } catch (BadLocationException ex) {
159.278 + Exceptions.printStackTrace(ex);
159.279 + end = start;
159.280 + }
159.281 + if (end == 0) {
159.282 + end = start;
159.283 + }
159.284 + }
159.285 +
159.286 + // Some errors have better offsets if we look at the token stream
159.287 + if (re instanceof MismatchedTokenException) {
159.288 + MismatchedTokenException m = (MismatchedTokenException)re;
159.289 + if (m.token != null) {
159.290 + if (m.token instanceof org.python.antlr.runtime.CommonToken) {
159.291 + CommonToken token = (org.python.antlr.runtime.CommonToken)m.token;
159.292 + start = token.getStartIndex();
159.293 + end = token.getStopIndex();
159.294 + }
159.295 + }
159.296 + }
159.297 +
159.298 + if (start > source.length()) {
159.299 + start = source.length();
159.300 + end = start;
159.301 + }
159.302 +
159.303 + errors.add(new DefaultError(null, message, null, file, start, end, Severity.ERROR));
159.304 +
159.305 + // In order to avoid a StackOverflowError, the BaseRecognizer must be recreated.
159.306 + // We must keep the names of the tokens to avoid a NullPointerException.
159.307 + // See bz252630
159.308 + final String[] tokenNames = br.getTokenNames();
159.309 + br = new BaseRecognizer() {
159.310 +
159.311 + @Override
159.312 + public String getSourceName() {
159.313 + return file.getName();
159.314 + }
159.315 +
159.316 + @Override
159.317 + public String[] getTokenNames() {
159.318 + return tokenNames;
159.319 + }
159.320 + };
159.321 +
159.322 + super.reportError(br, re);
159.323 + }
159.324 + }
159.325 + };
159.326 +
159.327 + PythonLexer lexer = new PythonLexer(new ANTLRStringStream(sourceCode));
159.328 + lexer.setErrorHandler(errorHandler);
159.329 + CommonTokenStream tokens = new CommonTokenStream(lexer);
159.330 + tokens.discardOffChannelTokens(true);
159.331 + PythonTokenSource indentedSource = new PythonTokenSource(tokens, fileName);
159.332 + CommonTokenStream indentedTokens = new CommonTokenStream(indentedSource);
159.333 + // Import line ending with a dot raise a NullPointerException in
159.334 + // org.python.antlr.GrammarActions.makeDottedText called from parser.file_input
159.335 + // sanitizeImportTokens will remove the dot token from the list of tokens in
159.336 + // indentedTokens to avoid the bug and add an error at this file.
159.337 + // See https://netbeans.org/bugzilla/show_bug.cgi?id=252356
159.338 + sanitizeImportTokens(indentedTokens, errors, file);
159.339 + org.python.antlr.PythonParser parser;
159.340 + if (charset != null) {
159.341 + parser = new org.python.antlr.PythonParser(indentedTokens, charset);
159.342 + } else {
159.343 + parser = new org.python.antlr.PythonParser(indentedTokens);
159.344 + }
159.345 + parser.setTreeAdaptor(new PythonTreeAdaptor());
159.346 + parser.setErrorHandler(errorHandler);
159.347 + org.python.antlr.PythonParser.file_input_return r = parser.file_input();
159.348 + PythonTree t = (PythonTree)r.getTree();
159.349 + PythonParserResult result = new PythonParserResult(t, context.snapshot);
159.350 + result.setErrors(errors);
159.351 +
159.352 + result.setSanitized(context.sanitized, context.sanitizedRange, context.sanitizedContents);
159.353 + result.setSource(sourceCode);
159.354 +
159.355 + return result;
159.356 + } catch (ParseException pe) {
159.357 + if (sanitizing == Sanitize.NONE) {
159.358 + PythonParserResult sanitizedResult = sanitize(context, sanitizing);
159.359 + if (sanitizedResult.isValid()) {
159.360 + return sanitizedResult;
159.361 + } else {
159.362 + int offset = pe.index;
159.363 + assert offset >= 0;
159.364 + String desc = pe.getLocalizedMessage();
159.365 + if (desc == null) {
159.366 + desc = pe.getMessage();
159.367 + }
159.368 + DefaultError error = new DefaultError(null /*key*/, desc, null, file, offset, offset, Severity.ERROR);
159.369 + PythonParserResult parserResult = new PythonParserResult(null, context.snapshot);
159.370 + parserResult.addError(error);
159.371 + for (Error e : errors) {
159.372 + parserResult.addError(e);
159.373 + }
159.374 +
159.375 + return parserResult;
159.376 + }
159.377 + } else {
159.378 + return sanitize(context, sanitizing);
159.379 + }
159.380 + } catch (NullPointerException e) {
159.381 + String fileName = "";
159.382 + if (file != null) {
159.383 + fileName = FileUtil.getFileDisplayName(file);
159.384 + }
159.385 + e = Exceptions.attachMessage(e, "Was parsing " + fileName);
159.386 + Exceptions.printStackTrace(e);
159.387 + return new PythonParserResult(null, context.snapshot);
159.388 + } catch (Throwable t) {
159.389 + runtimeException = t;
159.390 + StackTraceElement[] stackTrace = t.getStackTrace();
159.391 + if (stackTrace != null && stackTrace.length > 0 && stackTrace[0].getClassName().startsWith("org.python.antlr")) {//.runtime.tree.RewriteRuleElementStream")) {
159.392 + // This is issue 150921
159.393 + // Don't bug user about it -- we already know
159.394 + Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Encountered issue #150921", t);
159.395 + } else {
159.396 + t = Exceptions.attachMessage(t, "Was parsing " + FileUtil.getFileDisplayName(file));
159.397 + Exceptions.printStackTrace(t);
159.398 + }
159.399 + return new PythonParserResult(null, context.snapshot);
159.400 + }
159.401 + }
159.402 +
159.403 + private void sanitizeImportTokens(CommonTokenStream indentedTokens, List errors, FileObject file) {
159.404 + List tokens = indentedTokens.getTokens();
159.405 + List<CommonToken> tokensToRemove = new ArrayList<>();
159.406 + int i = 0;
159.407 + while (i < tokens.size()) {
159.408 + CommonToken importToken = (CommonToken)tokens.get(i);
159.409 + if ("import".equals(importToken.getText()) || "from".equals(importToken.getText())) {
159.410 + // sanitizeDotTokens return the index of the token that starts the next line
159.411 + i = sanitizeDotTokens(tokens, tokensToRemove, importToken, i + 1, errors, file);
159.412 + } else {
159.413 + i++;
159.414 + }
159.415 + }
159.416 +
159.417 + for (CommonToken token : tokensToRemove) {
159.418 + tokens.remove(token);
159.419 + }
159.420 + }
159.421 +
159.422 + private int sanitizeDotTokens(List tokens, List tokensToRemove, CommonToken importToken,
159.423 + int startIndex, List errors, FileObject file) {
159.424 + for (int j = startIndex; j < tokens.size() - 1; j++) {
159.425 + CommonToken dotToken = (CommonToken)tokens.get(j);
159.426 + CommonToken nextToken = (CommonToken)tokens.get(j + 1);
159.427 + if (".".equals(dotToken.getText())) {
159.428 + if (nextToken.getText().startsWith("\n")) {
159.429 + tokensToRemove.add(dotToken);
159.430 + String rawTokenText;
159.431 + if (nextToken.getText().startsWith("\n")) {
159.432 + rawTokenText = "\\n";
159.433 + } else {
159.434 + rawTokenText = " ";
159.435 + }
159.436 + errors.add(
159.437 + new DefaultError(null, "Mismatch input '.' expecting NAME\nMissing NAME at '" + rawTokenText + "'",
159.438 + null, file, importToken.getStartIndex(), dotToken.getStopIndex(), Severity.ERROR));
159.439 + }
159.440 + } else if ("\n".equals(nextToken.getText())) { // End of line, must continue looping from external loop
159.441 + return j + 1;
159.442 + }
159.443 + }
159.444 +
159.445 + return startIndex;
159.446 + }
159.447 +
159.448 + private static String asString(CharSequence sequence) {
159.449 + if (sequence instanceof String) {
159.450 + return (String)sequence;
159.451 + } else {
159.452 + return sequence.toString();
159.453 + }
159.454 + }
159.455 +
159.456 +
159.457 + @SuppressWarnings("fallthrough")
159.458 + private PythonParserResult sanitize(final Context context, final Sanitize sanitizing) {
159.459 +
159.460 + switch (sanitizing) {
159.461 + case NEVER:
159.462 + return new PythonParserResult(null, context.snapshot);
159.463 +
159.464 + case NONE:
159.465 + if (context.caretOffset != -1) {
159.466 + return parse(context, Sanitize.EDITED_DOT);
159.467 + }
159.468 +
159.469 + case EDITED_DOT:
159.470 + // We've tried removing whitespace around the edit location
159.471 + // Fall through to try parsing with removing stuff around error location
159.472 + // (Don't bother doing this if errorOffset==caretOffset since that would try the same
159.473 + // source as EDITED_DOT which has no better chance of succeeding...)
159.474 + if (context.errorOffset != -1 && context.errorOffset != context.caretOffset) {
159.475 + return parse(context, Sanitize.ERROR_DOT);
159.476 + }
159.477 +
159.478 + // Fall through to try the next trick
159.479 + case ERROR_DOT:
159.480 +
159.481 + // We've tried removing dots - now try removing the whole line at the error position
159.482 + if (context.errorOffset != -1) {
159.483 + return parse(context, Sanitize.ERROR_LINE);
159.484 + }
159.485 +
159.486 + // Fall through to try the next trick
159.487 + case ERROR_LINE:
159.488 +
159.489 + // Messing with the error line didn't work - we could try "around" the error line
159.490 + // but I'm not attempting that now.
159.491 + // Finally try removing the whole line around the user editing position
159.492 + // (which could be far from where the error is showing up - but if you're typing
159.493 + // say a new "def" statement in a class, this will show up as an error on a mismatched
159.494 + // "end" statement rather than here
159.495 + if (context.caretOffset != -1) {
159.496 + return parse(context, Sanitize.EDITED_LINE);
159.497 + }
159.498 +
159.499 + // Fall through for default handling
159.500 + case EDITED_LINE:
159.501 + default:
159.502 + // We're out of tricks - just return the failed parse result
159.503 + return new PythonParserResult(null, context.snapshot);
159.504 + }
159.505 + }
159.506 +
159.507 + /**
159.508 + * Try cleaning up the source buffer around the current offset to increase
159.509 + * likelihood of parse success. Initially this method had a lot of
159.510 + * logic to determine whether a parse was likely to fail (e.g. invoking
159.511 + * the isEndMissing method from bracket completion etc.).
159.512 + * However, I am now trying a parse with the real source first, and then
159.513 + * only if that fails do I try parsing with sanitized source. Therefore,
159.514 + * this method has to be less conservative in ripping out code since it
159.515 + * will only be used when the regular source is failing.
159.516 + *
159.517 + * @todo Automatically close current statement by inserting ";"
159.518 + * @todo Handle sanitizing "new ^" from parse errors
159.519 + * @todo Replace "end" insertion fix with "}" insertion
159.520 + */
159.521 + private boolean sanitizeSource(Context context, Sanitize sanitizing) {
159.522 + int offset = context.caretOffset;
159.523 +
159.524 + // Let caretOffset represent the offset of the portion of the buffer we'll be operating on
159.525 + if ((sanitizing == Sanitize.ERROR_DOT) || (sanitizing == Sanitize.ERROR_LINE)) {
159.526 + offset = context.errorOffset;
159.527 + }
159.528 +
159.529 + // Don't attempt cleaning up the source if we don't have the buffer position we need
159.530 + if (offset == -1) {
159.531 + return false;
159.532 + }
159.533 +
159.534 + // The user might be editing around the given caretOffset.
159.535 + // See if it looks modified
159.536 + // Insert an end statement? Insert a } marker?
159.537 + String doc = context.source;
159.538 + if (offset > doc.length()) {
159.539 + return false;
159.540 + }
159.541 +
159.542 + try {
159.543 + // Sometimes the offset shows up on the next line
159.544 + if (GsfUtilities.isRowEmpty(doc, offset) || GsfUtilities.isRowWhite(doc, offset)) {
159.545 + offset = GsfUtilities.getRowStart(doc, offset) - 1;
159.546 + if (offset < 0) {
159.547 + offset = 0;
159.548 + }
159.549 + }
159.550 +
159.551 + if (!(GsfUtilities.isRowEmpty(doc, offset) || GsfUtilities.isRowWhite(doc, offset))) {
159.552 + if ((sanitizing == Sanitize.EDITED_LINE) || (sanitizing == Sanitize.ERROR_LINE)) {
159.553 + // See if I should try to remove the current line, since it has text on it.
159.554 + int lineEnd = GsfUtilities.getRowLastNonWhite(doc, offset);
159.555 +
159.556 + if (lineEnd != -1) {
159.557 + lineEnd++; // lineEnd is exclusive, not inclusive
159.558 + StringBuilder sb = new StringBuilder(doc.length());
159.559 + int lineStart = GsfUtilities.getRowStart(doc, offset);
159.560 + if (lineEnd >= lineStart + 2) {
159.561 + sb.append(doc.substring(0, lineStart));
159.562 + sb.append("//");
159.563 + int rest = lineStart + 2;
159.564 + if (rest < doc.length()) {
159.565 + sb.append(doc.substring(rest, doc.length()));
159.566 + }
159.567 + } else {
159.568 + // A line with just one character - can't replace with a comment
159.569 + // Just replace the char with a space
159.570 + sb.append(doc.substring(0, lineStart));
159.571 + sb.append(" ");
159.572 + int rest = lineStart + 1;
159.573 + if (rest < doc.length()) {
159.574 + sb.append(doc.substring(rest, doc.length()));
159.575 + }
159.576 +
159.577 + }
159.578 +
159.579 + assert sb.length() == doc.length();
159.580 +
159.581 + context.sanitizedRange = new OffsetRange(lineStart, lineEnd);
159.582 + context.sanitizedSource = sb.toString();
159.583 + context.sanitizedContents = doc.substring(lineStart, lineEnd);
159.584 + return true;
159.585 + }
159.586 + } else {
159.587 + assert sanitizing == Sanitize.ERROR_DOT || sanitizing == Sanitize.EDITED_DOT;
159.588 + // Try nuking dots/colons from this line
159.589 + // See if I should try to remove the current line, since it has text on it.
159.590 + int lineStart = GsfUtilities.getRowStart(doc, offset);
159.591 + int lineEnd = offset - 1;
159.592 + while (lineEnd >= lineStart && lineEnd < doc.length()) {
159.593 + if (!Character.isWhitespace(doc.charAt(lineEnd))) {
159.594 + break;
159.595 + }
159.596 + lineEnd--;
159.597 + }
159.598 + if (lineEnd > lineStart) {
159.599 + StringBuilder sb = new StringBuilder(doc.length());
159.600 + String line = doc.substring(lineStart, lineEnd + 1);
159.601 + int removeChars = 0;
159.602 + int removeEnd = lineEnd + 1;
159.603 + boolean isLineEnd = GsfUtilities.getRowLastNonWhite(context.source, lineEnd) <= lineEnd;
159.604 +
159.605 + if (line.endsWith(".")) { // NOI18N
159.606 + removeChars = 1;
159.607 + } else if (line.endsWith("(")) { // NOI18N
159.608 + if (isLineEnd) {
159.609 + removeChars = 1;
159.610 + }
159.611 + } else if (line.endsWith(",")) { // NOI18N removeChars = 1;
159.612 + if (!isLineEnd) {
159.613 + removeChars = 1;
159.614 + }
159.615 + } else if (line.endsWith(", ")) { // NOI18N
159.616 + if (!isLineEnd) {
159.617 + removeChars = 2;
159.618 + }
159.619 + } else if (line.endsWith(",)")) { // NOI18N
159.620 + // Handle lone comma in parameter list - e.g.
159.621 + // type "foo(a," -> you end up with "foo(a,|)" which doesn't parse - but
159.622 + // the line ends with ")", not "," !
159.623 + // Just remove the comma
159.624 + removeChars = 1;
159.625 + removeEnd--;
159.626 + } else if (line.endsWith(", )")) { // NOI18N
159.627 + // Just remove the comma
159.628 + removeChars = 1;
159.629 + removeEnd -= 2;
159.630 + } else if (line.endsWith(" def") && isLineEnd) { // NOI18N
159.631 + removeChars = 3;
159.632 + } else {
159.633 +// // Make sure the line doesn't end with one of the JavaScript keywords
159.634 +// // (new, do, etc) - we can't handle that!
159.635 +// for (String keyword : PythonUtils.PYTHON_KEYWORDS) { // reserved words are okay
159.636 +// if (line.endsWith(keyword)) {
159.637 +// if ("print".equals(keyword)) { // NOI18N
159.638 +// // Only remove the keyword if it's the end of the line. Otherwise,
159.639 +// // it could have just been typed in front of something (e.g. inserted a print) and we don't
159.640 +// // want to confuse the parser with "va foo" instead of "var foo"
159.641 +// if (!isLineEnd) {
159.642 +// continue;
159.643 +// }
159.644 +// }
159.645 +// removeChars = 1;
159.646 +// break;
159.647 +// }
159.648 +// }
159.649 + }
159.650 +
159.651 + if (removeChars == 0) {
159.652 + return false;
159.653 + }
159.654 +
159.655 + int removeStart = removeEnd - removeChars;
159.656 +
159.657 + sb.append(doc.substring(0, removeStart));
159.658 +
159.659 + for (int i = 0; i < removeChars; i++) {
159.660 + sb.append(' ');
159.661 + }
159.662 +
159.663 + if (removeEnd < doc.length()) {
159.664 + sb.append(doc.substring(removeEnd, doc.length()));
159.665 + }
159.666 + assert sb.length() == doc.length();
159.667 +
159.668 + context.sanitizedRange = new OffsetRange(removeStart, removeEnd);
159.669 + context.sanitizedSource = sb.toString();
159.670 + context.sanitizedContents = doc.substring(removeStart, removeEnd);
159.671 + return true;
159.672 + }
159.673 + }
159.674 + }
159.675 + } catch (BadLocationException ble) {
159.676 + Exceptions.printStackTrace(ble);
159.677 + }
159.678 +
159.679 + return false;
159.680 + }
159.681 +
159.682 + private static int findLineOffset(String source, int line) {
159.683 + int offset = -1;
159.684 + for (int i = 0; i < line; i++) {
159.685 + offset = source.indexOf("\n", offset+1);
159.686 + if (offset == -1) {
159.687 + return source.length();
159.688 + }
159.689 + }
159.690 +
159.691 + return Math.min(source.length(), offset+1);
159.692 + }
159.693 +
159.694 + /** Attempts to sanitize the input buffer */
159.695 + public static enum Sanitize {
159.696 + /** Only parse the current file accurately, don't try heuristics */
159.697 + NEVER,
159.698 + /** Perform no sanitization */
159.699 + NONE,
159.700 + /** Try to remove the trailing . or :: at the caret line */
159.701 + EDITED_DOT,
159.702 + /** Try to remove the trailing . or :: at the error position, or the prior
159.703 + * line, or the caret line */
159.704 + ERROR_DOT,
159.705 + /** Try to cut out the error line */
159.706 + ERROR_LINE,
159.707 + /** Try to cut out the current edited line, if known */
159.708 + EDITED_LINE,
159.709 + }
159.710 +
159.711 + /** Sanitize context */
159.712 + public static class Context {
159.713 + private FileObject file;
159.714 +// private ParseListener listener;
159.715 + private int errorOffset;
159.716 + private String source;
159.717 + private String sanitizedSource;
159.718 + private OffsetRange sanitizedRange = OffsetRange.NONE;
159.719 + private String sanitizedContents;
159.720 + private int caretOffset;
159.721 + private Sanitize sanitized = Sanitize.NONE;
159.722 +// private TranslatedSource translatedSource;
159.723 +// private Parser.Job job;
159.724 + private Snapshot snapshot;
159.725 + private Task task;
159.726 + private SourceModificationEvent event;
159.727 +//
159.728 +// public Context(ParserFile parserFile, ParseListener listener, String source, int caretOffset, TranslatedSource translatedSource, Parser.Job job) {
159.729 +// this.file = parserFile;
159.730 +// this.listener = listener;
159.731 +// this.source = source;
159.732 +// this.caretOffset = caretOffset;
159.733 +// this.translatedSource = translatedSource;
159.734 +// this.job = job;
159.735 +//
159.736 +//
159.737 +// if (caretOffset != -1) {
159.738 +// sanitized = Sanitize.EDITED_DOT;
159.739 +// }
159.740 +// }
159.741 +//
159.742 +// @Override
159.743 +// public String toString() {
159.744 +// return "PythonParser.Context(" + file.toString() + ")"; // NOI18N
159.745 +// }
159.746 +//
159.747 +// public OffsetRange getSanitizedRange() {
159.748 +// return sanitizedRange;
159.749 +// }
159.750 +//
159.751 +// public Sanitize getSanitized() {
159.752 +// return sanitized;
159.753 +// }
159.754 +//
159.755 +// public String getSanitizedSource() {
159.756 +// return sanitizedSource;
159.757 +// }
159.758 +//
159.759 +// public int getErrorOffset() {
159.760 +// return errorOffset;
159.761 +// }
159.762 + }
159.763 +}
160.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
160.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonParserResult.java Mon Sep 21 13:01:16 2015 +0200
160.3 @@ -0,0 +1,152 @@
160.4 +/*
160.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
160.6 + *
160.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
160.8 + *
160.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
160.10 + * Other names may be trademarks of their respective owners.
160.11 + *
160.12 + * The contents of this file are subject to the terms of either the GNU
160.13 + * General Public License Version 2 only ("GPL") or the Common
160.14 + * Development and Distribution License("CDDL") (collectively, the
160.15 + * "License"). You may not use this file except in compliance with the
160.16 + * License. You can obtain a copy of the License at
160.17 + * http://www.netbeans.org/cddl-gplv2.html
160.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
160.19 + * specific language governing permissions and limitations under the
160.20 + * License. When distributing the software, include this License Header
160.21 + * Notice in each file and include the License file at
160.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
160.23 + * particular file as subject to the "Classpath" exception as provided
160.24 + * by Oracle in the GPL Version 2 section of the License file that
160.25 + * accompanied this code. If applicable, add the following below the
160.26 + * License Header, with the fields enclosed by brackets [] replaced by
160.27 + * your own identifying information:
160.28 + * "Portions Copyrighted [year] [name of copyright owner]"
160.29 + *
160.30 + * Contributor(s):
160.31 + *
160.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
160.33 + */
160.34 +package org.netbeans.modules.python.source;
160.35 +
160.36 +import java.util.LinkedList;
160.37 +import java.util.List;
160.38 +import org.netbeans.api.annotations.common.NonNull;
160.39 +import org.netbeans.modules.csl.api.Error;
160.40 +import org.netbeans.modules.csl.api.OffsetRange;
160.41 +import org.netbeans.modules.csl.spi.ParserResult;
160.42 +import org.netbeans.modules.parsing.api.Snapshot;
160.43 +import org.netbeans.modules.python.source.PythonParser.Sanitize;
160.44 +import org.netbeans.modules.python.source.scopes.SymbolTable;
160.45 +import org.python.antlr.PythonTree;
160.46 +
160.47 +/**
160.48 + * A ParserResult for Python. The AST Jython's AST.
160.49 + *
160.50 + * @todo Cache AstPath for caret position here!
160.51 + * @author Tor Norbye
160.52 + */
160.53 +public class PythonParserResult extends ParserResult {
160.54 + private PythonTree root;
160.55 + private List<Error> errors;
160.56 + private OffsetRange sanitizedRange = OffsetRange.NONE;
160.57 + private String source;
160.58 + private String sanitizedContents;
160.59 + private PythonParser.Sanitize sanitized;
160.60 + private PythonStructureScanner.AnalysisResult analysisResult;
160.61 + private SymbolTable symbolTable;
160.62 + private int codeTemplateOffset = -1;
160.63 +
160.64 + public PythonParserResult(PythonTree tree, @NonNull Snapshot snapshot) {
160.65 + super(snapshot);
160.66 + this.root = tree;
160.67 + this.errors = new LinkedList<>();
160.68 + }
160.69 +
160.70 + public PythonTree getRoot() {
160.71 + return root;
160.72 + }
160.73 +
160.74 + @Override
160.75 + public List<? extends Error> getDiagnostics() {
160.76 + return errors;
160.77 + }
160.78 +
160.79 + @Override
160.80 + protected void invalidate() {
160.81 + }
160.82 +
160.83 + public void setErrors(List<? extends Error> errors) {
160.84 + this.errors.clear();
160.85 + this.errors.addAll(errors);
160.86 + }
160.87 +
160.88 + /**
160.89 + * Set the range of source that was sanitized, if any.
160.90 + */
160.91 + void setSanitized(PythonParser.Sanitize sanitized, OffsetRange sanitizedRange, String sanitizedContents) {
160.92 + this.sanitized = sanitized;
160.93 + this.sanitizedRange = sanitizedRange;
160.94 + this.sanitizedContents = sanitizedContents;
160.95 + if (sanitizedContents == null || sanitizedRange == OffsetRange.NONE) {
160.96 + this.sanitized = Sanitize.NONE;
160.97 + }
160.98 + }
160.99 +
160.100 + public PythonParser.Sanitize getSanitized() {
160.101 + return sanitized;
160.102 + }
160.103 +
160.104 + /**
160.105 + * Return whether the source code for the parse result was "cleaned"
160.106 + * or "sanitized" (modified to reduce chance of parser errors) or not.
160.107 + * This method returns OffsetRange.NONE if the source was not sanitized,
160.108 + * otherwise returns the actual sanitized range.
160.109 + */
160.110 + public OffsetRange getSanitizedRange() {
160.111 + return sanitizedRange;
160.112 + }
160.113 +
160.114 + public SymbolTable getSymbolTable() {
160.115 + if (symbolTable == null) {
160.116 + symbolTable = new SymbolTable(root, getSnapshot().getSource().getFileObject());
160.117 + }
160.118 +
160.119 + return symbolTable;
160.120 + }
160.121 +
160.122 + public String getSanitizedContents() {
160.123 + return sanitizedContents;
160.124 + }
160.125 +
160.126 + public String getSource() {
160.127 + return source;
160.128 + }
160.129 +
160.130 + public void setSource(String source) {
160.131 + this.source = source;
160.132 + }
160.133 +
160.134 + /**
160.135 + * @return the codeTemplateOffset
160.136 + */
160.137 + public int getCodeTemplateOffset() {
160.138 + return codeTemplateOffset;
160.139 + }
160.140 +
160.141 + /**
160.142 + * @param codeTemplateOffset the codeTemplateOffset to set
160.143 + */
160.144 + public void setCodeTemplateOffset(int codeTemplateOffset) {
160.145 + this.codeTemplateOffset = codeTemplateOffset;
160.146 + }
160.147 +
160.148 + public void addError(Error e) {
160.149 + errors.add(e);
160.150 + }
160.151 +
160.152 + public boolean isValid() {
160.153 + return errors.isEmpty();
160.154 + }
160.155 +}
161.1 --- a/python.source/src/org/netbeans/modules/python/source/PythonProjectSourceLevelQuery.java Fri Sep 18 16:20:24 2015 -0500
161.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
161.3 @@ -1,29 +0,0 @@
161.4 -/*
161.5 - * To change this license header, choose License Headers in Project Properties.
161.6 - * To change this template file, choose Tools | Templates
161.7 - * and open the template in the editor.
161.8 - */
161.9 -package org.netbeans.modules.python.source;
161.10 -
161.11 -import org.netbeans.modules.python.source.queries.SourceLevelQueryImplementation;
161.12 -import org.netbeans.api.project.FileOwnerQuery;
161.13 -import org.netbeans.api.project.Project;
161.14 -import org.openide.filesystems.FileObject;
161.15 -import org.openide.util.lookup.ServiceProvider;
161.16 -
161.17 -@ServiceProvider(service = SourceLevelQueryImplementation.class, position = 400)
161.18 -public class PythonProjectSourceLevelQuery implements SourceLevelQueryImplementation {
161.19 -
161.20 - @Override
161.21 - public Result getSourceLevel(FileObject pythonFile) {
161.22 - final Project project = FileOwnerQuery.getOwner(pythonFile);
161.23 - if (project != null) {
161.24 - SourceLevelQueryImplementation impl = project.getLookup().lookup(SourceLevelQueryImplementation.class);
161.25 - if (impl != null) {
161.26 - return impl.getSourceLevel(pythonFile);
161.27 - }
161.28 - }
161.29 - return null;
161.30 - }
161.31 -
161.32 -}
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
162.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonStructureItem.java Mon Sep 21 13:01:16 2015 +0200
162.3 @@ -0,0 +1,195 @@
162.4 +/*
162.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
162.6 + *
162.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
162.8 + *
162.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
162.10 + * Other names may be trademarks of their respective owners.
162.11 + *
162.12 + * The contents of this file are subject to the terms of either the GNU
162.13 + * General Public License Version 2 only ("GPL") or the Common
162.14 + * Development and Distribution License("CDDL") (collectively, the
162.15 + * "License"). You may not use this file except in compliance with the
162.16 + * License. You can obtain a copy of the License at
162.17 + * http://www.netbeans.org/cddl-gplv2.html
162.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
162.19 + * specific language governing permissions and limitations under the
162.20 + * License. When distributing the software, include this License Header
162.21 + * Notice in each file and include the License file at
162.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
162.23 + * particular file as subject to the "Classpath" exception as provided
162.24 + * by Oracle in the GPL Version 2 section of the License file that
162.25 + * accompanied this code. If applicable, add the following below the
162.26 + * License Header, with the fields enclosed by brackets [] replaced by
162.27 + * your own identifying information:
162.28 + * "Portions Copyrighted [year] [name of copyright owner]"
162.29 + *
162.30 + * Contributor(s):
162.31 + *
162.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
162.33 + */
162.34 +package org.netbeans.modules.python.source;
162.35 +
162.36 +import java.util.ArrayList;
162.37 +import java.util.Collections;
162.38 +import java.util.List;
162.39 +import javax.swing.ImageIcon;
162.40 +import org.netbeans.modules.csl.api.ElementHandle;
162.41 +import org.netbeans.modules.csl.api.ElementKind;
162.42 +import org.netbeans.modules.csl.api.HtmlFormatter;
162.43 +import org.netbeans.modules.csl.api.Modifier;
162.44 +import org.netbeans.modules.csl.api.StructureItem;
162.45 +import org.netbeans.modules.python.source.elements.AstElement;
162.46 +import org.netbeans.modules.python.source.scopes.SymbolTable;
162.47 +import org.openide.util.ImageUtilities;
162.48 +import org.python.antlr.PythonTree;
162.49 +import org.python.antlr.ast.ClassDef;
162.50 +import org.python.antlr.ast.FunctionDef;
162.51 +
162.52 +public final class PythonStructureItem extends AstElement implements StructureItem {
162.53 + private List<PythonStructureItem> children;
162.54 + private PythonStructureItem parent;
162.55 +
162.56 + public PythonStructureItem(SymbolTable scopes, ClassDef def) {
162.57 + this(scopes, def, def.getInternalName(), ElementKind.CLASS);
162.58 + }
162.59 +
162.60 + public PythonStructureItem(SymbolTable scopes, FunctionDef def) {
162.61 + this(scopes, def, def.getInternalName(), ElementKind.METHOD);
162.62 + if ("__init__".equals(name)) { // NOI18N
162.63 + kind = ElementKind.CONSTRUCTOR;
162.64 + }
162.65 + }
162.66 +
162.67 + public PythonStructureItem(SymbolTable scopes, PythonTree node, String name, ElementKind kind) {
162.68 + super(scopes, node, name, kind);
162.69 + this.node = node;
162.70 + this.name = name;
162.71 + this.kind = kind;
162.72 + }
162.73 +
162.74 + void add(PythonStructureItem child) {
162.75 + if (children == null) {
162.76 + children = new ArrayList<>();
162.77 + }
162.78 + children.add(child);
162.79 + child.parent = this;
162.80 + }
162.81 +
162.82 + @Override
162.83 + public String getSortText() {
162.84 + return name;
162.85 + }
162.86 +
162.87 + @Override
162.88 + public String getHtml(HtmlFormatter formatter) {
162.89 + formatter.appendText(name);
162.90 + if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
162.91 + FunctionDef def = (FunctionDef)node;
162.92 + List<String> params = PythonAstUtils.getParameters(def);
162.93 + if (params.size() > 0) {
162.94 + boolean isFirst = true;
162.95 + formatter.appendHtml("(");
162.96 + formatter.parameters(true);
162.97 + for (String param : params) {
162.98 + if (isFirst) {
162.99 + isFirst = false;
162.100 + } else {
162.101 + formatter.appendText(",");
162.102 + }
162.103 + formatter.appendText(param);
162.104 + }
162.105 + formatter.parameters(false);
162.106 + formatter.appendHtml(")");
162.107 + }
162.108 + }
162.109 + return formatter.getText();
162.110 + }
162.111 +
162.112 + @Override
162.113 + public ElementHandle getElementHandle() {
162.114 + return null;
162.115 + }
162.116 +
162.117 + @Override
162.118 + public boolean isLeaf() {
162.119 + return children == null;
162.120 + }
162.121 +
162.122 + @Override
162.123 + public List<? extends StructureItem> getNestedItems() {
162.124 + return children == null ? Collections.<StructureItem>emptyList() : children;
162.125 + }
162.126 +
162.127 + @Override
162.128 + public long getPosition() {
162.129 + return node.getCharStartIndex();
162.130 + }
162.131 +
162.132 + @Override
162.133 + public long getEndPosition() {
162.134 + return node.getCharStopIndex();
162.135 + }
162.136 +
162.137 + @Override
162.138 + public ImageIcon getCustomIcon() {
162.139 + if (kind == ElementKind.CLASS && getModifiers().contains(Modifier.PRIVATE)) {
162.140 + // GSF doesn't automatically handle icons on private classes, so I have to
162.141 + // work around that here
162.142 + return ImageUtilities.loadImageIcon("org/netbeans/modules/python/editor/resources/private-class.png", false); //NOI18N
162.143 + }
162.144 +
162.145 + return null;
162.146 + }
162.147 +
162.148 + @Override
162.149 + public Object getSignature() {
162.150 + if ((kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) && parent != null &&
162.151 + parent.kind == ElementKind.CLASS) {
162.152 + return parent.name + "." + name;
162.153 + }
162.154 + return super.getSignature();
162.155 + }
162.156 +
162.157 + @Override
162.158 + public boolean equals(Object obj) {
162.159 + if (obj == null) {
162.160 + return false;
162.161 + }
162.162 + if (getClass() != obj.getClass()) {
162.163 + return false;
162.164 + }
162.165 + final PythonStructureItem other = (PythonStructureItem)obj;
162.166 + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
162.167 + return false;
162.168 + }
162.169 + if (this.kind != other.kind) {
162.170 + return false;
162.171 + }
162.172 + if (this.getModifiers() != other.getModifiers() && (this.modifiers == null || !this.modifiers.equals(other.modifiers))) {
162.173 + return false;
162.174 + }
162.175 +
162.176 + if ((kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) && node != null && other.node != null) {
162.177 + FunctionDef def = (FunctionDef)node;
162.178 + List<String> params = PythonAstUtils.getParameters(def);
162.179 + List<String> otherParams = PythonAstUtils.getParameters((FunctionDef)other.node);
162.180 + if (!params.equals((otherParams))) {
162.181 + return false;
162.182 + }
162.183 + }
162.184 +
162.185 +// if (this.getNestedItems().size() != other.getNestedItems().size()) {
162.186 +// return false;
162.187 +// }
162.188 +//
162.189 + return true;
162.190 + }
162.191 +
162.192 + @Override
162.193 + public int hashCode() {
162.194 + int hash = 7;
162.195 + hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0);
162.196 + return hash;
162.197 + }
162.198 +}
163.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
163.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonStructureScanner.java Mon Sep 21 13:01:16 2015 +0200
163.3 @@ -0,0 +1,274 @@
163.4 +/*
163.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
163.6 + *
163.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
163.8 + *
163.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
163.10 + * Other names may be trademarks of their respective owners.
163.11 + *
163.12 + * The contents of this file are subject to the terms of either the GNU
163.13 + * General Public License Version 2 only ("GPL") or the Common
163.14 + * Development and Distribution License("CDDL") (collectively, the
163.15 + * "License"). You may not use this file except in compliance with the
163.16 + * License. You can obtain a copy of the License at
163.17 + * http://www.netbeans.org/cddl-gplv2.html
163.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
163.19 + * specific language governing permissions and limitations under the
163.20 + * License. When distributing the software, include this License Header
163.21 + * Notice in each file and include the License file at
163.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
163.23 + * particular file as subject to the "Classpath" exception as provided
163.24 + * by Oracle in the GPL Version 2 section of the License file that
163.25 + * accompanied this code. If applicable, add the following below the
163.26 + * License Header, with the fields enclosed by brackets [] replaced by
163.27 + * your own identifying information:
163.28 + * "Portions Copyrighted [year] [name of copyright owner]"
163.29 + *
163.30 + * Contributor(s):
163.31 + *
163.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
163.33 + */
163.34 +package org.netbeans.modules.python.source;
163.35 +
163.36 +import java.util.ArrayList;
163.37 +import java.util.Collections;
163.38 +import java.util.HashMap;
163.39 +import java.util.List;
163.40 +import java.util.Map;
163.41 +import javax.swing.text.BadLocationException;
163.42 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
163.43 +import org.netbeans.editor.BaseDocument;
163.44 +import org.netbeans.editor.Utilities;
163.45 +import org.netbeans.modules.csl.api.ElementKind;
163.46 +import org.netbeans.modules.csl.api.OffsetRange;
163.47 +import org.netbeans.modules.csl.api.StructureItem;
163.48 +import org.netbeans.modules.csl.api.StructureScanner;
163.49 +import org.netbeans.modules.csl.api.StructureScanner.Configuration;
163.50 +import org.netbeans.modules.csl.spi.GsfUtilities;
163.51 +import org.netbeans.modules.csl.spi.ParserResult;
163.52 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
163.53 +import org.netbeans.modules.python.source.scopes.SymInfo;
163.54 +import org.netbeans.modules.python.source.scopes.SymbolTable;
163.55 +import org.openide.util.Exceptions;
163.56 +import org.python.antlr.PythonTree;
163.57 +import org.python.antlr.Visitor;
163.58 +import org.python.antlr.ast.ClassDef;
163.59 +import org.python.antlr.ast.FunctionDef;
163.60 +import org.python.antlr.ast.Str;
163.61 +
163.62 +/**
163.63 + * This class analyzes the structure of a Python parse tree
163.64 + * and infers structure (navigation items, folds, etc.)
163.65 + *
163.66 + * @author Tor Norbye
163.67 + */
163.68 +public class PythonStructureScanner implements StructureScanner {
163.69 +
163.70 + public static AnalysisResult analyze(PythonParserResult info) {
163.71 + AnalysisResult analysisResult = new AnalysisResult();
163.72 +
163.73 + PythonTree root = PythonAstUtils.getRoot(info);
163.74 + if (root != null) {
163.75 + SymbolTable scopes = PythonAstUtils.getParseResult(info).getSymbolTable();
163.76 + StructureVisitor visitor = new StructureVisitor(scopes);
163.77 + try {
163.78 + visitor.visit(root);
163.79 + analysisResult.setElements(visitor.getRoots());
163.80 + } catch (Exception ex) {
163.81 + Exceptions.printStackTrace(ex);
163.82 + }
163.83 + }
163.84 +
163.85 + return analysisResult;
163.86 + }
163.87 +
163.88 + @Override
163.89 + public List<? extends StructureItem> scan(ParserResult info) {
163.90 + PythonParserResult parseResult = PythonAstUtils.getParseResult(info);
163.91 + if (parseResult == null) {
163.92 + return Collections.emptyList();
163.93 + }
163.94 +
163.95 + return getStructure(parseResult).getElements();
163.96 + }
163.97 +
163.98 + public PythonStructureScanner.AnalysisResult getStructure(PythonParserResult result) {
163.99 + // TODO Cache ! (Used to be in PythonParserResult
163.100 + AnalysisResult analysisResult = PythonStructureScanner.analyze(result);
163.101 + return analysisResult;
163.102 + }
163.103 +
163.104 + @Override
163.105 + public Map<String, List<OffsetRange>> folds(ParserResult info) {
163.106 + PythonParserResult result = PythonAstUtils.getParseResult(info);
163.107 + PythonTree root = PythonAstUtils.getRoot(result);
163.108 + if (root == null) {
163.109 + return Collections.emptyMap();
163.110 + }
163.111 +
163.112 + //TranslatedSource source = result.getTranslatedSource();
163.113 + //
163.114 + //AnalysisResult ar = result.getStructure();
163.115 + //
163.116 + //List<?extends AstElement> elements = ar.getElements();
163.117 + //List<StructureItem> itemList = new ArrayList<StructureItem>(elements.size());
163.118 +
163.119 + BaseDocument doc = GsfUtilities.getDocument(result.getSnapshot().getSource().getFileObject(), false);
163.120 + if (doc != null) {
163.121 + try {
163.122 + doc.readLock(); // For Utilities.getRowEnd() access
163.123 + FoldVisitor visitor = new FoldVisitor((PythonParserResult) info, doc);
163.124 + visitor.visit(root);
163.125 + List<OffsetRange> codeBlocks = visitor.getCodeBlocks();
163.126 +
163.127 + Map<String, List<OffsetRange>> folds = new HashMap<>();
163.128 + folds.put("codeblocks", codeBlocks); // NOI18N
163.129 +
163.130 + return folds;
163.131 + } catch (Exception ex) {
163.132 + Exceptions.printStackTrace(ex);
163.133 + } finally {
163.134 + doc.readUnlock();
163.135 + }
163.136 + }
163.137 + return Collections.emptyMap();
163.138 + }
163.139 +
163.140 + @Override
163.141 + public Configuration getConfiguration() {
163.142 + return new Configuration(true, true, -1);
163.143 + }
163.144 +
163.145 + private static class FoldVisitor extends Visitor {
163.146 + private List<OffsetRange> codeBlocks = new ArrayList<>();
163.147 + private PythonParserResult info;
163.148 + private BaseDocument doc;
163.149 +
163.150 + private FoldVisitor(PythonParserResult info, BaseDocument doc) {
163.151 + this.info = info;
163.152 + this.doc = doc;
163.153 + }
163.154 +
163.155 + private void addFoldRange(PythonTree node) {
163.156 + OffsetRange astRange = PythonAstUtils.getRange(node);
163.157 +
163.158 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
163.159 + if (lexRange != OffsetRange.NONE) {
163.160 + try {
163.161 + int startRowEnd = Utilities.getRowEnd(doc, lexRange.getStart());
163.162 + if (startRowEnd < lexRange.getEnd()) {
163.163 + codeBlocks.add(new OffsetRange(startRowEnd, lexRange.getEnd()));
163.164 + }
163.165 + } catch (BadLocationException ex) {
163.166 + Exceptions.printStackTrace(ex);
163.167 + }
163.168 + }
163.169 + }
163.170 +
163.171 + @Override
163.172 + public Object visitClassDef(ClassDef node) throws Exception {
163.173 + addFoldRange(node);
163.174 +
163.175 + return super.visitClassDef(node);
163.176 + }
163.177 +
163.178 + @Override
163.179 + public Object visitFunctionDef(FunctionDef node) throws Exception {
163.180 + addFoldRange(node);
163.181 +
163.182 + return super.visitFunctionDef(node);
163.183 + }
163.184 +
163.185 + @Override
163.186 + public Object visitStr(Str node) throws Exception {
163.187 + addFoldRange(node);
163.188 + return super.visitStr(node);
163.189 + }
163.190 +
163.191 + public List<OffsetRange> getCodeBlocks() {
163.192 + return codeBlocks;
163.193 + }
163.194 + }
163.195 +
163.196 + private static class StructureVisitor extends Visitor {
163.197 + List<PythonStructureItem> roots = new ArrayList<>();
163.198 + List<PythonStructureItem> stack = new ArrayList<>();
163.199 + SymbolTable scopes;
163.200 +
163.201 + StructureVisitor(SymbolTable scopes) {
163.202 + this.scopes = scopes;
163.203 + }
163.204 +
163.205 + private List<PythonStructureItem> getRoots() {
163.206 + return roots;
163.207 + }
163.208 +
163.209 + @Override
163.210 + public Object visitClassDef(ClassDef def) throws Exception {
163.211 + PythonStructureItem item = new PythonStructureItem(scopes, def);
163.212 + add(item);
163.213 +
163.214 + ScopeInfo scope = scopes.getScopeInfo(def);
163.215 + if (scope != null && scope.attributes.size() > 0) {
163.216 + for (Map.Entry<String, SymInfo> entry : scope.attributes.entrySet()) {
163.217 + // TODO - sort these puppies? Right now their natural order will be
163.218 + // random (hashkey dependent) instead of by source position or by name
163.219 + SymInfo sym = entry.getValue();
163.220 + if (sym.node != null) {
163.221 + String name = entry.getKey();
163.222 + PythonStructureItem attribute = new PythonStructureItem(scopes, sym.node, name, ElementKind.ATTRIBUTE);
163.223 + item.add(attribute);
163.224 + }
163.225 + }
163.226 + }
163.227 +
163.228 + stack.add(item);
163.229 + Object result = super.visitClassDef(def);
163.230 + stack.remove(stack.size() - 1);
163.231 +
163.232 + return result;
163.233 + }
163.234 +
163.235 + @Override
163.236 + public Object visitFunctionDef(FunctionDef def) throws Exception {
163.237 + PythonStructureItem item = new PythonStructureItem(scopes, def);
163.238 +
163.239 + add(item);
163.240 + stack.add(item);
163.241 + Object result = super.visitFunctionDef(def);
163.242 + stack.remove(stack.size() - 1);
163.243 +
163.244 + return result;
163.245 + }
163.246 +
163.247 + private void add(PythonStructureItem child) {
163.248 + PythonStructureItem parent = stack.size() > 0 ? stack.get(stack.size() - 1) : null;
163.249 + if (parent == null) {
163.250 + roots.add(child);
163.251 + } else {
163.252 + parent.add(child);
163.253 + }
163.254 + }
163.255 + }
163.256 +
163.257 + public static class AnalysisResult {
163.258 + //private List<?extends AstElement> elements;
163.259 + private List<PythonStructureItem> elements;
163.260 +
163.261 + private AnalysisResult() {
163.262 + }
163.263 +
163.264 + //private void setElements(List<?extends AstElement> elements) {
163.265 + private void setElements(List<PythonStructureItem> elements) {
163.266 + this.elements = elements;
163.267 + }
163.268 +
163.269 + //public List<?extends AstElement> getElements() {
163.270 + public List<PythonStructureItem> getElements() {
163.271 + if (elements == null) {
163.272 + return Collections.emptyList();
163.273 + }
163.274 + return elements;
163.275 + }
163.276 + }
163.277 +}
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonUtils.java Mon Sep 21 13:01:16 2015 +0200
164.3 @@ -0,0 +1,513 @@
164.4 +/*
164.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
164.6 + *
164.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
164.8 + *
164.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
164.10 + * Other names may be trademarks of their respective owners.
164.11 + *
164.12 + * The contents of this file are subject to the terms of either the GNU
164.13 + * General Public License Version 2 only ("GPL") or the Common
164.14 + * Development and Distribution License("CDDL") (collectively, the
164.15 + * "License"). You may not use this file except in compliance with the
164.16 + * License. You can obtain a copy of the License at
164.17 + * http://www.netbeans.org/cddl-gplv2.html
164.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
164.19 + * specific language governing permissions and limitations under the
164.20 + * License. When distributing the software, include this License Header
164.21 + * Notice in each file and include the License file at
164.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
164.23 + * particular file as subject to the "Classpath" exception as provided
164.24 + * by Oracle in the GPL Version 2 section of the License file that
164.25 + * accompanied this code. If applicable, add the following below the
164.26 + * License Header, with the fields enclosed by brackets [] replaced by
164.27 + * your own identifying information:
164.28 + * "Portions Copyrighted [year] [name of copyright owner]"
164.29 + *
164.30 + * Contributor(s):
164.31 + *
164.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
164.33 + */
164.34 +package org.netbeans.modules.python.source;
164.35 +
164.36 +import java.util.Comparator;
164.37 +import java.util.List;
164.38 +import javax.swing.text.Document;
164.39 +import org.netbeans.api.annotations.common.NonNull;
164.40 +import org.netbeans.api.project.FileOwnerQuery;
164.41 +import org.netbeans.api.project.Project;
164.42 +import org.netbeans.api.project.ProjectUtils;
164.43 +import org.netbeans.api.project.SourceGroup;
164.44 +import org.netbeans.api.project.Sources;
164.45 +import org.netbeans.modules.python.api.PythonMIMEResolver;
164.46 +import org.netbeans.modules.python.api.PythonPlatform;
164.47 +import org.netbeans.modules.python.api.PythonPlatformManager;
164.48 +import org.openide.filesystems.FileObject;
164.49 +import org.openide.filesystems.FileUtil;
164.50 +import org.openide.util.NbBundle;
164.51 +import org.python.antlr.PythonTree;
164.52 +import org.python.antlr.ast.Attribute;
164.53 +import org.python.antlr.ast.Name;
164.54 +
164.55 +/**
164.56 + *
164.57 + * @author Tor Norbye
164.58 + */
164.59 +public class PythonUtils {
164.60 + public static boolean canContainPython(FileObject f) {
164.61 + String mimeType = f.getMIMEType();
164.62 + return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(mimeType);
164.63 + // TODO: "text/x-yaml".equals(mimeType) || // NOI18N
164.64 + // RubyInstallation.RHTML_MIME_TYPE.equals(mimeType);
164.65 + }
164.66 +
164.67 + public static boolean isPythonFile(FileObject f) {
164.68 + return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(f.getMIMEType());
164.69 + }
164.70 +
164.71 + public static boolean isRstFile(FileObject f) {
164.72 + return "rst".equals(f.getExt()); // NOI18N
164.73 + }
164.74 +
164.75 + public static boolean isPythonDocument(Document doc) {
164.76 + String mimeType = (String)doc.getProperty("mimeType"); // NOI18N
164.77 +
164.78 + return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(mimeType);
164.79 + }
164.80 + public static final String DOT__INIT__ = ".__init__"; // NOI18N
164.81 +
164.82 + // From PythonProjectType
164.83 + public static final String SOURCES_TYPE_PYTHON = "python"; // NOI18N
164.84 +
164.85 + // Cache
164.86 + private static FileObject prevParent;
164.87 + private static String prevRootUrl;
164.88 +
164.89 + /**
164.90 + * Produce the module name (including packages) for a given python source file.
164.91 + *
164.92 + * @param fo The source file (can be null, if file is not))
164.93 + * @param file The parser file (can be null, if fo is not).
164.94 + * @param fileName The filename (basename only)
164.95 + * @param projectRelativeName If non null, the path from the project root down to this file
164.96 + * @return A string for the full package module name
164.97 + */
164.98 + public static String getModuleName(@NonNull FileObject fo) {
164.99 +
164.100 + // TODO - use PythonPlatform's library roots!
164.101 +
164.102 + String module = fo.getName();
164.103 +
164.104 + // First see if we're on the load path for the platform, and if so,
164.105 + // use that as the base
164.106 + // TODO - look up platform for the current search context instead of all platforms!!
164.107 + if (fo.getParent() != prevParent) {
164.108 + prevRootUrl = null;
164.109 + prevParent = fo.getParent();
164.110 + }
164.111 +
164.112 + String url = fo.toURL().toExternalForm();
164.113 + if (prevRootUrl == null) {
164.114 + boolean found = false;
164.115 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
164.116 +
164.117 + PlatformSearch:
164.118 + for (String name : manager.getPlatformList()) {
164.119 + PythonPlatform platform = manager.getPlatform(name);
164.120 + if (platform != null) {
164.121 + List<FileObject> unique = platform.getUniqueLibraryRoots();
164.122 + for (FileObject root : unique) {
164.123 + if (FileUtil.isParentOf(root, fo)) {
164.124 + for (FileObject r : platform.getLibraryRoots()) {
164.125 + if (FileUtil.isParentOf(r, fo)) {
164.126 + // See if the folder itself contains
164.127 + // an __init__.py file - if it does,
164.128 + // then include the directory itself
164.129 + // in the package name.
164.130 + if (r.getFileObject("__init__.py") != null) { // NOI18N
164.131 + r = r.getParent();
164.132 + }
164.133 +
164.134 + prevRootUrl = r.toURL().toExternalForm();
164.135 + found = true;
164.136 + break PlatformSearch;
164.137 + }
164.138 + }
164.139 + break PlatformSearch;
164.140 + }
164.141 + }
164.142 + }
164.143 + }
164.144 +
164.145 + if (!found) {
164.146 + Project project = FileOwnerQuery.getOwner(fo);
164.147 + if (project != null) {
164.148 + Sources source = ProjectUtils.getSources(project);
164.149 + // Look up the source path
164.150 + SourceGroup[] sourceGroups = source.getSourceGroups(SOURCES_TYPE_PYTHON);
164.151 + for (SourceGroup group : sourceGroups) {
164.152 + FileObject folder = group.getRootFolder();
164.153 + if (FileUtil.isParentOf(folder, fo)) {
164.154 + // See if the folder itself contains
164.155 + // an __init__.py file - if it does,
164.156 + // then include the directory itself
164.157 + // in the package name.
164.158 + if (folder.getFileObject("__init__.py") != null) { // NOI18N
164.159 + folder = folder.getParent();
164.160 + }
164.161 +
164.162 + prevRootUrl = folder.toURL().toExternalForm();
164.163 + break;
164.164 + }
164.165 + }
164.166 + }
164.167 + }
164.168 + }
164.169 +
164.170 + if (prevRootUrl != null) {
164.171 + module = url.substring(prevRootUrl.length());
164.172 + if (module.startsWith("/")) {
164.173 + module = module.substring(1);
164.174 + }
164.175 + }
164.176 +
164.177 + // Strip off .y extension
164.178 + if (module.endsWith(".py")) { // NOI18N
164.179 + module = module.substring(0, module.length() - 3);
164.180 + }
164.181 +
164.182 + if (module.indexOf('/') != -1) {
164.183 + module = module.replace('/', '.');
164.184 + }
164.185 +
164.186 + if (module.endsWith(DOT__INIT__)) {
164.187 + module = module.substring(0, module.length() - DOT__INIT__.length());
164.188 + }
164.189 +
164.190 + return module;
164.191 + }
164.192 +
164.193 + // According to https://hg.python.org/cpython/file/3.5/Lib/keyword.py
164.194 + // and https://hg.python.org/cpython/file/2.7/Lib/keyword.py
164.195 + static final String[] PYTHON_KEYWORDS = new String[]{
164.196 + "False", // NOI18N
164.197 + "None", // NOI18N
164.198 + "True", // NOI18N
164.199 + "and", // NOI18N
164.200 + "as", // NOI18N
164.201 + "assert", // NOI18N
164.202 + "break", // NOI18N
164.203 + "class", // NOI18N
164.204 + "continue", // NOI18N
164.205 + "def", // NOI18N
164.206 + "del", // NOI18N
164.207 + "elif", // NOI18N
164.208 + "else", // NOI18N
164.209 + "except", // NOI18N
164.210 + "finally", // NOI18N
164.211 + "for", // NOI18N
164.212 + "from", // NOI18N
164.213 + "global", // NOI18N
164.214 + "if", // NOI18N
164.215 + "import", // NOI18N
164.216 + "in", // NOI18N
164.217 + "is", // NOI18N
164.218 + "lambda", // NOI18N
164.219 + "nonlocal", // NOI18N
164.220 + "not", // NOI18N
164.221 + "or", // NOI18N
164.222 + "pass", // NOI18N
164.223 + "raise", // NOI18N
164.224 + "return", // NOI18N
164.225 + "try", // NOI18N
164.226 + "while", // NOI18N
164.227 + "with", // NOI18N
164.228 + "yield", // NOI18N
164.229 + "async", // NOI18N, Python 3.5 only
164.230 + "await", // NOI18N, Python 3.5 only
164.231 + "exec", // NOI18N, Python 2 only
164.232 + "print", // NOI18N, Pytohn 2 only, function in python 3
164.233 + };
164.234 +
164.235 + public static boolean isPythonKeyword(String name) {
164.236 + for (String s : PYTHON_KEYWORDS) {
164.237 + if (s.equals(name)) {
164.238 + return true;
164.239 + }
164.240 + }
164.241 +
164.242 + return false;
164.243 + }
164.244 +
164.245 + /**
164.246 + * Return true iff the name is a class name
164.247 + * @param name The name
164.248 + * @param emptyDefault Whether empty or _ names should be considered a class name or not
164.249 + * @return True iff the name looks like a class name
164.250 + */
164.251 + public static boolean isClassName(String name, boolean emptyDefault) {
164.252 + if (name == null || name.length() == 0) {
164.253 + return emptyDefault;
164.254 + }
164.255 + if (name.startsWith("_") && name.length() > 1) {
164.256 + return Character.isUpperCase(name.charAt(1));
164.257 + }
164.258 +
164.259 + return Character.isUpperCase(name.charAt(0));
164.260 + }
164.261 +
164.262 + /**
164.263 + * Return true iff the name is a method name
164.264 + * @param name The name
164.265 + * @param emptyDefault Whether empty or _ names should be considered a class name or not
164.266 + * @return True iff the name looks like a method name
164.267 + */
164.268 + public static boolean isMethodName(String name, boolean emptyDefault) {
164.269 + if (name == null || name.length() == 0) {
164.270 + return emptyDefault;
164.271 + }
164.272 + if (name.startsWith("__") && name.length() > 2) {
164.273 + return Character.isLowerCase(name.charAt(2));
164.274 + }
164.275 + if (name.startsWith("_") && name.length() > 1) {
164.276 + return Character.isLowerCase(name.charAt(1));
164.277 + }
164.278 +
164.279 + return Character.isLowerCase(name.charAt(0));
164.280 + }
164.281 +
164.282 + public static boolean isValidPythonClassName(String name) {
164.283 + if (isPythonKeyword(name)) {
164.284 + return false;
164.285 + }
164.286 +
164.287 + if (name.trim().length() == 0) {
164.288 + return false;
164.289 + }
164.290 +
164.291 + if (!Character.isUpperCase(name.charAt(0))) {
164.292 + return false;
164.293 + }
164.294 +
164.295 + for (int i = 1; i < name.length(); i++) {
164.296 + char c = name.charAt(i);
164.297 + if (!Character.isJavaIdentifierPart(c)) {
164.298 + return false;
164.299 + }
164.300 +
164.301 + }
164.302 +
164.303 + return true;
164.304 + }
164.305 +
164.306 + /** Is this name a valid operator name? */
164.307 + public static boolean isOperator(String name) {
164.308 + // TODO - update to Python
164.309 + if (name.length() == 0) {
164.310 + return false;
164.311 + }
164.312 +
164.313 + switch (name.charAt(0)) {
164.314 + case '+':
164.315 + return name.equals("+") || name.equals("+@");
164.316 + case '-':
164.317 + return name.equals("-") || name.equals("-@");
164.318 + case '*':
164.319 + return name.equals("*") || name.equals("**");
164.320 + case '<':
164.321 + return name.equals("<") || name.equals("<<") || name.equals("<=") || name.equals("<=>");
164.322 + case '>':
164.323 + return name.equals(">") || name.equals(">>") || name.equals(">=");
164.324 + case '=':
164.325 + return name.equals("=") || name.equals("==") || name.equals("===") || name.equals("=~");
164.326 + case '!':
164.327 + return name.equals("!=") || name.equals("!~");
164.328 + case '&':
164.329 + return name.equals("&") || name.equals("&&");
164.330 + case '|':
164.331 + return name.equals("|") || name.equals("||");
164.332 + case '[':
164.333 + return name.equals("[]") || name.equals("[]=");
164.334 + case '%':
164.335 + return name.equals("%");
164.336 + case '/':
164.337 + return name.equals("/");
164.338 + case '~':
164.339 + return name.equals("~");
164.340 + case '^':
164.341 + return name.equals("^");
164.342 + case '`':
164.343 + return name.equals("`");
164.344 + default:
164.345 + return false;
164.346 + }
164.347 + }
164.348 +
164.349 + public static boolean isValidPythonMethodName(String name) {
164.350 + if (isPythonKeyword(name)) {
164.351 + return false;
164.352 + }
164.353 +
164.354 + if (name.trim().length() == 0) {
164.355 + return false;
164.356 + }
164.357 +
164.358 + // TODO - allow operators
164.359 + if (isOperator(name)) {
164.360 + return true;
164.361 + }
164.362 +
164.363 + if (Character.isUpperCase(name.charAt(0)) || Character.isWhitespace(name.charAt(0))) {
164.364 + return false;
164.365 + }
164.366 +
164.367 + for (int i = 0; i < name.length(); i++) {
164.368 + char c = name.charAt(i);
164.369 + if (!(Character.isLetterOrDigit(c) || c == '_')) {
164.370 + return false;
164.371 + }
164.372 +
164.373 + }
164.374 +
164.375 + return true;
164.376 + }
164.377 +
164.378 + public static boolean isValidPythonIdentifier(String name) {
164.379 + if (isPythonKeyword(name)) {
164.380 + return false;
164.381 + }
164.382 +
164.383 + if (name.trim().length() == 0) {
164.384 + return false;
164.385 + }
164.386 +
164.387 + for (int i = 0; i < name.length(); i++) {
164.388 + // Identifier char isn't really accurate - I can have a function named "[]" etc.
164.389 + // so just look for -obvious- mistakes
164.390 + if (Character.isWhitespace(name.charAt(i))) {
164.391 + return false;
164.392 + }
164.393 +
164.394 + // TODO - make this more accurate, like the method validifier
164.395 + }
164.396 +
164.397 + return true;
164.398 + }
164.399 +
164.400 + /**
164.401 + * Ruby identifiers should consist of [a-zA-Z0-9_]
164.402 + * http://www.headius.com/rubyspec/index.php/Variables
164.403 + * <p>
164.404 + * This method also accepts the field/global chars
164.405 + * since it's unlikely
164.406 + */
164.407 + public static boolean isSafeIdentifierName(String name, int fromIndex) {
164.408 + int i = fromIndex;
164.409 + for (; i < name.length(); i++) {
164.410 + char c = name.charAt(i);
164.411 + if (!(c == '$' || c == '@' || c == ':')) {
164.412 + break;
164.413 + }
164.414 + }
164.415 + for (; i < name.length(); i++) {
164.416 + char c = name.charAt(i);
164.417 + if (!((c >= 'a' && c <= 'z') || (c == '_') ||
164.418 + (c >= 'A' && c <= 'Z') ||
164.419 + (c >= '0' && c <= '9') ||
164.420 + (c == '?') || (c == '=') || (c == '!'))) { // Method suffixes; only allowed on the last line
164.421 +
164.422 + if (isOperator(name)) {
164.423 + return true;
164.424 + }
164.425 +
164.426 + return false;
164.427 + }
164.428 + }
164.429 +
164.430 + return true;
164.431 + }
164.432 +
164.433 + /**
164.434 + * Return null if the given identifier name is valid, otherwise a localized
164.435 + * error message explaining the problem.
164.436 + */
164.437 + public static String getIdentifierWarning(String name, int fromIndex) {
164.438 + if (isSafeIdentifierName(name, fromIndex)) {
164.439 + return null;
164.440 + } else {
164.441 + return NbBundle.getMessage(PythonUtils.class, "UnsafeIdentifierName");
164.442 + }
164.443 + }
164.444 +
164.445 + /** @todo Move into GsfUtilities after 6.5 */
164.446 + public static int getOffsetByLineCol(String source, int line, int col) {
164.447 + int offset = 0;
164.448 + for (int i = 0; i < line; i++) {
164.449 + offset = source.indexOf('\n', offset);
164.450 + if (offset == -1) {
164.451 + offset = source.length();
164.452 + break;
164.453 + }
164.454 + offset++;
164.455 + }
164.456 + if (col > 0) { // -1: invalid
164.457 + offset += col;
164.458 + }
164.459 +
164.460 + return offset;
164.461 + }
164.462 + public static Comparator NAME_NODE_COMPARATOR = new Comparator<Name>() {
164.463 + @Override
164.464 + public int compare(Name n1, Name n2) {
164.465 + return n1.getInternalId().compareTo(n2.getInternalId());
164.466 + }
164.467 + };
164.468 + public static Comparator ATTRIBUTE_NAME_NODE_COMPARATOR = new Comparator<Object>() {
164.469 + @SuppressWarnings("unchecked")
164.470 + @Override
164.471 + public int compare(Object n1, Object n2) {
164.472 + String s1 = "";
164.473 + String s2 = "";
164.474 +
164.475 + if (n1 instanceof Name) {
164.476 + s1 = ((Name)n1).getInternalId();
164.477 + } else if (n1 instanceof Attribute) {
164.478 + Attribute a = (Attribute)n1;
164.479 + String v = PythonAstUtils.getName(a.getInternalValue());
164.480 + if (v != null) {
164.481 + s1 = a.getInternalAttr() + "." + v;
164.482 + } else {
164.483 + s1 = a.getInternalAttr();
164.484 + }
164.485 + }
164.486 +
164.487 + if (n2 instanceof Name) {
164.488 + s2 = ((Name)n2).getInternalId();
164.489 + } else if (n2 instanceof Attribute) {
164.490 + Attribute a = (Attribute)n2;
164.491 + String v = PythonAstUtils.getName(a.getInternalValue());
164.492 + if (v != null) {
164.493 + s2 = a.getInternalAttr() + "." + v;
164.494 + } else {
164.495 + s2 = a.getInternalAttr();
164.496 + }
164.497 + }
164.498 +
164.499 + return s1.compareTo(s2);
164.500 + }
164.501 + };
164.502 + public static Comparator NODE_POS_COMPARATOR = new Comparator<PythonTree>() {
164.503 + @Override
164.504 + public int compare(PythonTree p1, PythonTree p2) {
164.505 + int ret = p1.getCharStartIndex() - p2.getCharStartIndex();
164.506 + if (ret != 0) {
164.507 + return ret;
164.508 + }
164.509 + ret = p2.getCharStopIndex() - p1.getCharStopIndex();
164.510 + if (ret != 0) {
164.511 + return ret;
164.512 + }
164.513 + return p2.getAntlrType() - p1.getAntlrType();
164.514 + }
164.515 + };
164.516 +}
165.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
165.2 +++ b/python.source/src/org/netbeans/modules/python/source/RstFormatter.java Mon Sep 21 13:01:16 2015 +0200
165.3 @@ -0,0 +1,1342 @@
165.4 +/*
165.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
165.6 + *
165.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
165.8 + *
165.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
165.10 + * Other names may be trademarks of their respective owners.
165.11 + *
165.12 + * The contents of this file are subject to the terms of either the GNU
165.13 + * General Public License Version 2 only ("GPL") or the Common
165.14 + * Development and Distribution License("CDDL") (collectively, the
165.15 + * "License"). You may not use this file except in compliance with the
165.16 + * License. You can obtain a copy of the License at
165.17 + * http://www.netbeans.org/cddl-gplv2.html
165.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
165.19 + * specific language governing permissions and limitations under the
165.20 + * License. When distributing the software, include this License Header
165.21 + * Notice in each file and include the License file at
165.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
165.23 + * particular file as subject to the "Classpath" exception as provided
165.24 + * by Oracle in the GPL Version 2 section of the License file that
165.25 + * accompanied this code. If applicable, add the following below the
165.26 + * License Header, with the fields enclosed by brackets [] replaced by
165.27 + * your own identifying information:
165.28 + * "Portions Copyrighted [year] [name of copyright owner]"
165.29 + *
165.30 + * If you wish your version of this file to be governed by only the CDDL
165.31 + * or only the GPL Version 2, indicate your decision by adding
165.32 + * "[Contributor] elects to include this software in this distribution
165.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
165.34 + * single choice of license, a recipient has the option to distribute
165.35 + * your version of this file under either the CDDL, the GPL Version 2 or
165.36 + * to extend the choice of license to its licensees as provided above.
165.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
165.38 + * Version 2 license, then the option applies only if the new code is
165.39 + * made subject to such option by the copyright holder.
165.40 + *
165.41 + * Contributor(s):
165.42 + *
165.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
165.44 + */
165.45 +package org.netbeans.modules.python.source;
165.46 +
165.47 +import java.awt.Color;
165.48 +import java.io.CharConversionException;
165.49 +import java.util.ArrayList;
165.50 +import java.util.Collections;
165.51 +import java.util.List;
165.52 +import javax.swing.text.AttributeSet;
165.53 +import javax.swing.text.BadLocationException;
165.54 +import javax.swing.text.StyleConstants;
165.55 +import org.netbeans.api.editor.mimelookup.MimeLookup;
165.56 +import org.netbeans.api.editor.mimelookup.MimePath;
165.57 +import org.netbeans.api.editor.settings.FontColorSettings;
165.58 +import org.netbeans.api.lexer.Language;
165.59 +import org.netbeans.api.lexer.Token;
165.60 +import org.netbeans.api.lexer.TokenHierarchy;
165.61 +import org.netbeans.api.lexer.TokenSequence;
165.62 +import org.netbeans.editor.BaseDocument;
165.63 +import org.netbeans.modules.csl.api.ElementHandle;
165.64 +import org.netbeans.modules.csl.api.ElementKind;
165.65 +import org.netbeans.modules.csl.spi.GsfUtilities;
165.66 +import org.netbeans.modules.csl.spi.ParserResult;
165.67 +import org.netbeans.modules.python.api.PythonMIMEResolver;
165.68 +import org.netbeans.modules.python.source.elements.Element;
165.69 +import org.netbeans.modules.python.source.elements.IndexedElement;
165.70 +import org.netbeans.modules.python.source.elements.IndexedMethod;
165.71 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
165.72 +import org.openide.filesystems.FileObject;
165.73 +import org.openide.util.Exceptions;
165.74 +import org.openide.util.Lookup;
165.75 +import org.openide.xml.XMLUtil;
165.76 +import org.python.antlr.PythonTree;
165.77 +
165.78 +/**
165.79 + * Support for reStructured text. Parse .rst files and rst content in
165.80 + * Python doc strings and format it as HTML. Also provide functions
165.81 + * to locate a code element in RST files.
165.82 + * @see http://www.python.org/dev/peps/pep-0287/
165.83 + * @see http://docutils.sourceforge.net/docs/user/rst/quickstart.html
165.84 + *
165.85 + * @todo Render verbatim blocks
165.86 + * @todo Syntax highlight verbatim blocks?
165.87 + * @todo Render *bold* and `identifier` stuff
165.88 + * @todo For class definitions which nest the method documentation,
165.89 + * try to remove all items, or perhaps just make it shorter
165.90 + * @todo Render note:: into something cleaner etc.
165.91 + *
165.92 + * @author Tor Norbye
165.93 + */
165.94 +public class RstFormatter {
165.95 + private static final String BRBR = "\n<br><br>\n"; // NOI18N
165.96 + private StringBuilder sb = new StringBuilder();
165.97 + private boolean lastWasEmpty = false;
165.98 + private int beginPos;
165.99 + private boolean inVerbatim;
165.100 + private boolean inIndex;
165.101 + private boolean inTable;
165.102 + private boolean inDiv;
165.103 + private int lastIndent;
165.104 + private boolean maybeVerbatim;
165.105 + private boolean inDocTest;
165.106 + private List<String> code;
165.107 +
165.108 + public RstFormatter() {
165.109 + }
165.110 +
165.111 + private void flush() {
165.112 + if (inTable) {
165.113 + sb.append("</pre>\n"); // NOI18N
165.114 + inTable = false;
165.115 + inVerbatim = false;
165.116 + } else if (inVerbatim) {
165.117 + // Process code and format as Python
165.118 + String html = getPythonHtml(code, true);
165.119 + if (html != null) {
165.120 + // <pre> tag is added as part of the rubyhtml (since it
165.121 + // needs to pick up the background color from the syntax
165.122 + // coloring settings)
165.123 + sb.append(html);
165.124 + } else {
165.125 + sb.append("<pre style=\"margin: 5px 5px; background: #ffffdd; border-size: 1px; padding: 5px\">"); // NOI18N
165.126 + sb.append("\n"); // NOI18N
165.127 + // Some kind of error; normal append
165.128 + for (String s : code) {
165.129 + appendEscaped(s);
165.130 + sb.append("<br>"); // NOI18N
165.131 + }
165.132 + sb.append("</pre>\n"); // NOI18N
165.133 + }
165.134 + inVerbatim = false;
165.135 + code = null;
165.136 + } else if (inDiv) {
165.137 + sb.append("</div>\n"); // NOI18N
165.138 + inDiv = false;
165.139 + }
165.140 + }
165.141 +
165.142 + private void appendEscaped(char c) {
165.143 + if ('<' == c) {
165.144 + sb.append("<"); // NOI18N
165.145 + } else if ('&' == c) {
165.146 + sb.append("&"); // NOI18N
165.147 + } else {
165.148 + sb.append(c);
165.149 + }
165.150 + }
165.151 +
165.152 + private void appendEscaped(CharSequence s) {
165.153 + for (int i = 0, n = s.length(); i < n; i++) {
165.154 + char c = s.charAt(i);
165.155 + if ('<' == c) {
165.156 + sb.append("<"); // NOI18N
165.157 + } else if ('&' == c) {
165.158 + sb.append("&"); // NOI18N
165.159 + } else {
165.160 + sb.append(c);
165.161 + }
165.162 + }
165.163 + }
165.164 +
165.165 + private int appendColonCmd(String line, int i, String marker, boolean url) throws CharConversionException {
165.166 + String MARKER = ":" + marker + ":`"; // NOI18N
165.167 + if (line.startsWith(MARKER, i)) {
165.168 + int end = line.indexOf("`", i + MARKER.length()); // NOI18N
165.169 + if (end != -1) {
165.170 + String token = line.substring(i + MARKER.length(), end);
165.171 + if (url) {
165.172 + sb.append("<a href=\""); // NOI18N
165.173 + if ("pep".equals(marker)) { // NOI18N
165.174 + sb.append("http://www.python.org/dev/peps/pep-"); // NOI18N
165.175 + for (int j = 0; j < 4 - token.length(); j++) {
165.176 + sb.append("0");
165.177 + }
165.178 + sb.append(token);
165.179 + sb.append("/"); // NOI18N
165.180 + sb.append("\">PEP "); // NOI18N
165.181 + sb.append(token);
165.182 + sb.append("</a>");
165.183 + return end;
165.184 + } else {
165.185 + sb.append(marker);
165.186 + sb.append(":"); // NOI18N
165.187 + appendEscaped(token);
165.188 + }
165.189 + sb.append("\">"); // NOI18N
165.190 + } else if (marker.equals("keyword")) { // NOI18N
165.191 + sb.append("<code style=\""); // NOI18N
165.192 +
165.193 + MimePath mimePath = MimePath.parse(PythonMIMEResolver.PYTHON_MIME_TYPE);
165.194 + Lookup lookup = MimeLookup.getLookup(mimePath);
165.195 + FontColorSettings fcs = lookup.lookup(FontColorSettings.class);
165.196 +
165.197 + AttributeSet attribs = fcs.getTokenFontColors("keyword"); // NOI18N
165.198 + Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
165.199 + if (fg != null) {
165.200 + sb.append("color:"); // NOI18N
165.201 + sb.append(getHtmlColor(fg));
165.202 + sb.append(";"); // NOI18N
165.203 + }
165.204 + Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
165.205 + // Only set the background for dark colors
165.206 + if (bg != null && bg.getRed() < 128) {
165.207 + sb.append("background:"); // NOI18N
165.208 + sb.append(getHtmlColor(bg));
165.209 + }
165.210 +
165.211 + sb.append("\">"); // NOI18N
165.212 + } else {
165.213 + sb.append("<code>"); // NOI18N
165.214 + }
165.215 + appendEscaped(token);
165.216 + if (url) {
165.217 + sb.append("</a>"); // NOI18N
165.218 + } else {
165.219 + sb.append("</code>"); // NOI18N
165.220 + }
165.221 + //return end+1; // instead of end+2: get to end of ``, minus loop increment
165.222 + return end; // instead of end+2: get to end of ``, minus loop increment
165.223 + }
165.224 + }
165.225 +
165.226 + return -1;
165.227 + }
165.228 +
165.229 + private void appendRstLine(String line) throws CharConversionException {
165.230 + int n = line.length();
165.231 + char prev = 0;
165.232 + Loop:
165.233 + for (int i = 0; i < n; i++) {
165.234 + char c = line.charAt(i);
165.235 + if (c == '`') {
165.236 + if (i < n - 2 && line.charAt(i + 1) == '`') {
165.237 + // See if it's an ``identifier``
165.238 + int end = line.indexOf("``", i + 2);
165.239 + if (end != -1) {
165.240 + sb.append("<code>"); // NOI18N
165.241 + appendEscaped(line.substring(i + 2, end));
165.242 + sb.append("</code>"); // NOI18N
165.243 + i = end + 1; // instead of end+2: get to end of ``, minus loop increment
165.244 + continue;
165.245 + }
165.246 + } else {
165.247 + // Single identifier
165.248 + for (int j = i + 1; j < n; j++) {
165.249 + char d = line.charAt(j);
165.250 + if (d == '`') {
165.251 + sb.append("<code>"); // NOI18N
165.252 + appendEscaped(line.substring(i + 1, j));
165.253 + sb.append("</code>"); // NOI18N
165.254 + i = j;
165.255 + continue Loop;
165.256 + } else if (!Character.isJavaIdentifierPart(d)) {
165.257 + break;
165.258 + }
165.259 + }
165.260 + }
165.261 + } else if (c == ':') {
165.262 + int nextI = appendColonCmd(line, i, "class", true); // NOI18N
165.263 + if (nextI == -1) {
165.264 + nextI = appendColonCmd(line, i, "exc", true); // NOI18N
165.265 + if (nextI == -1) {
165.266 + nextI = appendColonCmd(line, i, "var", false); // NOI18N
165.267 + if (nextI == -1) {
165.268 + nextI = appendColonCmd(line, i, "meth", true); // NOI18N
165.269 + if (nextI == -1) {
165.270 + nextI = appendColonCmd(line, i, "func", true); // NOI18N
165.271 + if (nextI == -1) {
165.272 + nextI = appendColonCmd(line, i, "data", false); // NOI18N
165.273 + if (nextI == -1) {
165.274 + nextI = appendColonCmd(line, i, "attr", false); // NOI18N
165.275 + if (nextI == -1) {
165.276 + nextI = appendColonCmd(line, i, "envvar", false); // NOI18N
165.277 + if (nextI == -1) {
165.278 + nextI = appendColonCmd(line, i, "mod", true); // NOI18N
165.279 + if (nextI == -1) {
165.280 + nextI = appendColonCmd(line, i, "pep", true); // NOI18N
165.281 + if (nextI == -1) {
165.282 + nextI = appendColonCmd(line, i, "ref", false); // NOI18N
165.283 + if (nextI == -1) {
165.284 + nextI = appendColonCmd(line, i, "mod", true); // NOI18N
165.285 + if (nextI == -1) {
165.286 + nextI = appendColonCmd(line, i, "keyword", false); // NOI18N
165.287 + if (nextI == -1) {
165.288 + if (line.startsWith(":noindex:", i)) { // NOI18N
165.289 + nextI = i + 9;
165.290 + } else if (line.startsWith(":synopsis:", i)) { // NOI18N
165.291 + nextI = i + 10;
165.292 + } else if (line.startsWith(":deprecated:", i)) {
165.293 + sb.append("Deprecated. ");
165.294 + nextI = i + 12;
165.295 + } else if (line.startsWith(":platform:", i)) {
165.296 + sb.append("Platform: ");
165.297 + nextI = i + 10;
165.298 + }
165.299 + }
165.300 + }
165.301 + }
165.302 + }
165.303 + }
165.304 + }
165.305 + }
165.306 + }
165.307 + }
165.308 + }
165.309 + }
165.310 + }
165.311 + }
165.312 + if (nextI != -1) {
165.313 + i = nextI;
165.314 + continue;
165.315 + }
165.316 + } else if (c == '*') {
165.317 + // Bold?
165.318 + if (i < n - 1 && Character.isJavaIdentifierPart(line.charAt(i + 1)) && !Character.isJavaIdentifierPart(prev)) { // TODO Use PythonUtils
165.319 + // Peek ahead to see if we have [not-identifier-char]*[identifierchars]*[not-identifier-chars]
165.320 + for (int j = i + 1; j < n; j++) {
165.321 + char d = line.charAt(j);
165.322 + if (d == '*') {
165.323 + if (j == n - 1 || !Character.isJavaIdentifierPart(line.charAt(j + 1))) {
165.324 + // Yess, make bold
165.325 + sb.append("<b>"); // NOI18N
165.326 + appendEscaped(line.substring(i + 1, j));
165.327 + sb.append("</b>"); // NOI18N
165.328 + i = j;
165.329 + continue Loop;
165.330 + }
165.331 + } else if (!Character.isJavaIdentifierPart(d)) {
165.332 + break;
165.333 + }
165.334 + }
165.335 + }
165.336 + } // TODO: :addedin, :deprecated, etc
165.337 +
165.338 + appendEscaped(c);
165.339 + prev = c;
165.340 + }
165.341 + }
165.342 +
165.343 + public void append(String line) {
165.344 + try {
165.345 + String trim = line.trim();
165.346 + if (trim.length() == 0) {
165.347 + inDocTest = false;
165.348 + if (inIndex) {
165.349 + // Completely swallow all indexing entries
165.350 + return;
165.351 + } else if (inTable) {
165.352 + sb.append("</pre>\n"); // NOI18N
165.353 + inVerbatim = false;
165.354 + inTable = false;
165.355 + } else if (inVerbatim) {
165.356 + sb.append("\n"); // NOI18N
165.357 + } else if (!lastWasEmpty && sb.length() > beginPos) {
165.358 + sb.append(BRBR); // NOI18N
165.359 + }
165.360 + lastWasEmpty = true;
165.361 + } else {
165.362 + if (!lastWasEmpty && trim.startsWith("- ")) { // NOI18N
165.363 + // lists - make sure they're on a new line
165.364 + sb.append("<br>"); // NOI18N
165.365 + }
165.366 +
165.367 + lastWasEmpty = false;
165.368 +
165.369 + if (maybeVerbatim) {
165.370 + int indent = getIndentation(line, 0);
165.371 + if (indent > lastIndent) {
165.372 + // Truncate last whitespace separator before <pre> if any
165.373 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
165.374 + sb.setLength(sb.length() - BRBR.length());
165.375 + }
165.376 + inVerbatim = true;
165.377 + code = new ArrayList<>();
165.378 + code.add(line);
165.379 + maybeVerbatim = false;
165.380 + return;
165.381 + }
165.382 + maybeVerbatim = false;
165.383 + } else if (inVerbatim || inTable) {
165.384 + int indent = getIndentation(line, 0);
165.385 + if (indent <= lastIndent) {
165.386 +//// // Truncate trailing whitespace
165.387 +//// while (sb.length() > 0 && sb.charAt(sb.length()-1) == '\n') {
165.388 +//// sb.setLength(sb.length()-1);
165.389 +//// }
165.390 +//// sb.append("</pre>"); // NOI18N
165.391 +// inVerbatim = false;
165.392 +// inTable = false;
165.393 + flush();
165.394 + lastWasEmpty = true;
165.395 + } else if (inVerbatim) {
165.396 + // We need to buffer up the text such that we can lex it as a unit
165.397 + // (and determine when done with the section if it's code or regular text)
165.398 + code.add(line);
165.399 + return;
165.400 + } else {
165.401 + appendEscaped(line);
165.402 + sb.append("\n"); // NOI18N
165.403 + return;
165.404 + }
165.405 + } else if (inDiv) {
165.406 + int indent = getIndentation(line, 0);
165.407 + if (indent <= lastIndent) {
165.408 + // Truncate last whitespace separator before <pre> if any
165.409 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
165.410 + sb.setLength(sb.length() - BRBR.length());
165.411 + }
165.412 + sb.append("</div>\n"); // NOI18N
165.413 + inDiv = false;
165.414 + lastWasEmpty = true;
165.415 + } else {
165.416 + appendRstLine(line);
165.417 + sb.append("\n"); // NOI18N
165.418 + return;
165.419 + }
165.420 + } else if (inIndex) {
165.421 + int indent = getIndentation(line, 0);
165.422 + if (indent <= lastIndent) {
165.423 + inIndex = false;
165.424 + lastWasEmpty = true;
165.425 + } else {
165.426 + return;
165.427 + }
165.428 +
165.429 + }
165.430 +
165.431 + if (trim.startsWith(".. method:: ")) { // NOI18N
165.432 + String sig = trim.substring(12).trim();
165.433 + sb.append("<a href=\"meth:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
165.434 + return;
165.435 + } else if (trim.startsWith(".. function:: ")) { // NOI18N
165.436 + String sig = trim.substring(14).trim();
165.437 + sb.append("<a href=\"func:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
165.438 + return;
165.439 + } else if (trim.startsWith(".. class:: ")) { // NOI18N
165.440 + String sig = trim.substring(11).trim();
165.441 + sb.append("<a href=\"class:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
165.442 + return;
165.443 + } else if (trim.startsWith(".. attribute:: ")) { // NOI18N
165.444 + String sig = trim.substring(15).trim();
165.445 + sb.append("<a href=\"attr:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
165.446 + return;
165.447 + } else if (trim.startsWith(".. data:: ")) { // NOI18N
165.448 + String sig = trim.substring(10).trim();
165.449 + sb.append("<a href=\"data:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
165.450 + return;
165.451 + } else if (trim.startsWith(".. module:: ")) { // NOI18N
165.452 + String sig = trim.substring(12).trim();
165.453 + sb.append("<a href=\"module:" + sig.replace("\"", """) + "\">" + sig + "</a>"); // NOI18N
165.454 + sb.append("<br>\n");
165.455 + return;
165.456 + } else if (trim.startsWith(".. productionlist:")) {
165.457 + lastIndent = getIndentation(line, 0);
165.458 + inVerbatim = true;
165.459 + code = new ArrayList<>();
165.460 + code.add(line);
165.461 + maybeVerbatim = false;
165.462 + return;
165.463 + }
165.464 +
165.465 + if (trim.startsWith(">>>") || inDocTest) { // NOI18N
165.466 + if (!trim.startsWith(">>>")) { // NOI18N
165.467 + sb.append("<code>"); // NOI18N
165.468 + appendEscaped(line); // NOI18N
165.469 + // Wait until there is an empty line before we mark doctest done!
165.470 + // inDocTest = false;
165.471 + sb.append("</code><br>"); // NOI18N
165.472 + } else {
165.473 + sb.append("<code>"); // NOI18N
165.474 + appendEscaped(">>>"); // NOI18N
165.475 + String html = getPythonHtml(Collections.singletonList(trim.substring(3)), false);
165.476 + sb.append(html);
165.477 + sb.append("</code>"); // NOI18N
165.478 + inDocTest = true;
165.479 + }
165.480 + return;
165.481 + }
165.482 + inDocTest = false;
165.483 +
165.484 + if (trim.startsWith(".. note::") || trim.startsWith(".. warning::") || trim.startsWith(".. seealso:")) { // NOI18N
165.485 + // Truncate last whitespace separator before <pre> if any
165.486 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
165.487 + sb.setLength(sb.length() - BRBR.length());
165.488 + }
165.489 + sb.append("<div style=\"margin: 5px 5px; "); // NOI18N
165.490 + if (!trim.contains("seealso")) { // NOI18N
165.491 + sb.append("background: #ffdddd; "); // NOI18N
165.492 + } else {
165.493 + sb.append("background: #ddffdd; "); // NOI18N
165.494 + }
165.495 + sb.append("border-size: 1px; padding: 5px\">"); // NOI18N
165.496 + if (trim.contains("note:")) {
165.497 + sb.append("<b>NOTE</b>: "); // NOI18N
165.498 + } else if (trim.contains("warning")) {
165.499 + sb.append("<b>WARNING</b>: "); // NOI18N
165.500 + } else {
165.501 + sb.append("<b>See Also</b>: "); // NOI18N
165.502 + }
165.503 + sb.append("\n"); // NOI18N
165.504 + inDiv = true;
165.505 + lastIndent = getIndentation(line, 0);
165.506 + maybeVerbatim = false;
165.507 + return;
165.508 + } else if (trim.startsWith(".. versionadded::") || trim.startsWith(".. versionchanged::") || trim.startsWith(".. deprecated::")) { // NOI18N
165.509 + // Truncate last whitespace separator before <pre> if any
165.510 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
165.511 + sb.setLength(sb.length() - BRBR.length());
165.512 + }
165.513 + sb.append("<div style=\"margin: 5px 5px; background: #dddddd; border-size: 1px; padding: 5px\">"); // NOI18N
165.514 + if (trim.contains("added:")) {
165.515 + sb.append("<b>Version Added</b>: "); // NOI18N
165.516 + } else if (trim.contains("changed")) {
165.517 + sb.append("<b>Version Changed</b>: "); // NOI18N
165.518 + } else {
165.519 + assert trim.contains("deprecated"); // NOI18N
165.520 + sb.append("<b>Deprecated</b>: "); // NOI18N
165.521 + }
165.522 + sb.append(trim.substring(trim.indexOf("::") + 2));
165.523 + sb.append("\n"); // NOI18N
165.524 + inDiv = true;
165.525 + lastIndent = getIndentation(line, 0);
165.526 + maybeVerbatim = false;
165.527 + return;
165.528 + } else if (trim.startsWith(".. index:")) { // NOI18N
165.529 + inIndex = true;
165.530 + lastIndent = getIndentation(line, 0);
165.531 + return;
165.532 + } else if (trim.startsWith(".. _") && trim.endsWith(":")) {
165.533 + // skip lines like .. _pyzipfile-objects:
165.534 + return;
165.535 + } else if (trim.startsWith(".. moduleauthor::") || trim.startsWith(".. sectionauthor::")) { // NOI18N
165.536 + if (trim.startsWith(".. mod")) {
165.537 + sb.append("<br>Module Author:</b>");
165.538 + } else {
165.539 + sb.append("<br>Section Author:</b>");
165.540 + }
165.541 + appendEscaped(trim.substring(trim.indexOf("::") + 2)); //
165.542 + sb.append("\n");
165.543 + return;
165.544 + } else if (trim.endsWith("::")) { // NOI18N
165.545 + maybeVerbatim = true;
165.546 + lastIndent = getIndentation(line, 0);
165.547 + } else if (trim.startsWith("+-----")) { // NOI18N
165.548 + // A table
165.549 + sb.append("<pre>"); // NOI18N
165.550 + appendEscaped(line);
165.551 + sb.append("\n"); // NOI18N
165.552 + inTable = true;
165.553 + lastIndent = getIndentation(line, 0) - 1;
165.554 + return;
165.555 + } else if (line.startsWith("======") || line.startsWith("------") || line.startsWith("******") || line.startsWith("^^^^^^^^")) { // NOI18N
165.556 + // PREVIOUS line could be a title.
165.557 + // Note -- we're comparing on "line" and not "trim" here because in indented contexts,
165.558 + // === sometimes represents parts of tables -- see the turtle.rst file for examples.
165.559 +
165.560 + int n = sb.length();
165.561 + if (n > 0 && sb.charAt(n - 1) == '\n') {
165.562 + n--;
165.563 + }
165.564 + int index = n - 1;
165.565 + for (; index >= 0; index--) {
165.566 + char c = sb.charAt(index);
165.567 + if (c == '\n') {
165.568 + index++;
165.569 + break;
165.570 + }
165.571 + }
165.572 + if (index == -1) {
165.573 + index = 0;
165.574 + }
165.575 + // Index now points to the beginning of the previous line
165.576 + boolean empty = true;
165.577 +// boolean okay = true;
165.578 + int start = index;
165.579 + for (; index < n; index++) {
165.580 + char c = sb.charAt(index);
165.581 + if (c == '\n') {
165.582 + break;
165.583 + }
165.584 + empty = false;
165.585 +// if (c == '<') {
165.586 +// okay = false;
165.587 +// }
165.588 + }
165.589 + if (!empty/* && okay*/) {
165.590 + String tag = "h2"; // NOI18N
165.591 + if (line.startsWith("-") || line.startsWith("^")) { // NOI18N
165.592 + tag = "h3"; // NOI18N
165.593 + }
165.594 + sb.insert(start, "<" + tag + ">"); // NOI18N
165.595 + sb.append("</" + tag + ">\n"); // NOI18N
165.596 + lastWasEmpty = true;
165.597 + return;
165.598 + }
165.599 + }
165.600 +
165.601 + //sb.append(line);
165.602 + appendRstLine(line);
165.603 +
165.604 + sb.append("\n"); // NOI18N
165.605 + }
165.606 + } catch (CharConversionException ex) {
165.607 + Exceptions.printStackTrace(ex);
165.608 + }
165.609 + }
165.610 +
165.611 + public void appendSignature(Element element) {
165.612 + sb.append("<pre>"); // NOI18N
165.613 +
165.614 + if (element instanceof IndexedMethod) {
165.615 + IndexedMethod executable = (IndexedMethod)element;
165.616 + if (element.getIn() != null && !PythonIndex.isBuiltinModule(element.getIn())) {
165.617 + String in = element.getIn();
165.618 + sb.append("<i>"); // NOI18N
165.619 + sb.append(in);
165.620 + sb.append("</i>"); // NOI18N
165.621 + sb.append("<br>"); // NOI18N
165.622 + }
165.623 + // TODO - share this between Navigator implementation and here...
165.624 + sb.append("<b>"); // NOI18N
165.625 + sb.append(element.getName());
165.626 + sb.append("</b>"); // NOI18N
165.627 + String[] parameters = executable.getParams();
165.628 +
165.629 + if ((parameters != null) && (parameters.length > 0)) {
165.630 + sb.append("("); // NOI18N
165.631 +
165.632 + sb.append("<font color=\"#808080\">"); // NOI18N
165.633 +
165.634 + boolean first = true;
165.635 + for (String parameter : parameters) {
165.636 + if (first) {
165.637 + first = false;
165.638 + } else {
165.639 + sb.append(", ");
165.640 + }
165.641 + sb.append(parameter);
165.642 + }
165.643 +
165.644 + sb.append("</font>"); // NOI18N
165.645 +
165.646 + sb.append(")"); // NOI18N
165.647 + }
165.648 + } else if (element instanceof IndexedElement) {
165.649 + //IndexedElement clz = (IndexedElement)element;
165.650 + String name = element.getName();
165.651 +// final String fqn = clz.getFqn();
165.652 +// if (fqn != null && !name.equals(fqn)) {
165.653 +// signature.append("<i>"); // NOI18N
165.654 +// signature.append(fqn); // NOI18N
165.655 +// signature.append("</i>"); // NOI18N
165.656 +// signature.append("<br>"); // NOI18N
165.657 +// }
165.658 + sb.append("<b>"); // NOI18N
165.659 + sb.append(name);
165.660 + sb.append("</b>"); // NOI18N
165.661 + } else {
165.662 + sb.append(element.getName());
165.663 + }
165.664 +
165.665 + sb.append("</pre>\n"); // NOI18N
165.666 + }
165.667 +
165.668 + public void appendHtml(String html) {
165.669 + sb.append(html);
165.670 + }
165.671 +
165.672 + public void markEmpty() {
165.673 + beginPos = sb.length();
165.674 + }
165.675 +
165.676 + public String toHtml() {
165.677 + flush();
165.678 + return sb.toString();
165.679 + }
165.680 +
165.681 + public static String document(String rst) {
165.682 + RstFormatter formatter = new RstFormatter();
165.683 + String[] lines = rst.split("\n"); // NOI18N
165.684 + for (String line : lines) {
165.685 + formatter.append(line);
165.686 + }
165.687 + return formatter.toHtml();
165.688 + }
165.689 +
165.690 + public static String getDocumentation(IndexedElement indexedElement) {
165.691 + RstFormatter formatter = new RstFormatter();
165.692 + FileObject fileObject = indexedElement.getFileObject();
165.693 + if (fileObject == null) {
165.694 + return null;
165.695 + }
165.696 + BaseDocument document = GsfUtilities.getDocument(fileObject, true);
165.697 + if (document == null) {
165.698 + return null;
165.699 + }
165.700 +
165.701 + String[] signatureHolder = new String[1];
165.702 + String rst = formatter.extractRst(indexedElement, document, signatureHolder);
165.703 + if (rst != null && rst.length() > 0) {
165.704 + String signature = signatureHolder[0];
165.705 + if (signature == null) {
165.706 + formatter.appendSignature(indexedElement);
165.707 + formatter.appendHtml("\n<hr>\n"); // NOI18N
165.708 + formatter.markEmpty();
165.709 + } else {
165.710 + formatter.appendHtml("<pre>"); // NOI18N
165.711 + formatter.appendHtml("<b>"); // NOI18N
165.712 + int paren = signature.indexOf('(');
165.713 + if (paren != -1) {
165.714 + formatter.appendHtml(signature.substring(0, paren));
165.715 + formatter.appendHtml("</b>"); // NOI18N
165.716 + formatter.appendHtml("<font color=\"#808080\">"); // NOI18N
165.717 + formatter.appendHtml(signature.substring(paren));
165.718 + formatter.appendHtml("</font>"); // NOI18N
165.719 + } else {
165.720 + formatter.appendHtml(signature);
165.721 + formatter.appendHtml("()"); // NOI18N
165.722 + formatter.appendHtml("</b>"); // NOI18N
165.723 + }
165.724 + formatter.appendHtml("</pre>"); // NOI18N
165.725 + formatter.appendHtml("\n<hr>\n"); // NOI18N
165.726 + formatter.markEmpty();
165.727 + }
165.728 +
165.729 + String[] lines = rst.split("\n"); // NOI18N
165.730 + for (String line : lines) {
165.731 + formatter.append(line);
165.732 + }
165.733 + return formatter.toHtml();
165.734 + }
165.735 +
165.736 + return null;
165.737 + }
165.738 +
165.739 + /**
165.740 + * Find the reStructured text for the documentation for the given element
165.741 + * in the given RST document
165.742 + * @param indexedElement
165.743 + * @param document
165.744 + * @return
165.745 + */
165.746 + private String extractRst(IndexedElement element, BaseDocument doc, String[] signatureHolder) {
165.747 + return extractRst(element.getName(), element.getClz(), element.getKind(), doc, signatureHolder);
165.748 + }
165.749 +
165.750 + String extractRst(String name, String clz, ElementKind kind, BaseDocument doc, String[] signatureHolder) {
165.751 + try {
165.752 + String text = doc.getText(0, doc.getLength());
165.753 + // What about functions?
165.754 + if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
165.755 + int offset = findElementMatch(text, "function::", name, true); // NOI18N
165.756 + if (offset == -1) {
165.757 + offset = findElementMatch(text, "method::", name, false); // NOI18N
165.758 + if (offset == -1 && kind == ElementKind.CONSTRUCTOR) {
165.759 + offset = findElementMatch(text, "class::", name, false); // NOI18N
165.760 + if (offset == -1 && clz != null && clz.length() > 0 && "__init__".equals(name)) { // NOI18N
165.761 + offset = findElementMatch(text, "method::", clz, false); // NOI18N
165.762 + if (offset == -1) {
165.763 + offset = findElementMatch(text, "class::", clz, false); // NOI18N
165.764 + }
165.765 + }
165.766 + }
165.767 + }
165.768 + if (offset != -1) {
165.769 + int end = findElementEnd(text, offset);
165.770 + int nextLine = getNextLineOffset(text, offset);
165.771 + if (nextLine < end) {
165.772 + if (signatureHolder != null) {
165.773 + String signature = text.substring(text.indexOf("::", offset) + 2, nextLine).trim(); // NOI18N
165.774 + signatureHolder[0] = signature;
165.775 + }
165.776 + return text.substring(nextLine, end);
165.777 + }
165.778 + }
165.779 + } else if (kind == ElementKind.CLASS) {
165.780 + int offset = findElementMatch(text, "class::", name, false); // NOI18N
165.781 + if (offset == -1) {
165.782 + offset = findElementMatch(text, "exception::", name, false); // NOI18N
165.783 + }
165.784 + if (offset != -1) {
165.785 + int end = findElementEnd(text, offset);
165.786 + int nextLine = getNextLineOffset(text, offset);
165.787 + if (nextLine < end) {
165.788 + String elementText = text.substring(nextLine, end);
165.789 + return elementText;
165.790 + }
165.791 + }
165.792 + } else if (kind == ElementKind.MODULE) {
165.793 + int offset = findElementMatch(text, "module::", name, false); // NOI18N
165.794 + if (offset == -1) {
165.795 + offset = findElementMatch(text, "currentmodule::", name, false); // NOI18N
165.796 + }
165.797 + if (offset != -1) {
165.798 + int end = findElementEnd(text, offset);
165.799 + int nextLine = getNextLineOffset(text, offset);
165.800 + if (nextLine < end) {
165.801 + String elementText = text.substring(nextLine, end);
165.802 + return elementText;
165.803 + }
165.804 + }
165.805 + } else {
165.806 +// assert kind == ElementKind.ATTRIBUTE :;
165.807 + int offset = findElementMatch(text, "data::", name, true); // NOI18N
165.808 + if (offset == -1) {
165.809 + offset = findElementMatch(text, "attribute::", name, false); // NOI18N
165.810 + }
165.811 + if (offset != -1) {
165.812 + int end = findElementEnd(text, offset);
165.813 + int nextLine = getNextLineOffset(text, offset);
165.814 + if (nextLine < end) {
165.815 + String elementText = text.substring(nextLine, end);
165.816 + return elementText;
165.817 + }
165.818 + }
165.819 + }
165.820 + } catch (BadLocationException ex) {
165.821 + Exceptions.printStackTrace(ex);
165.822 + return "";
165.823 + }
165.824 +
165.825 +// while (true) {
165.826 +// try {
165.827 +// int ret = doc.find(new FinderFactory.StringFwdFinder(".. " + key + "::", true), offset, -1);
165.828 +// if (ret == -1) {
165.829 +// break;
165.830 +// }
165.831 +// } catch (BadLocationException ex) {
165.832 +// Exceptions.printStackTrace(ex);
165.833 +// }
165.834 +// }
165.835 +
165.836 +
165.837 + return "";
165.838 + }
165.839 +
165.840 + public static int getIndentation(String text, int lineBegin) {
165.841 + for (int i = lineBegin; i < text.length(); i++) {
165.842 + char c = text.charAt(i);
165.843 + if (c == '\n') {
165.844 + // Empty lines don't count
165.845 + return -1;
165.846 + }
165.847 + if (!Character.isWhitespace(c)) {
165.848 + // Doesn't quite work for tabs etc. but those aren't
165.849 + // really used in rst files... Fix when I switch to
165.850 + // direct document iteration
165.851 + return i - lineBegin;
165.852 + }
165.853 + }
165.854 +
165.855 + return -1;
165.856 + }
165.857 +
165.858 + public static int getNextLineOffset(String text, int offset) {
165.859 + int index = text.indexOf('\n', offset);
165.860 + if (index == -1) {
165.861 + return -1;
165.862 + } else {
165.863 + return index + 1;
165.864 + }
165.865 + }
165.866 +
165.867 + public static int findElementEnd(String text, int offset) {
165.868 + // Find beginning of line
165.869 + int lineBegin = 0;
165.870 + for (int i = offset; i > 0; i--) {
165.871 + char c = text.charAt(i);
165.872 + if (c == '\n') {
165.873 + lineBegin = i + 1;
165.874 + break;
165.875 + }
165.876 + }
165.877 +
165.878 + // Compute indentation of the ..
165.879 + int firstIndent = getIndentation(text, lineBegin);
165.880 + offset = getNextLineOffset(text, lineBegin);
165.881 + while (true) {
165.882 + offset = getNextLineOffset(text, offset);
165.883 + if (offset == -1) {
165.884 + return text.length();
165.885 + }
165.886 + int indent = getIndentation(text, offset);
165.887 + if (indent == -1) {
165.888 + // Empty line - doesn't count
165.889 + continue;
165.890 + } else if (indent <= firstIndent) {
165.891 + return offset;
165.892 + }
165.893 + }
165.894 + }
165.895 +
165.896 + public static int findElementMatch(String text, String key, String name, boolean checkAdjacentLines) {
165.897 + int nameLength = name.length();
165.898 + int offset = 0;
165.899 + int keyLength = key.length();
165.900 + while (true) {
165.901 + int next = text.indexOf(key, offset);
165.902 + if (next == -1) {
165.903 + break;
165.904 + }
165.905 + offset = next + keyLength;
165.906 +
165.907 + int lineEnd = text.indexOf('\n', offset);
165.908 + if (lineEnd == -1) {
165.909 + lineEnd = text.length(); // on last line with no crlf at the end
165.910 + }
165.911 +
165.912 + // Skip whitespace
165.913 + for (; offset < lineEnd; offset++) {
165.914 + char c = text.charAt(offset);
165.915 + if (c != ' ') {
165.916 + break;
165.917 + }
165.918 + }
165.919 +
165.920 + int nameBegin = offset;
165.921 + int nameEnd = -1;
165.922 +
165.923 + // Pick out the bame
165.924 + for (int i = offset; i < lineEnd; i++) {
165.925 + char c = text.charAt(i);
165.926 + if (c == '(' || c == ' ') {
165.927 + nameEnd = i;
165.928 + break;
165.929 + } else if (c == '.') {
165.930 + nameBegin = i + 1;
165.931 + }
165.932 + }
165.933 + if (nameEnd == -1) {
165.934 + nameEnd = lineEnd;
165.935 + }
165.936 +
165.937 +
165.938 + if (nameEnd - nameBegin == nameLength &&
165.939 + text.regionMatches(nameBegin, name, 0, nameLength)) {
165.940 + // TODO - validate the arguments list?
165.941 + return next;
165.942 + }
165.943 +
165.944 + // Look on subsequent lines too - we sometimes have adjacent lines
165.945 + // with additional signatures
165.946 + if (checkAdjacentLines) {
165.947 + while (true) {
165.948 + int lineBegin = lineEnd+1;
165.949 + if (lineBegin >= text.length()) {
165.950 + break;
165.951 + }
165.952 +
165.953 + lineEnd = text.indexOf('\n', lineBegin);
165.954 + if (lineEnd == -1) {
165.955 + lineEnd = text.length(); // on last line with no crlf at the end
165.956 + }
165.957 +
165.958 + while (lineBegin < lineEnd) {
165.959 + char c = text.charAt(lineBegin);
165.960 + if (!Character.isWhitespace(c)) {
165.961 + break;
165.962 + }
165.963 + lineBegin++;
165.964 + }
165.965 +
165.966 + while (lineEnd > lineBegin) {
165.967 + char c = text.charAt(lineEnd-1);
165.968 + if (!Character.isWhitespace(c)) {
165.969 + break;
165.970 + }
165.971 + lineEnd--;
165.972 + }
165.973 +
165.974 + if (lineEnd <= lineBegin) {
165.975 + break;
165.976 + }
165.977 +
165.978 + nameBegin = lineBegin;
165.979 + nameEnd = -1;
165.980 +
165.981 + // Pick out the name
165.982 + for (int i = lineBegin; i < lineEnd; i++) {
165.983 + char c = text.charAt(i);
165.984 + if (c == '(' || c == ' ') {
165.985 + nameEnd = i;
165.986 + break;
165.987 + } else if (c == '.') {
165.988 + nameBegin = i + 1;
165.989 + }
165.990 + }
165.991 + if (nameEnd == -1) {
165.992 + nameEnd = lineEnd;
165.993 + }
165.994 +
165.995 + if (nameEnd - nameBegin == nameLength &&
165.996 + text.regionMatches(nameBegin, name, 0, nameLength)) {
165.997 + // TODO - validate the arguments list?
165.998 + return next;
165.999 + }
165.1000 + }
165.1001 + }
165.1002 +
165.1003 + }
165.1004 +
165.1005 + return -1;
165.1006 + }
165.1007 +
165.1008 + public static String document(ParserResult info, ElementHandle element) {
165.1009 + if (element instanceof IndexedElement) {
165.1010 + IndexedElement indexedElement = (IndexedElement)element;
165.1011 +
165.1012 + FileObject fo = indexedElement.getFileObject();
165.1013 +
165.1014 + if (fo == null) {
165.1015 + return null;
165.1016 + }
165.1017 +
165.1018 + if (PythonUtils.isRstFile(fo)) {
165.1019 + return getDocumentation(indexedElement);
165.1020 + }
165.1021 +
165.1022 +
165.1023 + PythonTree node = indexedElement.getNode();
165.1024 + if (node != null) {
165.1025 + return document(info, node, indexedElement);
165.1026 + }
165.1027 + }
165.1028 + return null;
165.1029 + }
165.1030 +
165.1031 + public static String document(ParserResult info, PythonTree node, IndexedElement element) {
165.1032 + if (node != null) {
165.1033 + String doc = PythonAstUtils.getDocumentation(node);
165.1034 + if (doc != null) {
165.1035 + // Honor empty lines: paragraphs
165.1036 + RstFormatter formatter = new RstFormatter();
165.1037 + if (element != null) {
165.1038 + formatter.appendSignature(element);
165.1039 + }
165.1040 + if (doc.indexOf('\n') != -1) {
165.1041 + formatter.appendHtml("\n<hr>\n"); // NOI18N
165.1042 + formatter.markEmpty();
165.1043 + String[] lines = doc.split("\n"); // NOI18N
165.1044 + for (String line : lines) {
165.1045 + formatter.append(line);
165.1046 + }
165.1047 + } else if (doc.length() > 0) {
165.1048 + formatter.appendHtml("\n<hr>\n"); // NOI18N
165.1049 + formatter.markEmpty();
165.1050 + formatter.append(doc);
165.1051 + }
165.1052 +
165.1053 + return formatter.toHtml();
165.1054 + }
165.1055 + }
165.1056 +
165.1057 + return null;
165.1058 + }
165.1059 +
165.1060 + public static String getSignature(Element element) {
165.1061 + StringBuilder signature = new StringBuilder();
165.1062 + // TODO:
165.1063 + signature.append("<pre>"); // NOI18N
165.1064 +
165.1065 + if (element instanceof IndexedMethod) {
165.1066 + IndexedMethod executable = (IndexedMethod)element;
165.1067 + if (element.getIn() != null) {
165.1068 + String in = element.getIn();
165.1069 + signature.append("<i>"); // NOI18N
165.1070 + signature.append(in);
165.1071 + signature.append("</i>"); // NOI18N
165.1072 + signature.append("<br>"); // NOI18N
165.1073 + }
165.1074 + // TODO - share this between Navigator implementation and here...
165.1075 + signature.append("<b>"); // NOI18N
165.1076 + signature.append(element.getName());
165.1077 + signature.append("</b>"); // NOI18N
165.1078 + String[] parameters = executable.getParams();
165.1079 +
165.1080 + if ((parameters != null) && (parameters.length > 0)) {
165.1081 + signature.append("("); // NOI18N
165.1082 +
165.1083 + signature.append("<font color=\"#808080\">"); // NOI18N
165.1084 +
165.1085 + boolean first = true;
165.1086 + for (String parameter : parameters) {
165.1087 + if (first) {
165.1088 + first = false;
165.1089 + } else {
165.1090 + signature.append(", "); // NOI18N
165.1091 + }
165.1092 + signature.append(parameter);
165.1093 + }
165.1094 +
165.1095 + signature.append("</font>"); // NOI18N
165.1096 +
165.1097 + signature.append(")"); // NOI18N
165.1098 + }
165.1099 + } else if (element instanceof IndexedElement) {
165.1100 +// IndexedElement clz = (IndexedElement)element;
165.1101 + String name = element.getName();
165.1102 +// final String fqn = clz.getFqn();
165.1103 +// if (fqn != null && !name.equals(fqn)) {
165.1104 +// signature.append("<i>"); // NOI18N
165.1105 +// signature.append(fqn); // NOI18N
165.1106 +// signature.append("</i>"); // NOI18N
165.1107 +// signature.append("<br>"); // NOI18N
165.1108 +// }
165.1109 + signature.append("<b>"); // NOI18N
165.1110 + signature.append(name);
165.1111 + signature.append("</b>"); // NOI18N
165.1112 + } else {
165.1113 + signature.append(element.getName());
165.1114 + }
165.1115 +
165.1116 + signature.append("</pre>\n"); // NOI18N
165.1117 +
165.1118 + return signature.toString();
165.1119 + }
165.1120 +
165.1121 + @SuppressWarnings("unchecked")
165.1122 + private String getPythonHtml(List<String> source, boolean addPre) {
165.1123 + StringBuilder python = new StringBuilder(500);
165.1124 +
165.1125 + for (String s : source) {
165.1126 + python.append(s);
165.1127 + python.append("\n"); // NOI18N
165.1128 + }
165.1129 +
165.1130 + Language<?> language = PythonTokenId.language();
165.1131 + String mimeType = PythonMIMEResolver.PYTHON_MIME_TYPE;
165.1132 + // TODO - handle YAML and other languages I can see in the documentation...
165.1133 + /*if (python.indexOf(" <%") != -1) { // NOI18N
165.1134 + mimeType = "application/x-httpd-eruby"; // RHTML
165.1135 + Collection<LanguageProvider> providers = (Collection<LanguageProvider>) Lookup.getDefault().lookupAll(LanguageProvider.class);
165.1136 + for (LanguageProvider provider : providers) {
165.1137 + language = provider.findLanguage(mimeType);
165.1138 + if (language != null) {
165.1139 + break;
165.1140 + }
165.1141 + }
165.1142 +
165.1143 + if (language == null) {
165.1144 + mimeType = PythonTokenId.PYTHON_MIME_TYPE;
165.1145 + language = PythonTokenId.language();
165.1146 + }
165.1147 + } else*/ if (source.get(0).trim().startsWith("<")) {
165.1148 + // Looks like markup (other than RHTML) - don't colorize it
165.1149 + // since we don't know how
165.1150 + return null;
165.1151 + }
165.1152 +
165.1153 + StringBuilder buffer = new StringBuilder(1500);
165.1154 +
165.1155 + boolean errors = appendSequence(buffer, python.toString(), language, mimeType, addPre);
165.1156 + return errors ? null : buffer.toString();
165.1157 + }
165.1158 +
165.1159 + @SuppressWarnings("unchecked")
165.1160 + private boolean appendSequence(StringBuilder sb, String text,
165.1161 + Language<?> language, String mimeType, boolean addPre) {
165.1162 + // XXX is this getting called twice?
165.1163 + MimePath mimePath = MimePath.parse(mimeType);
165.1164 + Lookup lookup = MimeLookup.getLookup(mimePath);
165.1165 + FontColorSettings fcs = lookup.lookup(FontColorSettings.class);
165.1166 +
165.1167 + if (addPre) {
165.1168 + sb.append("<pre style=\""); // NOI18N
165.1169 +
165.1170 + sb.append("border-color: #dddddd; border-style: solid; border-width: 1px; ");
165.1171 +
165.1172 + AttributeSet attribs = fcs.getTokenFontColors("default"); // NOI18N
165.1173 + Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
165.1174 + if (fg != null) {
165.1175 + sb.append("color:"); // NOI18N
165.1176 + sb.append(getHtmlColor(fg));
165.1177 + sb.append(";"); // NOI18N
165.1178 + }
165.1179 + Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
165.1180 + // Only set the background for dark colors
165.1181 + if (bg != null && bg.getRed() < 128) {
165.1182 + sb.append("background:"); // NOI18N
165.1183 + sb.append(getHtmlColor(bg));
165.1184 + }
165.1185 +
165.1186 + sb.append("\">\n"); // NOI18N
165.1187 + }
165.1188 + TokenHierarchy hi = TokenHierarchy.create(text, language);
165.1189 + TokenSequence ts = hi.tokenSequence();
165.1190 +
165.1191 + int offset = 0;
165.1192 + ts.move(offset);
165.1193 +
165.1194 + if (ts.moveNext()) {
165.1195 + do {
165.1196 + Token t = ts.token();
165.1197 + String tokenText = t.text().toString();
165.1198 +
165.1199 + // TODO - make style classes instead of inlining everything as font!
165.1200 + String category = t.id().name();
165.1201 + String primaryCategory = t.id().primaryCategory();
165.1202 +
165.1203 + if ("error".equals(primaryCategory)) { // NOI18N
165.1204 + // Abort: an error token means the output probably isn't
165.1205 + // code, or it's code or markup but in a different language
165.1206 + // than we're trying to process it as
165.1207 + return true;
165.1208 + }
165.1209 +
165.1210 + AttributeSet attribs = fcs.getTokenFontColors(category);
165.1211 + String escapedText = tokenText;
165.1212 + try {
165.1213 + escapedText = XMLUtil.toElementContent(tokenText);
165.1214 + } catch (CharConversionException cce) {
165.1215 + Exceptions.printStackTrace(cce);
165.1216 + }
165.1217 +
165.1218 + if (attribs == null) {
165.1219 + category = primaryCategory;
165.1220 + attribs = fcs.getTokenFontColors(category);
165.1221 +
165.1222 + }
165.1223 +
165.1224 + TokenSequence embedded = ts.embedded();
165.1225 + if (embedded != null) {
165.1226 + //embedded.languagePath().mimePath();
165.1227 + String embeddedMimeType = MimePath.parse(embedded.languagePath().mimePath()).getPath();
165.1228 + Color bg = null;
165.1229 + Color fg = null;
165.1230 + if (attribs != null) {
165.1231 + bg = (Color)attribs.getAttribute(StyleConstants.Background);
165.1232 + fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
165.1233 + if (fg != null || bg != null) {
165.1234 + sb.append("<span style=\"");
165.1235 + if (bg != null) {
165.1236 + sb.append("background:"); // NOI18N
165.1237 + sb.append(getHtmlColor(bg));
165.1238 + sb.append(";");
165.1239 + }
165.1240 + if (fg != null) {
165.1241 + sb.append("color:"); // NOI18N
165.1242 + sb.append(getHtmlColor(fg));
165.1243 + }
165.1244 + sb.append("\">"); // NOI18N
165.1245 + }
165.1246 + }
165.1247 + appendSequence(sb, tokenText, embedded.language(), embeddedMimeType, false);
165.1248 + if (fg != null || bg != null) {
165.1249 + sb.append("</span>"); // NOI18N
165.1250 + }
165.1251 + continue;
165.1252 + }
165.1253 +
165.1254 + if (attribs == null) {
165.1255 + sb.append(escapedText);
165.1256 +
165.1257 + continue;
165.1258 + }
165.1259 +
165.1260 + if (escapedText.indexOf('\n') != -1) {
165.1261 + escapedText = escapedText.replace("\n", "<br>"); // NOI18N
165.1262 + }
165.1263 +
165.1264 + if (t.id() == PythonTokenId.WHITESPACE) {
165.1265 + sb.append(escapedText);
165.1266 + } else {
165.1267 + sb.append("<span style=\""); // NOI18N
165.1268 +
165.1269 + Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
165.1270 +
165.1271 + if (fg != null) {
165.1272 + sb.append("color:"); // NOI18N
165.1273 + sb.append(getHtmlColor(fg));
165.1274 + sb.append(";"); // NOI18N
165.1275 + }
165.1276 +
165.1277 + Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
165.1278 +
165.1279 + if (bg != null) {
165.1280 + sb.append("background:"); // NOI18N
165.1281 + sb.append(getHtmlColor(bg));
165.1282 + sb.append(";"); // NOI18NP
165.1283 + }
165.1284 +
165.1285 + Boolean b = (Boolean)attribs.getAttribute(StyleConstants.Bold);
165.1286 +
165.1287 + if ((b != null) && b) {
165.1288 + sb.append("font-weight:bold;"); // NOI18N
165.1289 + }
165.1290 +
165.1291 + b = (Boolean)attribs.getAttribute(StyleConstants.Italic);
165.1292 +
165.1293 + if ((b != null) && b) {
165.1294 + sb.append("font-style:italic;"); // NOI18N
165.1295 + }
165.1296 +
165.1297 + // TODO - underline, strikethrough, ... and FONTS!
165.1298 + sb.append("\">"); // NOI18N
165.1299 + sb.append(escapedText);
165.1300 + sb.append("</span>"); // NOI18N
165.1301 + }
165.1302 + } while (ts.moveNext());
165.1303 + }
165.1304 +
165.1305 + if (addPre) {
165.1306 + sb.append("</pre>\n");
165.1307 + }
165.1308 +
165.1309 + return false;
165.1310 + }
165.1311 +
165.1312 +
165.1313 + // TODO - move to GsfUtilities?
165.1314 + private static String getHtmlColor(Color c) {
165.1315 + int r = c.getRed();
165.1316 + int g = c.getGreen();
165.1317 + int b = c.getBlue();
165.1318 + StringBuffer result = new StringBuffer();
165.1319 + result.append('#');
165.1320 +
165.1321 + String rs = Integer.toHexString(r);
165.1322 + String gs = Integer.toHexString(g);
165.1323 + String bs = Integer.toHexString(b);
165.1324 +
165.1325 + if (r < 0x10) {
165.1326 + result.append('0');
165.1327 + }
165.1328 +
165.1329 + result.append(rs);
165.1330 +
165.1331 + if (g < 0x10) {
165.1332 + result.append('0');
165.1333 + }
165.1334 +
165.1335 + result.append(gs);
165.1336 +
165.1337 + if (b < 0x10) {
165.1338 + result.append('0');
165.1339 + }
165.1340 +
165.1341 + result.append(bs);
165.1342 +
165.1343 + return result.toString();
165.1344 + }
165.1345 +}
166.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
166.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/AstElement.java Mon Sep 21 13:01:16 2015 +0200
166.3 @@ -0,0 +1,117 @@
166.4 +/*
166.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
166.6 + *
166.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
166.8 + *
166.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
166.10 + * Other names may be trademarks of their respective owners.
166.11 + *
166.12 + * The contents of this file are subject to the terms of either the GNU
166.13 + * General Public License Version 2 only ("GPL") or the Common
166.14 + * Development and Distribution License("CDDL") (collectively, the
166.15 + * "License"). You may not use this file except in compliance with the
166.16 + * License. You can obtain a copy of the License at
166.17 + * http://www.netbeans.org/cddl-gplv2.html
166.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
166.19 + * specific language governing permissions and limitations under the
166.20 + * License. When distributing the software, include this License Header
166.21 + * Notice in each file and include the License file at
166.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
166.23 + * particular file as subject to the "Classpath" exception as provided
166.24 + * by Oracle in the GPL Version 2 section of the License file that
166.25 + * accompanied this code. If applicable, add the following below the
166.26 + * License Header, with the fields enclosed by brackets [] replaced by
166.27 + * your own identifying information:
166.28 + * "Portions Copyrighted [year] [name of copyright owner]"
166.29 + *
166.30 + * Contributor(s):
166.31 + *
166.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
166.33 + */
166.34 +package org.netbeans.modules.python.source.elements;
166.35 +
166.36 +import java.util.Set;
166.37 +import org.netbeans.modules.csl.api.ElementKind;
166.38 +import org.netbeans.modules.csl.api.Modifier;
166.39 +import org.netbeans.modules.csl.api.OffsetRange;
166.40 +import org.netbeans.modules.csl.spi.ParserResult;
166.41 +import org.netbeans.modules.python.source.PythonAstUtils;
166.42 +import org.netbeans.modules.python.source.PythonParserResult;
166.43 +import org.netbeans.modules.python.source.PythonStructureItem;
166.44 +import org.netbeans.modules.python.source.PythonStructureScanner;
166.45 +import org.netbeans.modules.python.source.scopes.SymbolTable;
166.46 +import org.python.antlr.PythonTree;
166.47 +import org.python.antlr.ast.Call;
166.48 +import org.python.antlr.ast.ClassDef;
166.49 +import org.python.antlr.ast.FunctionDef;
166.50 +import org.python.antlr.ast.Name;
166.51 +
166.52 +/**
166.53 + * Elements representing a node in a parse tree
166.54 + *
166.55 + * @author Tor Norbye
166.56 + */
166.57 +public class AstElement extends Element {
166.58 + protected PythonTree node;
166.59 + protected String name;
166.60 + protected ElementKind kind;
166.61 + //protected CompilationInfo info;
166.62 + protected Set<Modifier> modifiers;
166.63 + protected SymbolTable scopes;
166.64 +
166.65 + public AstElement(SymbolTable scopes, PythonTree node, String name, ElementKind kind) {
166.66 + //this.info = info;
166.67 + this.scopes = scopes;
166.68 + this.node = node;
166.69 + this.name = name;
166.70 + this.kind = kind;
166.71 + }
166.72 +
166.73 + public static AstElement create(PythonParserResult result, PythonTree node) {
166.74 + SymbolTable scopes = result.getSymbolTable();
166.75 +
166.76 + if (node instanceof FunctionDef) {
166.77 + return new PythonStructureItem(scopes, (FunctionDef)node);
166.78 + } else if (node instanceof ClassDef) {
166.79 + return new PythonStructureItem(scopes, (ClassDef)node);
166.80 + } else if (node instanceof Call) {
166.81 + String name = PythonAstUtils.getCallName((Call)node);
166.82 + return new AstElement(scopes, node, name, ElementKind.METHOD);
166.83 + } else if (node instanceof Name) {
166.84 + return new AstElement(scopes, node, ((Name)node).getInternalId(), ElementKind.VARIABLE);
166.85 + } else {
166.86 + return new AstElement(scopes, node, null, ElementKind.OTHER);
166.87 + }
166.88 + }
166.89 +
166.90 + public PythonTree getNode() {
166.91 + return node;
166.92 + }
166.93 +
166.94 + @Override
166.95 + public String getName() {
166.96 + return name;
166.97 + }
166.98 +
166.99 + @Override
166.100 + public ElementKind getKind() {
166.101 + return kind;
166.102 + }
166.103 +
166.104 + @Override
166.105 + public Set<Modifier> getModifiers() {
166.106 + if (modifiers == null) {
166.107 + if (name != null && scopes.isPrivate(node, name)) {
166.108 + modifiers = IndexedElement.PRIVATE_MODIFIERS;
166.109 + } else {
166.110 + modifiers = IndexedElement.PUBLIC_MODIFIERS;
166.111 + }
166.112 + }
166.113 +
166.114 + return modifiers;
166.115 + }
166.116 +
166.117 + public Object getSignature() {
166.118 + return name;
166.119 + }
166.120 +}
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/Element.java Mon Sep 21 13:01:16 2015 +0200
167.3 @@ -0,0 +1,85 @@
167.4 +/*
167.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
167.6 + *
167.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
167.8 + *
167.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
167.10 + * Other names may be trademarks of their respective owners.
167.11 + *
167.12 + * The contents of this file are subject to the terms of either the GNU
167.13 + * General Public License Version 2 only ("GPL") or the Common
167.14 + * Development and Distribution License("CDDL") (collectively, the
167.15 + * "License"). You may not use this file except in compliance with the
167.16 + * License. You can obtain a copy of the License at
167.17 + * http://www.netbeans.org/cddl-gplv2.html
167.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
167.19 + * specific language governing permissions and limitations under the
167.20 + * License. When distributing the software, include this License Header
167.21 + * Notice in each file and include the License file at
167.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
167.23 + * particular file as subject to the "Classpath" exception as provided
167.24 + * by Oracle in the GPL Version 2 section of the License file that
167.25 + * accompanied this code. If applicable, add the following below the
167.26 + * License Header, with the fields enclosed by brackets [] replaced by
167.27 + * your own identifying information:
167.28 + * "Portions Copyrighted [year] [name of copyright owner]"
167.29 + *
167.30 + * Contributor(s):
167.31 + *
167.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
167.33 + */
167.34 +package org.netbeans.modules.python.source.elements;
167.35 +
167.36 +import java.util.Collections;
167.37 +import java.util.Set;
167.38 +import org.netbeans.modules.csl.api.ElementHandle;
167.39 +import org.netbeans.modules.csl.api.ElementKind;
167.40 +import org.netbeans.modules.csl.api.Modifier;
167.41 +import org.netbeans.modules.csl.api.OffsetRange;
167.42 +import org.netbeans.modules.csl.spi.ParserResult;
167.43 +import org.netbeans.modules.python.api.PythonMIMEResolver;
167.44 +import org.openide.filesystems.FileObject;
167.45 +
167.46 +/**
167.47 + *
167.48 + * @author Tor Norbye
167.49 + */
167.50 +public abstract class Element implements ElementHandle {
167.51 + @Override
167.52 + public abstract String getName();
167.53 +
167.54 + @Override
167.55 + public abstract ElementKind getKind();
167.56 +
167.57 + @Override
167.58 + public String getMimeType() {
167.59 + return PythonMIMEResolver.PYTHON_MIME_TYPE;
167.60 + }
167.61 +
167.62 + @Override
167.63 + public boolean signatureEquals(ElementHandle handle) {
167.64 + // XXX TODO
167.65 + return false;
167.66 + }
167.67 +
167.68 + @Override
167.69 + public OffsetRange getOffsetRange(ParserResult pr) {
167.70 + // XXX TODO
167.71 + return null;
167.72 + }
167.73 +
167.74 + @Override
167.75 + public FileObject getFileObject() {
167.76 + return null;
167.77 + }
167.78 +
167.79 + @Override
167.80 + public Set<Modifier> getModifiers() {
167.81 + return Collections.emptySet();
167.82 + }
167.83 +
167.84 + @Override
167.85 + public String getIn() {
167.86 + return null;
167.87 + }
167.88 +}
168.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
168.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/IndexedElement.java Mon Sep 21 13:01:16 2015 +0200
168.3 @@ -0,0 +1,527 @@
168.4 +/*
168.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
168.6 + *
168.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
168.8 + *
168.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
168.10 + * Other names may be trademarks of their respective owners.
168.11 + *
168.12 + * The contents of this file are subject to the terms of either the GNU
168.13 + * General Public License Version 2 only ("GPL") or the Common
168.14 + * Development and Distribution License("CDDL") (collectively, the
168.15 + * "License"). You may not use this file except in compliance with the
168.16 + * License. You can obtain a copy of the License at
168.17 + * http://www.netbeans.org/cddl-gplv2.html
168.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
168.19 + * specific language governing permissions and limitations under the
168.20 + * License. When distributing the software, include this License Header
168.21 + * Notice in each file and include the License file at
168.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
168.23 + * particular file as subject to the "Classpath" exception as provided
168.24 + * by Oracle in the GPL Version 2 section of the License file that
168.25 + * accompanied this code. If applicable, add the following below the
168.26 + * License Header, with the fields enclosed by brackets [] replaced by
168.27 + * your own identifying information:
168.28 + * "Portions Copyrighted [year] [name of copyright owner]"
168.29 + *
168.30 + * Contributor(s):
168.31 + *
168.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
168.33 + */
168.34 +package org.netbeans.modules.python.source.elements;
168.35 +
168.36 +import java.util.Collections;
168.37 +import java.util.EnumSet;
168.38 +import java.util.Set;
168.39 +import org.netbeans.modules.csl.api.ElementKind;
168.40 +import org.netbeans.modules.csl.api.Modifier;
168.41 +import org.netbeans.modules.csl.api.OffsetRange;
168.42 +import org.netbeans.modules.csl.spi.ParserResult;
168.43 +import org.netbeans.modules.python.source.PythonIndex;
168.44 +import org.netbeans.modules.python.source.PythonAstUtils;
168.45 +import org.openide.filesystems.FileObject;
168.46 +import org.python.antlr.PythonTree;
168.47 +
168.48 +/**
168.49 + * Elements representing information coming from the persistent index
168.50 + *
168.51 + * @author Tor Norbye
168.52 + */
168.53 +public class IndexedElement extends Element {
168.54 + public static final EnumSet<Modifier> PRIVATE_MODIFIERS = EnumSet.of(Modifier.PRIVATE);
168.55 + public static final EnumSet<Modifier> PROTECTED_MODIFIERS = EnumSet.of(Modifier.PROTECTED);
168.56 + public static final EnumSet<Modifier> STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC);
168.57 + public static final EnumSet<Modifier> PRIVATE_STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC, Modifier.PRIVATE);
168.58 + public static final EnumSet<Modifier> PROTECTED_STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC, Modifier.PROTECTED);
168.59 + public static final Set<Modifier> PUBLIC_MODIFIERS = Collections.emptySet();
168.60 +
168.61 + // Plan: Stash a single item for class entries so I can search by document for the class.
168.62 + // Add more types into the types
168.63 + /** This method is documented */
168.64 + public static final int DOCUMENTED = 1 << 0;
168.65 + /** This method is private */
168.66 + public static final int PRIVATE = 1 << 2;
168.67 + /** This is a function, not a property */
168.68 + public static final int FUNCTION = 1 << 3;
168.69 + /** This element is "static" (e.g. it's a classvar for fields, class method for methods etc) */
168.70 + public static final int STATIC = 1 << 4;
168.71 + /** This element is deliberately not documented (rdoc :nodoc:) */
168.72 + public static final int NODOC = 1 << 5;
168.73 + /** This is a global variable */
168.74 + public static final int GLOBAL = 1 << 6;
168.75 + /** This is a constructor */
168.76 + public static final int CONSTRUCTOR = 1 << 7;
168.77 + /** This is a deprecated */
168.78 + public static final int DEPRECATED = 1 << 8;
168.79 + /** This is a documentation-only definition */
168.80 + public static final int DOC_ONLY = 1 << 9;
168.81 + /** This is a constant/final */
168.82 + public static final int FINAL = 1 << 10;
168.83 +
168.84 + // Flags noting semicolon positions in attributes
168.85 + public static final int NAME_INDEX = 0;
168.86 + public static final int TYPE_INDEX = 1;
168.87 + public static final int FLAG_INDEX = 2;
168.88 + public static final int ARG_INDEX = 3;
168.89 +// public static final int IN_INDEX = 1;
168.90 +// public static final int CASE_SENSITIVE_INDEX = 2;
168.91 +// public static final int FLAG_INDEX = 3;
168.92 +// public static final int ARG_INDEX = 4;
168.93 +// public static final int NODE_INDEX = 5;
168.94 +// public static final int DOC_INDEX = 6;
168.95 +// public static final int BROWSER_INDEX = 7;
168.96 +// public static final int TYPE_INDEX = 8;
168.97 + protected final String name;
168.98 + protected final ElementKind kind;
168.99 + protected String url;
168.100 + protected FileObject fileObject;
168.101 + protected final String module;
168.102 + protected String rhs;
168.103 + protected boolean smart;
168.104 + protected boolean inherited;
168.105 + protected Set<Modifier> modifiers;
168.106 + protected PythonTree node;
168.107 + protected int flags;
168.108 + protected final String attributes;
168.109 + protected final String clz;
168.110 + protected int order;
168.111 +
168.112 + public IndexedElement(String name, ElementKind kind, String url, String module, String clz, String attributes) {
168.113 + this.name = name;
168.114 + this.kind = kind;
168.115 + this.url = url;
168.116 + this.module = module;
168.117 + this.clz = clz;
168.118 + this.attributes = attributes;
168.119 +
168.120 + // Should be IndexedMethod:
168.121 + //assert !((!(this instanceof IndexedMethod)) && (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR)) : this;
168.122 + }
168.123 +
168.124 + public static IndexedElement create(String signature, String module, String url, String clz) {
168.125 + int semi = signature.indexOf(';');
168.126 + assert semi != -1;
168.127 +
168.128 + String name = signature.substring(0, semi);
168.129 + int flags = IndexedElement.decode(signature, semi + 3, 0);
168.130 +
168.131 + char type = signature.charAt(semi + 1);
168.132 + ElementKind kind;
168.133 + switch (type) {
168.134 + case 'C':
168.135 + kind = ElementKind.CLASS;
168.136 + break;
168.137 + case 'I':
168.138 + kind = ElementKind.MODULE;
168.139 + break;
168.140 + case 'D':
168.141 + kind = ElementKind.VARIABLE;
168.142 + break;
168.143 + case 'A':
168.144 + kind = ElementKind.ATTRIBUTE;
168.145 + break;
168.146 + case 'F':
168.147 + case 'M':
168.148 + case 'c': {
168.149 + kind = type == 'c' ? ElementKind.CONSTRUCTOR : ElementKind.METHOD;
168.150 + IndexedMethod method = new IndexedMethod(name, kind, url, module, clz, signature);
168.151 + method.flags = flags;
168.152 + return method;
168.153 + }
168.154 + default:
168.155 + kind = ElementKind.OTHER;
168.156 + break;
168.157 + }
168.158 +
168.159 + IndexedElement element = new IndexedElement(name, kind, url, module, clz, signature);
168.160 + element.flags = flags;
168.161 + return element;
168.162 + }
168.163 +
168.164 + @Override
168.165 + public boolean equals(Object obj) {
168.166 + if (obj == null) {
168.167 + return false;
168.168 + }
168.169 + if (getClass() != obj.getClass()) {
168.170 + return false;
168.171 + }
168.172 + final IndexedElement other = (IndexedElement)obj;
168.173 + if (this.name != other.name && (this.name == null || !this.name.equals(other.name))) {
168.174 + return false;
168.175 + }
168.176 + if (this.module != other.module && (this.module == null || !this.module.equals(other.module))) {
168.177 + return false;
168.178 + }
168.179 + if (this.kind != other.kind) {
168.180 + return false;
168.181 + }
168.182 + return true;
168.183 + }
168.184 +
168.185 + public String getModule() {
168.186 + return module;
168.187 + }
168.188 +
168.189 + @Override
168.190 + public int hashCode() {
168.191 + int hash = 3;
168.192 + hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
168.193 + hash = 67 * hash + (this.kind != null ? this.kind.hashCode() : 0);
168.194 + return hash;
168.195 + }
168.196 +
168.197 + @Override
168.198 + public String getName() {
168.199 + return name;
168.200 + }
168.201 +
168.202 + @Override
168.203 + public ElementKind getKind() {
168.204 + return kind;
168.205 + }
168.206 +
168.207 + public String getFilenameUrl() {
168.208 + return url;
168.209 + }
168.210 +
168.211 + @Override
168.212 + public FileObject getFileObject() {
168.213 + if ((fileObject == null) && (url != null)) {
168.214 + fileObject = PythonIndex.getFileObject(url);
168.215 +
168.216 + if (fileObject == null) {
168.217 + // Don't try again
168.218 + url = null;
168.219 + }
168.220 + }
168.221 +
168.222 + return fileObject;
168.223 + }
168.224 +
168.225 + public void setFlags(int flags) {
168.226 + this.flags = flags;
168.227 + }
168.228 +
168.229 + public void setInherited(boolean inherited) {
168.230 + this.inherited = inherited;
168.231 + }
168.232 +
168.233 + public boolean isInherited() {
168.234 + return inherited;
168.235 + }
168.236 +
168.237 + public String getType() {
168.238 + return null;
168.239 + }
168.240 +
168.241 + public String getOrigin() {
168.242 + return module;
168.243 + }
168.244 +
168.245 + public boolean isSmart() {
168.246 + return smart;
168.247 + }
168.248 +
168.249 + public void setSmart(boolean smart) {
168.250 + this.smart = smart;
168.251 + }
168.252 +
168.253 + public String getRhs() {
168.254 + if (rhs == null) {
168.255 + rhs = module;
168.256 + if (rhs.equals("stub_missing")) { // NOI18N
168.257 + rhs = "<i>builtin</i>";
168.258 + }
168.259 + }
168.260 + return rhs;
168.261 + }
168.262 +
168.263 + public void setRhs(String rhs) {
168.264 + this.rhs = rhs;
168.265 + }
168.266 +
168.267 + @Override
168.268 + public String getIn() {
168.269 + return module;
168.270 + }
168.271 +
168.272 + public String getSignature() {
168.273 + if (clz != null) {
168.274 + return clz + "." + name;
168.275 + }
168.276 +
168.277 + return name;
168.278 + }
168.279 +
168.280 + public String getClz() {
168.281 + return clz;
168.282 + }
168.283 +
168.284 + public int getOrder() {
168.285 + return order;
168.286 + }
168.287 +
168.288 + public void setOrder(int order) {
168.289 + this.order = order;
168.290 + }
168.291 +
168.292 + public static Set<Modifier> getModifiersForName(String name, boolean isPrivate, boolean isProtected, boolean isStatic) {
168.293 + Set<Modifier> modifiers;
168.294 +
168.295 + // Private variables: start with __ but doesn't end with __
168.296 + // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
168.297 + if (name != null && name.startsWith("__") && !name.endsWith("__")) { // NOI18N
168.298 + isPrivate = true;
168.299 + } else if (name != null && name.startsWith("_") && !name.endsWith("_")) { // NOI18N
168.300 + // From PEP8: Single_leading_underscore: weak "internal use" indicator
168.301 + // (e.g. "from M import *" does not import objects whose name
168.302 + // starts with an underscore).
168.303 + // The protected modifier might work well to visually indicate this.
168.304 + isProtected = true;
168.305 + }
168.306 + if (isPrivate) {
168.307 + if (isStatic) {
168.308 + modifiers = PRIVATE_STATIC_MODIFIERS;
168.309 + } else {
168.310 + modifiers = PRIVATE_MODIFIERS;
168.311 + }
168.312 + } else if (isProtected) {
168.313 + if (isStatic) {
168.314 + modifiers = PROTECTED_STATIC_MODIFIERS;
168.315 + } else {
168.316 + modifiers = PROTECTED_MODIFIERS;
168.317 + }
168.318 + } else {
168.319 + if (isStatic) {
168.320 + modifiers = STATIC_MODIFIERS;
168.321 + } else {
168.322 + modifiers = PUBLIC_MODIFIERS;
168.323 + }
168.324 + }
168.325 +
168.326 + return modifiers;
168.327 + }
168.328 +
168.329 + @Override
168.330 + public Set<Modifier> getModifiers() {
168.331 + if (modifiers == null) {
168.332 + modifiers = getModifiersForName(name, isPrivate(), false, isStatic());
168.333 + }
168.334 +
168.335 + return modifiers;
168.336 + }
168.337 +
168.338 + public PythonTree getNode() {
168.339 + if (node == null) {
168.340 + node = PythonAstUtils.getForeignNode(this, null);
168.341 + }
168.342 + return node;
168.343 + }
168.344 +
168.345 + @Override
168.346 + public String toString() {
168.347 + return "IndexedElement:" + name + "," + kind + "," + rhs;
168.348 + }
168.349 +
168.350 + protected int getAttributeSection(int section) {
168.351 + assert section != 0; // Obtain directly, and logic below (+1) is wrong
168.352 + int attributeIndex = 0;
168.353 + for (int i = 0; i < section; i++) {
168.354 + attributeIndex = attributes.indexOf(';', attributeIndex + 1);
168.355 + }
168.356 +
168.357 + assert attributeIndex != -1;
168.358 + return attributeIndex + 1;
168.359 + }
168.360 +
168.361 + /** Return a string (suitable for persistence) encoding the given flags */
168.362 + public static String encode(int flags) {
168.363 + return Integer.toString(flags, 16);
168.364 + }
168.365 +
168.366 + /** Return flag corresponding to the given encoding chars */
168.367 + public static int decode(String s, int startIndex, int defaultValue) {
168.368 + int value = 0;
168.369 + for (int i = startIndex, n = s.length(); i < n; i++) {
168.370 + char c = s.charAt(i);
168.371 + if (c == ';') {
168.372 + if (i == startIndex) {
168.373 + return defaultValue;
168.374 + }
168.375 + break;
168.376 + }
168.377 +
168.378 + value = value << 4;
168.379 +
168.380 + if (c > '9') {
168.381 + value += c - 'a' + 10;
168.382 + } else {
168.383 + value += c - '0';
168.384 + }
168.385 + }
168.386 +
168.387 + return value;
168.388 + }
168.389 +
168.390 + public static int getFlags(AstElement element) {
168.391 + // Return the flags corresponding to the given AST element
168.392 + int value = 0;
168.393 +
168.394 + ElementKind k = element.getKind();
168.395 + if (k == ElementKind.CONSTRUCTOR) {
168.396 + value = value | CONSTRUCTOR;
168.397 + }
168.398 + if (k == ElementKind.METHOD || k == ElementKind.CONSTRUCTOR) {
168.399 + value = value | FUNCTION;
168.400 + } else if (k == ElementKind.GLOBAL) {
168.401 + value = value | GLOBAL;
168.402 + }
168.403 + if (element.getModifiers().contains(Modifier.STATIC)) {
168.404 + value = value | STATIC;
168.405 + }
168.406 + if (element.getModifiers().contains(Modifier.DEPRECATED)) {
168.407 + value = value | DEPRECATED;
168.408 + }
168.409 + if (element.getModifiers().contains(Modifier.PRIVATE)) {
168.410 + value = value | PRIVATE;
168.411 + }
168.412 +
168.413 + return value;
168.414 + }
168.415 +
168.416 + public boolean isDocumented() {
168.417 + return (flags & DOCUMENTED) != 0;
168.418 + }
168.419 +
168.420 + public boolean isPublic() {
168.421 + return (flags & PRIVATE) == 0;
168.422 + }
168.423 +
168.424 + public boolean isPrivate() {
168.425 + return (flags & PRIVATE) != 0;
168.426 + }
168.427 +
168.428 + public boolean isFunction() {
168.429 + return (flags & FUNCTION) != 0;
168.430 + }
168.431 +
168.432 + public boolean isStatic() {
168.433 + return (flags & STATIC) != 0;
168.434 + }
168.435 +
168.436 + public boolean isNoDoc() {
168.437 + return (flags & NODOC) != 0;
168.438 + }
168.439 +
168.440 + public boolean isFinal() {
168.441 + return (flags & FINAL) != 0;
168.442 + }
168.443 +
168.444 + public boolean isConstructor() {
168.445 + return (flags & CONSTRUCTOR) != 0;
168.446 + }
168.447 +
168.448 + public boolean isDeprecated() {
168.449 + return (flags & DEPRECATED) != 0;
168.450 + }
168.451 +
168.452 + public boolean isDocOnly() {
168.453 + return (flags & DOC_ONLY) != 0;
168.454 + }
168.455 +
168.456 + public static String decodeFlags(int flags) {
168.457 + StringBuilder sb = new StringBuilder();
168.458 + if ((flags & DOCUMENTED) != 0) {
168.459 + sb.append("|DOCUMENTED");
168.460 + }
168.461 +
168.462 + if ((flags & PRIVATE) != 0) {
168.463 + sb.append("|PRIVATE");
168.464 + }
168.465 +
168.466 + if ((flags & CONSTRUCTOR) != 0) {
168.467 + sb.append("|CONSTRUCTOR");
168.468 + } else if ((flags & FUNCTION) != 0) {
168.469 + sb.append("|FUNCTION");
168.470 + } else if ((flags & GLOBAL) != 0) {
168.471 + sb.append("|GLOBAL");
168.472 + }
168.473 +
168.474 + if ((flags & STATIC) != 0) {
168.475 + sb.append("|STATIC");
168.476 + }
168.477 +
168.478 + if ((flags & NODOC) != 0) {
168.479 + sb.append("|NODOC");
168.480 + }
168.481 +
168.482 + if ((flags & DEPRECATED) != 0) {
168.483 + sb.append("|DEPRECATED");
168.484 + }
168.485 +
168.486 + if ((flags & DOC_ONLY) != 0) {
168.487 + sb.append("|DOC_ONLY");
168.488 + }
168.489 +
168.490 + if ((flags & FINAL) != 0) {
168.491 + sb.append("|FINAL");
168.492 + }
168.493 +
168.494 + if (sb.length() > 0) {
168.495 + sb.append("|");
168.496 + }
168.497 + return sb.toString();
168.498 + }
168.499 +
168.500 + // For testsuite
168.501 + public static int stringToFlags(String string) {
168.502 + int flags = 0;
168.503 + if (string.contains("|DOCUMENTED")) {
168.504 + flags |= DOCUMENTED;
168.505 + }
168.506 + if (string.contains("|PRIVATE")) {
168.507 + flags |= PRIVATE;
168.508 + }
168.509 + if (string.contains("|DEPRECATED")) {
168.510 + flags |= DEPRECATED;
168.511 + }
168.512 + if (string.contains("|CONSTRUCTOR")) {
168.513 + flags |= CONSTRUCTOR;
168.514 + }
168.515 +// if (string.indexOf("|PROTECTED") != -1) {
168.516 +// flags |= PROTECTED;
168.517 +// }
168.518 +// if (string.indexOf("|TOPLEVEL") != -1) {
168.519 +// flags |= TOPLEVEL;
168.520 +// }
168.521 + if (string.contains("|STATIC")) {
168.522 + flags |= STATIC;
168.523 + }
168.524 + if (string.contains("|NODOC")) {
168.525 + flags |= NODOC;
168.526 + }
168.527 +
168.528 + return flags;
168.529 + }
168.530 +}
169.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
169.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/IndexedMethod.java Mon Sep 21 13:01:16 2015 +0200
169.3 @@ -0,0 +1,88 @@
169.4 +/*
169.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
169.6 + *
169.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
169.8 + *
169.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
169.10 + * Other names may be trademarks of their respective owners.
169.11 + *
169.12 + * The contents of this file are subject to the terms of either the GNU
169.13 + * General Public License Version 2 only ("GPL") or the Common
169.14 + * Development and Distribution License("CDDL") (collectively, the
169.15 + * "License"). You may not use this file except in compliance with the
169.16 + * License. You can obtain a copy of the License at
169.17 + * http://www.netbeans.org/cddl-gplv2.html
169.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
169.19 + * specific language governing permissions and limitations under the
169.20 + * License. When distributing the software, include this License Header
169.21 + * Notice in each file and include the License file at
169.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
169.23 + * particular file as subject to the "Classpath" exception as provided
169.24 + * by Oracle in the GPL Version 2 section of the License file that
169.25 + * accompanied this code. If applicable, add the following below the
169.26 + * License Header, with the fields enclosed by brackets [] replaced by
169.27 + * your own identifying information:
169.28 + * "Portions Copyrighted [year] [name of copyright owner]"
169.29 + *
169.30 + * Contributor(s):
169.31 + *
169.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
169.33 + */
169.34 +package org.netbeans.modules.python.source.elements;
169.35 +
169.36 +import org.netbeans.modules.csl.api.ElementKind;
169.37 +
169.38 +/**
169.39 + *
169.40 + * @author Tor Norbye
169.41 + */
169.42 +public class IndexedMethod extends IndexedElement {
169.43 + private String[] params;
169.44 +
169.45 + public IndexedMethod(String name, ElementKind kind, String url, String module, String clz, String signature) {
169.46 + super(name, kind, url, module, clz, signature);
169.47 + }
169.48 +
169.49 + public String[] getParams() {
169.50 + if (params == null) {
169.51 + //int argsBegin = name.length()+3;
169.52 + int argsBegin = getAttributeSection(IndexedElement.ARG_INDEX);
169.53 + int argsEnd = attributes.indexOf(';', argsBegin);
169.54 + assert argsEnd != -1 : attributes;
169.55 + if (argsEnd > argsBegin) {
169.56 + String paramString = attributes.substring(argsBegin, argsEnd);
169.57 + params = paramString.split(",");
169.58 + } else {
169.59 + params = new String[0];
169.60 + }
169.61 + }
169.62 +
169.63 + return params;
169.64 + }
169.65 +
169.66 + @Override
169.67 + public boolean equals(Object obj) {
169.68 + if (obj == null) {
169.69 + return false;
169.70 + }
169.71 + if (getClass() != obj.getClass()) {
169.72 + return false;
169.73 + }
169.74 + final IndexedMethod other = (IndexedMethod)obj;
169.75 + if (this.attributes != other.attributes && (this.attributes == null || !this.attributes.equals(other.attributes))) {
169.76 + return false;
169.77 + }
169.78 + if (this.clz != other.clz && (this.clz == null || !this.clz.equals(other.clz))) {
169.79 + return false;
169.80 + }
169.81 + return true;
169.82 + }
169.83 +
169.84 + @Override
169.85 + public int hashCode() {
169.86 + int hash = 7;
169.87 + hash = 53 * hash + (this.attributes != null ? this.attributes.hashCode() : 0);
169.88 + hash = 53 * hash + (this.clz != null ? this.clz.hashCode() : 0);
169.89 + return hash;
169.90 + }
169.91 +}
170.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
170.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/IndexedPackage.java Mon Sep 21 13:01:16 2015 +0200
170.3 @@ -0,0 +1,106 @@
170.4 +/*
170.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
170.6 + *
170.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
170.8 + *
170.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
170.10 + * Other names may be trademarks of their respective owners.
170.11 + *
170.12 + * The contents of this file are subject to the terms of either the GNU
170.13 + * General Public License Version 2 only ("GPL") or the Common
170.14 + * Development and Distribution License("CDDL") (collectively, the
170.15 + * "License"). You may not use this file except in compliance with the
170.16 + * License. You can obtain a copy of the License at
170.17 + * http://www.netbeans.org/cddl-gplv2.html
170.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
170.19 + * specific language governing permissions and limitations under the
170.20 + * License. When distributing the software, include this License Header
170.21 + * Notice in each file and include the License file at
170.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
170.23 + * particular file as subject to the "Classpath" exception as provided
170.24 + * by Oracle in the GPL Version 2 section of the License file that
170.25 + * accompanied this code. If applicable, add the following below the
170.26 + * License Header, with the fields enclosed by brackets [] replaced by
170.27 + * your own identifying information:
170.28 + * "Portions Copyrighted [year] [name of copyright owner]"
170.29 + *
170.30 + * If you wish your version of this file to be governed by only the CDDL
170.31 + * or only the GPL Version 2, indicate your decision by adding
170.32 + * "[Contributor] elects to include this software in this distribution
170.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
170.34 + * single choice of license, a recipient has the option to distribute
170.35 + * your version of this file under either the CDDL, the GPL Version 2 or
170.36 + * to extend the choice of license to its licensees as provided above.
170.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
170.38 + * Version 2 license, then the option applies only if the new code is
170.39 + * made subject to such option by the copyright holder.
170.40 + *
170.41 + * Contributor(s):
170.42 + *
170.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
170.44 + */
170.45 +package org.netbeans.modules.python.source.elements;
170.46 +
170.47 +import java.util.Collections;
170.48 +import java.util.Set;
170.49 +import org.netbeans.modules.csl.api.ElementKind;
170.50 +import org.netbeans.modules.csl.api.Modifier;
170.51 +
170.52 +/**
170.53 + *
170.54 + * @author Tor Norbye
170.55 + */
170.56 +public class IndexedPackage extends IndexedElement {
170.57 + private String pkg;
170.58 + private boolean hasMore;
170.59 +
170.60 + public IndexedPackage(String name, String pkg, String url, boolean hasMore) {
170.61 + super(name, ElementKind.PACKAGE, url, null, null, null);
170.62 + this.pkg = pkg;
170.63 + this.hasMore = hasMore;
170.64 + }
170.65 +
170.66 + @Override
170.67 + public Set<Modifier> getModifiers() {
170.68 + return Collections.emptySet();
170.69 + }
170.70 +
170.71 + public String getPkg() {
170.72 + return pkg;
170.73 + }
170.74 +
170.75 + public boolean hasMore() {
170.76 + return hasMore;
170.77 + }
170.78 +
170.79 + @Override
170.80 + public boolean equals(Object obj) {
170.81 + if (obj == null) {
170.82 + return false;
170.83 + }
170.84 + if (getClass() != obj.getClass()) {
170.85 + return false;
170.86 + }
170.87 + final IndexedPackage other = (IndexedPackage)obj;
170.88 +
170.89 + // Side effect:
170.90 + // If any element thinks we have more
170.91 + if (other.hasMore) {
170.92 + this.hasMore = other.hasMore;
170.93 + } else if (this.hasMore) {
170.94 + other.hasMore = this.hasMore;
170.95 + }
170.96 +
170.97 + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
170.98 + return false;
170.99 + }
170.100 + return true;
170.101 + }
170.102 +
170.103 + @Override
170.104 + public int hashCode() {
170.105 + int hash = 7;
170.106 + hash = 73 * hash + (this.name != null ? this.name.hashCode() : 0);
170.107 + return hash;
170.108 + }
170.109 +}
171.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
171.2 +++ b/python.source/src/org/netbeans/modules/python/source/impl/PythonProjectSourceLevelQuery.java Mon Sep 21 13:01:16 2015 +0200
171.3 @@ -0,0 +1,29 @@
171.4 +/*
171.5 + * To change this license header, choose License Headers in Project Properties.
171.6 + * To change this template file, choose Tools | Templates
171.7 + * and open the template in the editor.
171.8 + */
171.9 +package org.netbeans.modules.python.source.impl;
171.10 +
171.11 +import org.netbeans.modules.python.source.queries.SourceLevelQueryImplementation;
171.12 +import org.netbeans.api.project.FileOwnerQuery;
171.13 +import org.netbeans.api.project.Project;
171.14 +import org.openide.filesystems.FileObject;
171.15 +import org.openide.util.lookup.ServiceProvider;
171.16 +
171.17 +@ServiceProvider(service = SourceLevelQueryImplementation.class, position = 400)
171.18 +public class PythonProjectSourceLevelQuery implements SourceLevelQueryImplementation {
171.19 +
171.20 + @Override
171.21 + public Result getSourceLevel(FileObject pythonFile) {
171.22 + final Project project = FileOwnerQuery.getOwner(pythonFile);
171.23 + if (project != null) {
171.24 + SourceLevelQueryImplementation impl = project.getLookup().lookup(SourceLevelQueryImplementation.class);
171.25 + if (impl != null) {
171.26 + return impl.getSourceLevel(pythonFile);
171.27 + }
171.28 + }
171.29 + return null;
171.30 + }
171.31 +
171.32 +}
172.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
172.2 +++ b/python.source/src/org/netbeans/modules/python/source/impl/QuerySupportFactory.java Mon Sep 21 13:01:16 2015 +0200
172.3 @@ -0,0 +1,80 @@
172.4 +/*
172.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
172.6 + *
172.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
172.8 + *
172.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
172.10 + * Other names may be trademarks of their respective owners.
172.11 + *
172.12 + * The contents of this file are subject to the terms of either the GNU
172.13 + * General Public License Version 2 only ("GPL") or the Common
172.14 + * Development and Distribution License("CDDL") (collectively, the
172.15 + * "License"). You may not use this file except in compliance with the
172.16 + * License. You can obtain a copy of the License at
172.17 + * http://www.netbeans.org/cddl-gplv2.html
172.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
172.19 + * specific language governing permissions and limitations under the
172.20 + * License. When distributing the software, include this License Header
172.21 + * Notice in each file and include the License file at
172.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
172.23 + * particular file as subject to the "Classpath" exception as provided
172.24 + * by Oracle in the GPL Version 2 section of the License file that
172.25 + * accompanied this code. If applicable, add the following below the
172.26 + * License Header, with the fields enclosed by brackets [] replaced by
172.27 + * your own identifying information:
172.28 + * "Portions Copyrighted [year] [name of copyright owner]"
172.29 + *
172.30 + * If you wish your version of this file to be governed by only the CDDL
172.31 + * or only the GPL Version 2, indicate your decision by adding
172.32 + * "[Contributor] elects to include this software in this distribution
172.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
172.34 + * single choice of license, a recipient has the option to distribute
172.35 + * your version of this file under either the CDDL, the GPL Version 2 or
172.36 + * to extend the choice of license to its licensees as provided above.
172.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
172.38 + * Version 2 license, then the option applies only if the new code is
172.39 + * made subject to such option by the copyright holder.
172.40 + *
172.41 + * Contributor(s):
172.42 + *
172.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
172.44 + */
172.45 +package org.netbeans.modules.python.source.impl;
172.46 +
172.47 +import java.io.IOException;
172.48 +import java.util.Collection;
172.49 +import java.util.Collections;
172.50 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
172.51 +import org.netbeans.modules.python.source.PythonIndexer;
172.52 +import org.openide.filesystems.FileObject;
172.53 +import org.openide.util.Exceptions;
172.54 +
172.55 +/**
172.56 + *
172.57 + * @author Ralph Ruijs
172.58 + */
172.59 +public final class QuerySupportFactory {
172.60 +
172.61 +
172.62 + public static QuerySupport getQuerySupport(final Collection<FileObject> roots) {
172.63 + try {
172.64 + return QuerySupport.forRoots(PythonIndexer.NAME,
172.65 + PythonIndexer.VERSION,
172.66 + roots.toArray(new FileObject[roots.size()]));
172.67 + } catch (IOException ex) {
172.68 + Exceptions.printStackTrace(ex);
172.69 + }
172.70 + return null;
172.71 + }
172.72 +
172.73 + public static QuerySupport getQuerySupport(final FileObject source) {
172.74 + return getQuerySupport(QuerySupport.findRoots(source,
172.75 + null,
172.76 + null,
172.77 + Collections.<String>emptySet()));
172.78 + }
172.79 +
172.80 + private QuerySupportFactory() {
172.81 + }
172.82 +
172.83 +}
173.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
173.2 +++ b/python.source/src/org/netbeans/modules/python/source/layer.xml Mon Sep 21 13:01:16 2015 +0200
173.3 @@ -0,0 +1,71 @@
173.4 +<?xml version="1.0" encoding="UTF-8"?>
173.5 +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
173.6 +<filesystem>
173.7 + <folder name="CslPlugins">
173.8 + <folder name="text">
173.9 + <folder name="x-python">
173.10 + <file name="structure.instance">
173.11 + <attr name="instanceClass" stringvalue="org.netbeans.modules.python.source.PythonStructureScanner"/>
173.12 + </file>
173.13 + </folder>
173.14 + </folder>
173.15 + </folder>
173.16 + <folder name="Editors">
173.17 + <folder name="text">
173.18 + <folder name="x-python">
173.19 + <file name="language.instance">
173.20 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.lexer.PythonTokenId.language"/>
173.21 + <attr name="instanceOf" stringvalue="org.netbeans.api.lexer.Language"/>
173.22 + </file>
173.23 + </folder>
173.24 + </folder>
173.25 + </folder>
173.26 + <folder name="OptionsDialog">
173.27 + <folder name="PreviewExamples">
173.28 + <folder name="text">
173.29 + <file name="x-python" url="PythonExample.py"/>
173.30 + </folder>
173.31 + </folder>
173.32 + <folder name="Editor">
173.33 + <folder name="Formatting">
173.34 + <attr name="position" intvalue="0"/>
173.35 + <folder name="text">
173.36 + <folder name="x-python">
173.37 + <file name="Imports.instance">
173.38 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
173.39 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtImports.getController"/>
173.40 + <attr name="position" intvalue="150"/>
173.41 + </file>
173.42 + <!-- Not yet implemented
173.43 + <file name="TabsAndIndents.instance">
173.44 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
173.45 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtTabsIndents.getController"/>
173.46 + <attr name="position" intvalue="100"/>
173.47 + </file>
173.48 + <file name="Alignment.instance">
173.49 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
173.50 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtAlignment.getController"/>
173.51 + <attr name="position" intvalue="200"/>
173.52 + </file>
173.53 + <file name="Wrapping.instance">
173.54 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
173.55 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtWrapping.getController"/>
173.56 + <attr name="position" intvalue="400"/>
173.57 + </file>
173.58 + <file name="BlankLines.instance">
173.59 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
173.60 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtBlankLines.getController"/>
173.61 + <attr name="position" intvalue="500"/>
173.62 + </file>
173.63 + -->
173.64 + <file name="Spaces.instance">
173.65 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
173.66 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtSpaces.getController"/>
173.67 + <attr name="position" intvalue="600"/>
173.68 + </file>
173.69 + </folder>
173.70 + </folder>
173.71 + </folder>
173.72 + </folder>
173.73 + </folder>
173.74 +</filesystem>
174.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
174.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/BuiltinException.java Mon Sep 21 13:01:16 2015 +0200
174.3 @@ -0,0 +1,127 @@
174.4 +/*
174.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
174.6 + *
174.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
174.8 + *
174.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
174.10 + * Other names may be trademarks of their respective owners.
174.11 + *
174.12 + * The contents of this file are subject to the terms of either the GNU
174.13 + * General Public License Version 2 only ("GPL") or the Common
174.14 + * Development and Distribution License("CDDL") (collectively, the
174.15 + * "License"). You may not use this file except in compliance with the
174.16 + * License. You can obtain a copy of the License at
174.17 + * http://www.netbeans.org/cddl-gplv2.html
174.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
174.19 + * specific language governing permissions and limitations under the
174.20 + * License. When distributing the software, include this License Header
174.21 + * Notice in each file and include the License file at
174.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
174.23 + * particular file as subject to the "Classpath" exception as provided
174.24 + * by Oracle in the GPL Version 2 section of the License file that
174.25 + * accompanied this code. If applicable, add the following below the
174.26 + * License Header, with the fields enclosed by brackets [] replaced by
174.27 + * your own identifying information:
174.28 + * "Portions Copyrighted [year] [name of copyright owner]"
174.29 + *
174.30 + * If you wish your version of this file to be governed by only the CDDL
174.31 + * or only the GPL Version 2, indicate your decision by adding
174.32 + * "[Contributor] elects to include this software in this distribution
174.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
174.34 + * single choice of license, a recipient has the option to distribute
174.35 + * your version of this file under either the CDDL, the GPL Version 2 or
174.36 + * to extend the choice of license to its licensees as provided above.
174.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
174.38 + * Version 2 license, then the option applies only if the new code is
174.39 + * made subject to such option by the copyright holder.
174.40 + *
174.41 + * Contributor(s):
174.42 + *
174.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
174.44 + */
174.45 +package org.netbeans.modules.python.editor.lexer;
174.46 +
174.47 +import java.util.Arrays;
174.48 +import java.util.HashSet;
174.49 +import java.util.Set;
174.50 +
174.51 +/**
174.52 + *
174.53 + * @author jenselme
174.54 + */
174.55 +public class BuiltinException {
174.56 + private final static String[] BUILTIN_EXCEPTIONS_ARRAY = {
174.57 + "ArithmeticError",
174.58 + "AssertionError",
174.59 + "AttributeError",
174.60 + "BaseException",
174.61 + "BlockingIOError",
174.62 + "BrokenPipeError",
174.63 + "BufferError",
174.64 + "BytesWarning",
174.65 + "BytesWarningBaseException",
174.66 + "ChildProcessError",
174.67 + "ConnectionAbortedError",
174.68 + "ConnectionError",
174.69 + "ConnectionRefusedError",
174.70 + "ConnectionResetError",
174.71 + "DeprecationWarning",
174.72 + "EnvironmentError",
174.73 + "EOFError",
174.74 + "Exception",
174.75 + "FileExistsError",
174.76 + "FileNotFoundError",
174.77 + "FloatingPointError",
174.78 + "FutureWarning",
174.79 + "GeneratorExit",
174.80 + "ImportError",
174.81 + "ImportWarning",
174.82 + "IndentationError",
174.83 + "IndexError",
174.84 + "InterruptedError",
174.85 + "IOError",
174.86 + "IsADirectoryError",
174.87 + "KeyboardInterrupt",
174.88 + "KeyError",
174.89 + "LookupError",
174.90 + "MemoryError",
174.91 + "NameError",
174.92 + "NotADirectoryError",
174.93 + "NotImplementedError",
174.94 + "OSError",
174.95 + "OverflowError",
174.96 + "PendingDeprecationWarning",
174.97 + "PermissionError",
174.98 + "ProcessLookupError",
174.99 + "ReferenceError",
174.100 + "ResourceWarning",
174.101 + "RuntimeError",
174.102 + "RuntimeWarning",
174.103 + "StandardError",
174.104 + "StopIteration",
174.105 + "SyntaxError",
174.106 + "SyntaxWarning",
174.107 + "SystemError",
174.108 + "SystemExit",
174.109 + "TabError",
174.110 + "TimeoutError",
174.111 + "TypeError",
174.112 + "UnboundLocalError",
174.113 + "UnicodeDecodeError",
174.114 + "UnicodeEncodeError",
174.115 + "UnicodeError",
174.116 + "UnicodeTranslateError",
174.117 + "UnicodeWarning",
174.118 + "UserWarning",
174.119 + "ValueError",
174.120 + "VMSError",
174.121 + "Warning",
174.122 + "WindowsError",
174.123 + "ZeroDivisionError"
174.124 + };
174.125 + private final static Set<String> BUILTIN_EXCEPTIONS = new HashSet<String>(Arrays.asList(BUILTIN_EXCEPTIONS_ARRAY));
174.126 +
174.127 + public static boolean isBuiltInException(CharSequence name) {
174.128 + return BUILTIN_EXCEPTIONS.contains(name.toString());
174.129 + }
174.130 +}
175.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
175.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/Call.java Mon Sep 21 13:01:16 2015 +0200
175.3 @@ -0,0 +1,322 @@
175.4 +/*
175.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
175.6 + *
175.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
175.8 + *
175.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
175.10 + * Other names may be trademarks of their respective owners.
175.11 + *
175.12 + * The contents of this file are subject to the terms of either the GNU
175.13 + * General Public License Version 2 only ("GPL") or the Common
175.14 + * Development and Distribution License("CDDL") (collectively, the
175.15 + * "License"). You may not use this file except in compliance with the
175.16 + * License. You can obtain a copy of the License at
175.17 + * http://www.netbeans.org/cddl-gplv2.html
175.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
175.19 + * specific language governing permissions and limitations under the
175.20 + * License. When distributing the software, include this License Header
175.21 + * Notice in each file and include the License file at
175.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
175.23 + * particular file as subject to the "Classpath" exception as provided
175.24 + * by Oracle in the GPL Version 2 section of the License file that
175.25 + * accompanied this code. If applicable, add the following below the
175.26 + * License Header, with the fields enclosed by brackets [] replaced by
175.27 + * your own identifying information:
175.28 + * "Portions Copyrighted [year] [name of copyright owner]"
175.29 + *
175.30 + * Contributor(s):
175.31 + *
175.32 + * The Original Software is NetBeans. The Initial Developer of the Original
175.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
175.34 + * Microsystems, Inc. All Rights Reserved.
175.35 + *
175.36 + * If you wish your version of this file to be governed by only the CDDL
175.37 + * or only the GPL Version 2, indicate your decision by adding
175.38 + * "[Contributor] elects to include this software in this distribution
175.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
175.40 + * single choice of license, a recipient has the option to distribute
175.41 + * your version of this file under either the CDDL, the GPL Version 2 or
175.42 + * to extend the choice of license to its licensees as provided above.
175.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
175.44 + * Version 2 license, then the option applies only if the new code is
175.45 + * made subject to such option by the copyright holder.
175.46 + */
175.47 +package org.netbeans.modules.python.source.lexer;
175.48 +
175.49 +import javax.swing.text.BadLocationException;
175.50 +import javax.swing.text.Document;
175.51 +import org.netbeans.api.annotations.common.NonNull;
175.52 +
175.53 +import org.netbeans.api.lexer.Token;
175.54 +import org.netbeans.api.lexer.TokenHierarchy;
175.55 +import org.netbeans.api.lexer.TokenId;
175.56 +import org.netbeans.api.lexer.TokenSequence;
175.57 +import org.netbeans.editor.BaseDocument;
175.58 +import org.netbeans.editor.Utilities;
175.59 +import org.openide.util.Exceptions;
175.60 +
175.61 +/**
175.62 + * Class which represents a Call in the source
175.63 + */
175.64 +public class Call {
175.65 + public static final Call LOCAL = new Call(null, null, false, false);
175.66 + public static final Call NONE = new Call(null, null, false, false);
175.67 + public static final Call UNKNOWN = new Call(null, null, false, false);
175.68 + private final String type;
175.69 + private final String lhs;
175.70 + private final boolean isStatic;
175.71 + private final boolean methodExpected;
175.72 +
175.73 + public Call(String type, String lhs, boolean isStatic, boolean methodExpected) {
175.74 + super();
175.75 + this.type = type;
175.76 + this.lhs = lhs;
175.77 + this.methodExpected = methodExpected;
175.78 + if (lhs == null) {
175.79 + lhs = type;
175.80 + }
175.81 + this.isStatic = isStatic;
175.82 + }
175.83 +
175.84 + public String getType() {
175.85 + return type;
175.86 + }
175.87 +
175.88 + public String getLhs() {
175.89 + return lhs;
175.90 + }
175.91 +
175.92 + public boolean isStatic() {
175.93 + return isStatic;
175.94 + }
175.95 +
175.96 + public boolean isSimpleIdentifier() {
175.97 + if (lhs == null) {
175.98 + return false;
175.99 + }
175.100 + // TODO - replace with the new PythonUtil validations
175.101 + for (int i = 0, n = lhs.length(); i < n; i++) {
175.102 + char c = lhs.charAt(i);
175.103 + if (Character.isJavaIdentifierPart(c)) {
175.104 + continue;
175.105 + }
175.106 + return false;
175.107 + }
175.108 + return true;
175.109 + }
175.110 +
175.111 + @Override
175.112 + public String toString() {
175.113 + if (this == LOCAL) {
175.114 + return "LOCAL";
175.115 + } else if (this == NONE) {
175.116 + return "NONE";
175.117 + } else if (this == UNKNOWN) {
175.118 + return "UNKNOWN";
175.119 + } else {
175.120 + return "Call(" + type + "," + lhs + "," + isStatic + ")";
175.121 + }
175.122 + }
175.123 +
175.124 + /** foo.| or foo.b| -> we're expecting a method call. For Foo:: we don't know. */
175.125 + public boolean isMethodExpected() {
175.126 + return this.methodExpected;
175.127 + }
175.128 +
175.129 + /**
175.130 + * Determine whether the given offset corresponds to a method call on another
175.131 + * object. This would happen in these cases:
175.132 + * Foo::|, Foo::Bar::|, Foo.|, Foo.x|, foo.|, foo.x|
175.133 + * and not here:
175.134 + * |, Foo|, foo|
175.135 + * The method returns the left hand side token, if any, such as "Foo", Foo::Bar",
175.136 + * and "foo". If not, it will return null.
175.137 + * Note that "self" and "super" are possible return values for the lhs, which mean
175.138 + * that you don't have a call on another object. Clients of this method should
175.139 + * handle that return value properly (I could return null here, but clients probably
175.140 + * want to distinguish self and super in this case so it's useful to return the info.)
175.141 + *
175.142 + * This method will also try to be smart such that if you have a block or array
175.143 + * call, it will return the relevant classnames (e.g. for [1,2].x| it returns "Array").
175.144 + */
175.145 + @SuppressWarnings("unchecked")
175.146 + @NonNull
175.147 + public static Call getCallType(BaseDocument doc, TokenHierarchy<Document> th, int offset) {
175.148 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(th, offset);
175.149 +
175.150 + if (ts == null) {
175.151 + return Call.NONE;
175.152 + }
175.153 +
175.154 + ts.move(offset);
175.155 +
175.156 + boolean methodExpected = false;
175.157 +
175.158 + if (!ts.moveNext() && !ts.movePrevious()) {
175.159 + return Call.NONE;
175.160 + }
175.161 +
175.162 + if (ts.offset() == offset) {
175.163 + // We're looking at the offset to the RIGHT of the caret
175.164 + // position, which could be whitespace, e.g.
175.165 + // "foo.x| " <-- looking at the whitespace
175.166 + ts.movePrevious();
175.167 + }
175.168 +
175.169 + Token<? extends PythonTokenId> token = ts.token();
175.170 +
175.171 + if (token != null) {
175.172 + TokenId id = token.id();
175.173 +
175.174 + if (id == PythonTokenId.WHITESPACE) {
175.175 + return Call.LOCAL;
175.176 + }
175.177 +
175.178 + // See if we're in the identifier - "x" in "foo.x"
175.179 + // I could also be a keyword in case the prefix happens to currently
175.180 + // match a keyword, such as "next"
175.181 + // However, if we're at the end of the document, x. will lex . as an
175.182 + // identifier of text ".", so handle this case specially
175.183 + if ((id == PythonTokenId.IDENTIFIER)/* || (id == PythonTokenId.CONSTANT)*/ ||
175.184 + id.primaryCategory().equals("keyword")) {
175.185 + String tokenText = token.text().toString();
175.186 +
175.187 + if (".".equals(tokenText)) {
175.188 + // Special case - continue - we'll handle this part next
175.189 + methodExpected = true;
175.190 + } else {
175.191 + methodExpected = true;
175.192 +
175.193 + if (Character.isUpperCase(tokenText.charAt(0))) {
175.194 + methodExpected = false;
175.195 + }
175.196 +
175.197 + if (!ts.movePrevious()) {
175.198 + return Call.LOCAL;
175.199 + }
175.200 + }
175.201 +
175.202 + token = ts.token();
175.203 + id = token.id();
175.204 + }
175.205 +
175.206 + // If we're not in the identifier we need to be in the dot (in "foo.x").
175.207 + // I can't just check for tokens DOT and COLON3 because for unparseable source
175.208 + // (like "File.|") the lexer will return the "." as an identifier.
175.209 + if (id == PythonTokenId.DOT) {
175.210 + methodExpected = true;
175.211 + } else if (id == PythonTokenId.IDENTIFIER) {
175.212 + String t = token.text().toString();
175.213 +
175.214 + if (t.equals(".")) {
175.215 + methodExpected = true;
175.216 + } else {
175.217 + return Call.LOCAL;
175.218 + }
175.219 + } else {
175.220 + return Call.LOCAL;
175.221 + }
175.222 +
175.223 + int lastSeparatorOffset = ts.offset();
175.224 + int beginOffset = lastSeparatorOffset;
175.225 + int lineStart = 0;
175.226 +
175.227 + try {
175.228 + if (offset > doc.getLength()) {
175.229 + offset = doc.getLength();
175.230 + }
175.231 +
175.232 + lineStart = Utilities.getRowStart(doc, offset);
175.233 + } catch (BadLocationException ble) {
175.234 + Exceptions.printStackTrace(ble);
175.235 + }
175.236 +
175.237 + // Find the beginning of the expression. We'll go past keywords, identifiers
175.238 + // and dots or double-colons
175.239 + while (ts.movePrevious()) {
175.240 + // If we get to the previous line we're done
175.241 + if (ts.offset() < lineStart) {
175.242 + break;
175.243 + }
175.244 +
175.245 + token = ts.token();
175.246 + id = token.id();
175.247 +
175.248 + String tokenText = null;
175.249 + if (id == PythonTokenId.ANY_KEYWORD || id == PythonTokenId.IDENTIFIER) {
175.250 + tokenText = token.text().toString();
175.251 + }
175.252 +
175.253 + if (id == PythonTokenId.WHITESPACE) {
175.254 + break;
175.255 + } else if (id == PythonTokenId.RBRACKET) {
175.256 + return new Call("ListType", null, false, methodExpected);
175.257 + } else if (id == PythonTokenId.RBRACE) {
175.258 + return new Call("DictType", null, false, methodExpected);
175.259 + } else if ((id == PythonTokenId.STRING_END)/* || (id == PythonTokenId.QUOTED_STRING_END)*/) {
175.260 + return new Call("StringType", null, false, methodExpected);
175.261 + } else if ((id == PythonTokenId.IDENTIFIER) && "True".equals(tokenText)) { // NOI18N
175.262 + return new Call("BooleanType", null, false, methodExpected);
175.263 + } else if ((id == PythonTokenId.IDENTIFIER) && "False".equals(tokenText)) { // NOI18N
175.264 + return new Call("BooleanType", null, false, methodExpected);
175.265 + } else if (((id == PythonTokenId.IDENTIFIER)) ||
175.266 + id.primaryCategory().equals("keyword") || (id == PythonTokenId.DOT)) {
175.267 +
175.268 + // We're building up a potential expression such as "Test::Unit" so continue looking
175.269 + beginOffset = ts.offset();
175.270 +
175.271 + continue;
175.272 + } else if ((id == PythonTokenId.LPAREN) || (id == PythonTokenId.LBRACE) ||
175.273 + (id == PythonTokenId.LBRACKET)) {
175.274 + // It's an expression for example within a parenthesis, e.g.
175.275 + // yield(^File.join())
175.276 + // in this case we can do top level completion
175.277 + // TODO: There are probably more valid contexts here
175.278 + break;
175.279 + } else if (id == PythonTokenId.ANY_OPERATOR) {
175.280 + break;
175.281 + } else {
175.282 + // Something else - such as "getFoo().x|" - at this point we don't know the type
175.283 + // so we'll just return unknown
175.284 + return Call.UNKNOWN;
175.285 + }
175.286 + }
175.287 +
175.288 + if (beginOffset < lastSeparatorOffset) {
175.289 + try {
175.290 + String lhs = doc.getText(beginOffset, lastSeparatorOffset - beginOffset);
175.291 +
175.292 + if (lhs.equals("super") || lhs.equals("self")) { // NOI18N
175.293 +
175.294 + return new Call(lhs, lhs, false, true);
175.295 + } else if (Character.isUpperCase(lhs.charAt(0))) {
175.296 +
175.297 +// // Detect constructor calls of the form String.new.^
175.298 +// if (lhs.endsWith(".new")) { // NOI18N
175.299 +// // See if it looks like a type prior to that
175.300 +// String type = lhs.substring(0, lhs.length()-4); // 4=".new".length()
175.301 +// if (PythonUtils.isValidPythonModuleName(type)) {
175.302 +// return new Call(type, lhs, false, methodExpected);
175.303 +// }
175.304 +// }
175.305 +
175.306 + String type = null;
175.307 +// if (PythonUtils.isValidPythonModuleName(lhs)) {
175.308 + type = lhs;
175.309 +// }
175.310 +
175.311 + return new Call(type, lhs, true, methodExpected);
175.312 + } else {
175.313 + return new Call(null, lhs, false, methodExpected);
175.314 + }
175.315 + } catch (BadLocationException ble) {
175.316 + Exceptions.printStackTrace(ble);
175.317 + }
175.318 + } else {
175.319 + return Call.UNKNOWN;
175.320 + }
175.321 + }
175.322 +
175.323 + return Call.LOCAL;
175.324 + }
175.325 +}
176.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
176.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonCommentLexer.java Mon Sep 21 13:01:16 2015 +0200
176.3 @@ -0,0 +1,229 @@
176.4 +/*
176.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
176.6 + *
176.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
176.8 + *
176.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
176.10 + * Other names may be trademarks of their respective owners.
176.11 + *
176.12 + * The contents of this file are subject to the terms of either the GNU
176.13 + * General Public License Version 2 only ("GPL") or the Common
176.14 + * Development and Distribution License("CDDL") (collectively, the
176.15 + * "License"). You may not use this file except in compliance with the
176.16 + * License. You can obtain a copy of the License at
176.17 + * http://www.netbeans.org/cddl-gplv2.html
176.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
176.19 + * specific language governing permissions and limitations under the
176.20 + * License. When distributing the software, include this License Header
176.21 + * Notice in each file and include the License file at
176.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
176.23 + * particular file as subject to the "Classpath" exception as provided
176.24 + * by Oracle in the GPL Version 2 section of the License file that
176.25 + * accompanied this code. If applicable, add the following below the
176.26 + * License Header, with the fields enclosed by brackets [] replaced by
176.27 + * your own identifying information:
176.28 + * "Portions Copyrighted [year] [name of copyright owner]"
176.29 + *
176.30 + * Contributor(s):
176.31 + *
176.32 + * The Original Software is NetBeans. The Initial Developer of the Original
176.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
176.34 + * Microsystems, Inc. All Rights Reserved.
176.35 + *
176.36 + * If you wish your version of this file to be governed by only the CDDL
176.37 + * or only the GPL Version 2, indicate your decision by adding
176.38 + * "[Contributor] elects to include this software in this distribution
176.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
176.40 + * single choice of license, a recipient has the option to distribute
176.41 + * your version of this file under either the CDDL, the GPL Version 2 or
176.42 + * to extend the choice of license to its licensees as provided above.
176.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
176.44 + * Version 2 license, then the option applies only if the new code is
176.45 + * made subject to such option by the copyright holder.
176.46 + */
176.47 +package org.netbeans.modules.python.source.lexer;
176.48 +
176.49 +import org.netbeans.api.lexer.Token;
176.50 +import org.netbeans.spi.lexer.Lexer;
176.51 +import org.netbeans.spi.lexer.LexerInput;
176.52 +import org.netbeans.spi.lexer.LexerRestartInfo;
176.53 +import org.netbeans.spi.lexer.TokenFactory;
176.54 +
176.55 +/**
176.56 + * A lexer for python comments.
176.57 + *
176.58 + * Highlights TODO items and certain keywords (like @-param and @-type (without -)).
176.59 + *
176.60 + * @author Tor Norbye
176.61 + */
176.62 +public class PythonCommentLexer implements Lexer<PythonCommentTokenId> {
176.63 + private static final int EOF = LexerInput.EOF;
176.64 + private final LexerInput input;
176.65 + private final TokenFactory<PythonCommentTokenId> tokenFactory;
176.66 + private final boolean substituting;
176.67 +
176.68 + private static enum State {
176.69 + INIT,
176.70 + /** We've just seen @type */
176.71 + SEEN_TYPE_KEY,
176.72 + /** We've just seen @type< > */
176.73 + SEEN_TYPE_WS,
176.74 + /** We've just seen @type <varname> */
176.75 + SEEN_NAME,
176.76 + /** We've just seen @type varname< > */
176.77 + SEEN_NAME_WS
176.78 + };
176.79 + private State state;
176.80 +
176.81 + /**
176.82 + * A Lexer for Python strings
176.83 + * @param substituting If true, handle substitution rules for double quoted strings, otherwise
176.84 + * single quoted strings.
176.85 + */
176.86 + public PythonCommentLexer(LexerRestartInfo<PythonCommentTokenId> info, boolean substituting) {
176.87 + this.input = info.input();
176.88 + this.tokenFactory = info.tokenFactory();
176.89 + this.substituting = substituting;
176.90 + state = (State)info.state();
176.91 + if (state == null) {
176.92 + state = State.INIT;
176.93 + }
176.94 + }
176.95 +
176.96 + @Override
176.97 + public Object state() {
176.98 + return state;
176.99 + }
176.100 +
176.101 + @Override
176.102 + public Token<PythonCommentTokenId> nextToken() {
176.103 + switch (state) {
176.104 + case SEEN_NAME:
176.105 + case SEEN_TYPE_KEY:
176.106 + while (true) {
176.107 + int ch = input.read();
176.108 + if (ch == ':' && state == State.SEEN_NAME && input.readLength() == 1) {
176.109 + continue;
176.110 + }
176.111 + if (ch == EOF || !Character.isWhitespace(ch)) {
176.112 + if (ch != EOF) {
176.113 + input.backup(1);
176.114 + }
176.115 + if (input.readLength() > 0) {
176.116 + state = (state == State.SEEN_TYPE_KEY) ? State.SEEN_TYPE_WS : State.SEEN_NAME_WS;
176.117 + return tokenFactory.createToken(PythonCommentTokenId.SEPARATOR,
176.118 + input.readLength());
176.119 + } else {
176.120 + return null;
176.121 + }
176.122 + }
176.123 + }
176.124 +
176.125 + case SEEN_NAME_WS:
176.126 + case SEEN_TYPE_WS:
176.127 + while (true) {
176.128 + int ch = input.read();
176.129 + if (ch == EOF || Character.isWhitespace(ch) || ch == ':') {
176.130 + if (ch != EOF) {
176.131 + input.backup(1);
176.132 + }
176.133 + if (input.readLength() > 0) {
176.134 + State nextState;
176.135 + PythonCommentTokenId id;
176.136 + if (state == State.SEEN_TYPE_WS) {
176.137 + nextState = State.SEEN_NAME;
176.138 + id = PythonCommentTokenId.VARNAME;
176.139 + } else {
176.140 + nextState = State.INIT;
176.141 + id = PythonCommentTokenId.TYPE;
176.142 + }
176.143 + state = nextState;
176.144 + return tokenFactory.createToken(id, input.readLength());
176.145 + } else if (ch == EOF) {
176.146 + return null;
176.147 + } else {
176.148 + // Error - : without an actual var name
176.149 + state = State.INIT;
176.150 + return nextToken(); // recurse
176.151 + }
176.152 + }
176.153 + }
176.154 + default:
176.155 + case INIT: {
176.156 +
176.157 + int last = EOF;
176.158 + while (true) {
176.159 + int ch = input.read();
176.160 +
176.161 + switch (ch) {
176.162 + case EOF:
176.163 + if (input.readLength() > 0) {
176.164 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
176.165 + input.readLength());
176.166 + } else {
176.167 + return null;
176.168 + }
176.169 +
176.170 + case '@': {
176.171 + // Is it "@type"
176.172 + int initialReadLength = input.readLength();
176.173 + if (input.read() == 't' && input.read() == 'y' && input.read() == 'p' && input.read() == 'e') {
176.174 + if (input.readLength() > 5) {
176.175 + input.backup(5);
176.176 + // Finish this token such that we can do a dedicated token for the @type item.
176.177 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
176.178 + input.readLength());
176.179 + }
176.180 + state = State.SEEN_TYPE_KEY;
176.181 + return tokenFactory.createToken(PythonCommentTokenId.TYPEKEY,
176.182 + input.readLength());
176.183 + }
176.184 + if (input.readLength() > initialReadLength) {
176.185 + input.backup(input.readLength() - initialReadLength);
176.186 + } else {
176.187 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
176.188 + input.readLength());
176.189 + }
176.190 + }
176.191 + break;
176.192 +
176.193 + case 'T': {
176.194 + if (last == EOF || !Character.isLetter(last)) {
176.195 + // Is it "\wTODO\w" ?
176.196 + int initialReadLength = input.readLength();
176.197 + if (input.read() == 'O' && input.read() == 'D' && input.read() == 'O') {
176.198 + int peek = input.read();
176.199 + input.backup(1);
176.200 + if (peek == EOF || !Character.isLetter(peek)) {
176.201 + if (input.readLength() > 4) {
176.202 + input.backup(4);
176.203 + // Finish this token such that we can do a dedicated token for the @type item.
176.204 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
176.205 + input.readLength());
176.206 + }
176.207 + return tokenFactory.createToken(PythonCommentTokenId.TODO,
176.208 + input.readLength());
176.209 + }
176.210 + }
176.211 + if (input.readLength() > initialReadLength) {
176.212 + input.backup(input.readLength() - initialReadLength);
176.213 + } else {
176.214 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
176.215 + input.readLength());
176.216 + }
176.217 + }
176.218 + }
176.219 + break;
176.220 + }
176.221 +
176.222 + last = ch;
176.223 + }
176.224 +
176.225 + }
176.226 + }
176.227 + }
176.228 +
176.229 + @Override
176.230 + public void release() {
176.231 + }
176.232 +}
177.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
177.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonCommentTokenId.java Mon Sep 21 13:01:16 2015 +0200
177.3 @@ -0,0 +1,120 @@
177.4 +/*
177.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
177.6 + *
177.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
177.8 + *
177.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
177.10 + * Other names may be trademarks of their respective owners.
177.11 + *
177.12 + * The contents of this file are subject to the terms of either the GNU
177.13 + * General Public License Version 2 only ("GPL") or the Common
177.14 + * Development and Distribution License("CDDL") (collectively, the
177.15 + * "License"). You may not use this file except in compliance with the
177.16 + * License. You can obtain a copy of the License at
177.17 + * http://www.netbeans.org/cddl-gplv2.html
177.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
177.19 + * specific language governing permissions and limitations under the
177.20 + * License. When distributing the software, include this License Header
177.21 + * Notice in each file and include the License file at
177.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
177.23 + * particular file as subject to the "Classpath" exception as provided
177.24 + * by Oracle in the GPL Version 2 section of the License file that
177.25 + * accompanied this code. If applicable, add the following below the
177.26 + * License Header, with the fields enclosed by brackets [] replaced by
177.27 + * your own identifying information:
177.28 + * "Portions Copyrighted [year] [name of copyright owner]"
177.29 + *
177.30 + * Contributor(s):
177.31 + *
177.32 + * The Original Software is NetBeans. The Initial Developer of the Original
177.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
177.34 + * Microsystems, Inc. All Rights Reserved.
177.35 + *
177.36 + * If you wish your version of this file to be governed by only the CDDL
177.37 + * or only the GPL Version 2, indicate your decision by adding
177.38 + * "[Contributor] elects to include this software in this distribution
177.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
177.40 + * single choice of license, a recipient has the option to distribute
177.41 + * your version of this file under either the CDDL, the GPL Version 2 or
177.42 + * to extend the choice of license to its licensees as provided above.
177.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
177.44 + * Version 2 license, then the option applies only if the new code is
177.45 + * made subject to such option by the copyright holder.
177.46 + */
177.47 +package org.netbeans.modules.python.source.lexer;
177.48 +
177.49 +import java.util.Collection;
177.50 +import java.util.EnumSet;
177.51 +import java.util.Map;
177.52 +
177.53 +import org.netbeans.api.lexer.InputAttributes;
177.54 +import org.netbeans.api.lexer.Language;
177.55 +import org.netbeans.api.lexer.LanguagePath;
177.56 +import org.netbeans.api.lexer.Token;
177.57 +import org.netbeans.api.lexer.TokenId;
177.58 +import org.netbeans.spi.lexer.LanguageEmbedding;
177.59 +import org.netbeans.spi.lexer.LanguageHierarchy;
177.60 +import org.netbeans.spi.lexer.Lexer;
177.61 +import org.netbeans.spi.lexer.LexerRestartInfo;
177.62 +
177.63 +/**
177.64 + *
177.65 + * @author Tor Norbye
177.66 + */
177.67 +public enum PythonCommentTokenId implements TokenId {
177.68 + TEXT("comment"),
177.69 + KEYWORD("comment"),
177.70 + SEPARATOR("comment"),
177.71 + TYPEKEY("comment"),
177.72 + VARNAME("comment"),
177.73 + TYPE("comment"),
177.74 + TODO("comment");
177.75 + private final String primaryCategory;
177.76 +
177.77 + PythonCommentTokenId() {
177.78 + this(null);
177.79 + }
177.80 +
177.81 + PythonCommentTokenId(String primaryCategory) {
177.82 + this.primaryCategory = primaryCategory;
177.83 + }
177.84 +
177.85 + @Override
177.86 + public String primaryCategory() {
177.87 + return primaryCategory;
177.88 + }
177.89 + public static final Language<PythonCommentTokenId> language =
177.90 + new LanguageHierarchy<PythonCommentTokenId>() {
177.91 + @Override
177.92 + protected Collection<PythonCommentTokenId> createTokenIds() {
177.93 + return EnumSet.allOf(PythonCommentTokenId.class);
177.94 + }
177.95 +
177.96 + @Override
177.97 + protected Map<String, Collection<PythonCommentTokenId>> createTokenCategories() {
177.98 + return null; // no extra categories
177.99 + }
177.100 +
177.101 + @Override
177.102 + protected Lexer<PythonCommentTokenId> createLexer(
177.103 + LexerRestartInfo<PythonCommentTokenId> info) {
177.104 + return new PythonCommentLexer(info, true);
177.105 + }
177.106 +
177.107 + @Override
177.108 + protected LanguageEmbedding<?> embedding(
177.109 + Token<PythonCommentTokenId> token, LanguagePath languagePath,
177.110 + InputAttributes inputAttributes) {
177.111 + return null; // No embedding
177.112 + }
177.113 +
177.114 + @Override
177.115 + public String mimeType() {
177.116 + return "text/x-python-comment"; // NOI18N
177.117 + }
177.118 + }.language();
177.119 +
177.120 + public static Language<PythonCommentTokenId> language() {
177.121 + return language;
177.122 + }
177.123 +}
178.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
178.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonLexer.java Mon Sep 21 13:01:16 2015 +0200
178.3 @@ -0,0 +1,1158 @@
178.4 +/*
178.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
178.6 + *
178.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
178.8 + *
178.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
178.10 + * Other names may be trademarks of their respective owners.
178.11 + *
178.12 + * The contents of this file are subject to the terms of either the GNU
178.13 + * General Public License Version 2 only ("GPL") or the Common
178.14 + * Development and Distribution License("CDDL") (collectively, the
178.15 + * "License"). You may not use this file except in compliance with the
178.16 + * License. You can obtain a copy of the License at
178.17 + * http://www.netbeans.org/cddl-gplv2.html
178.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
178.19 + * specific language governing permissions and limitations under the
178.20 + * License. When distributing the software, include this License Header
178.21 + * Notice in each file and include the License file at
178.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
178.23 + * particular file as subject to the "Classpath" exception as provided
178.24 + * by Oracle in the GPL Version 2 section of the License file that
178.25 + * accompanied this code. If applicable, add the following below the
178.26 + * License Header, with the fields enclosed by brackets [] replaced by
178.27 + * your own identifying information:
178.28 + * "Portions Copyrighted [year] [name of copyright owner]"
178.29 + *
178.30 + * Contributor(s):
178.31 + *
178.32 + * The Original Software is NetBeans. The Initial Developer of the Original
178.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
178.34 + * Microsystems, Inc. All Rights Reserved.
178.35 + *
178.36 + * If you wish your version of this file to be governed by only the CDDL
178.37 + * or only the GPL Version 2, indicate your decision by adding
178.38 + * "[Contributor] elects to include this software in this distribution
178.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
178.40 + * single choice of license, a recipient has the option to distribute
178.41 + * your version of this file under either the CDDL, the GPL Version 2 or
178.42 + * to extend the choice of license to its licensees as provided above.
178.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
178.44 + * Version 2 license, then the option applies only if the new code is
178.45 + * made subject to such option by the copyright holder.
178.46 + */
178.47 +package org.netbeans.modules.python.source.lexer;
178.48 +
178.49 +import org.netbeans.api.lexer.Token;
178.50 +import org.netbeans.api.lexer.TokenUtilities;
178.51 +import org.netbeans.spi.lexer.Lexer;
178.52 +import org.netbeans.spi.lexer.LexerInput;
178.53 +import org.netbeans.spi.lexer.LexerRestartInfo;
178.54 +import org.netbeans.spi.lexer.TokenFactory;
178.55 +
178.56 +/**
178.57 + * Lexer for Python.
178.58 + *
178.59 + * This is a hand written lexer for Python which recognizes the logical token types
178.60 + * we care about within the IDE support.
178.61 + *
178.62 + * Initially, we were using Jython's lexer directly here. However, that had some
178.63 + * problems:
178.64 + *
178.65 + * <ul>
178.66 + * <li>
178.67 + * In the IDE, we have to support incremental parsing. Not only is this a must
178.68 + * from a user performance perspective (typing a keystroke near the bottom of a
178.69 + * 2,000 line file shouldn't cause complete re-lexing of the entire document), but
178.70 + * the NetBeans APIs require it; they restart the lexer on the nearest token
178.71 + * boundary.
178.72 + * ANTLR doesn't support incremental lexing. I looked into what it would take
178.73 + * to patch it to do so (as I have done for JRuby in the Ruby support), but
178.74 + * it (a) wasn't trivial, and (b) would require a LOT of data to be stored for
178.75 + * every token boundary.
178.76 + * </li>
178.77 + * <li>
178.78 + * Similarly, we need to put our lexer on top of a LexerInput, and it is not
178.79 + * particularly compatible with the way ANTLR handles input. We had an
178.80 + * adapter class for this which was jumping through various hoops to expose
178.81 + * the LexerInput as ANTLR input. However, it had some severe problems with
178.82 + * large inputs.
178.83 + * </li>
178.84 + * <li>
178.85 + * We need slightly different token divisions. For example, for matching bracket
178.86 + * purposes, we'd like to have strings split into string delimiters and the
178.87 + * string contents. Similarly, Jython did some things like coalesce all whitespace
178.88 + * around a newline into that newline token which causes some complications
178.89 + * for our token analysis.
178.90 + * </li>
178.91 + * <li>
178.92 + * For Ruby, I decided to use the JRuby lexer because JRuby lexing is very
178.93 + * difficult. They have a huge complicated class to do the lexing - and there's
178.94 + * no Ruby language spec. Python on the other hand seems to have a very simple
178.95 + * lexing model, and a clear spec and grammar, so I don't feel worried that
178.96 + * our custom Python lexer is going to have a lot of corner case bugs.
178.97 + * </li>
178.98 + * </ul>
178.99 + *
178.100 + * @author Tor Norbye
178.101 + */
178.102 +public final class PythonLexer implements Lexer<PythonTokenId> {
178.103 + public static final String COMMENT_CAT = "comment";
178.104 + public static final String KEYWORD_CAT = "keyword"; // NOI18N
178.105 + public static final String STRING_CAT = "string"; // NOI18N
178.106 + public static final String WHITESPACE_CAT = "whitespace"; // NOI18N
178.107 + public static final String OPERATOR_CAT = "operator"; // NOI18N
178.108 + public static final String SEPARATOR_CAT = "separator"; // NOI18N
178.109 + public static final String ERROR_CAT = "error"; // NOI18N
178.110 + public static final String NUMBER_CAT = "number"; // NOI18N
178.111 + public static final String IDENTIFIER_CAT = "identifier"; // NOI18N
178.112 + private static final int EOF = LexerInput.EOF;
178.113 + private final LexerInput input;
178.114 + private final TokenFactory<PythonTokenId> tokenFactory;
178.115 +
178.116 + // Lexer state - preserved per token boundary
178.117 + private enum State {
178.118 + /** Normal state, same state as on entry into a Python file */
178.119 + INIT,
178.120 + /** We've processed the beginning string delimiter of a double-quoted short string */
178.121 + BEGIN_SHORTSTRING_DOUBLE,
178.122 + /** We've processed the beginning string delimiter of a single-quoted short string */
178.123 + BEGIN_SHORTSTRING_SINGLE,
178.124 + /** We've processed the beginning string delimiter of a double-quoted long string */
178.125 + BEGIN_LONGSTRING_DOUBLE,
178.126 + /** We've processed the beginning string delimiter of a singl-quoted long string */
178.127 + BEGIN_LONGSTRING_SINGLE,
178.128 + /** We've processed the string content in a double-quoted short string */
178.129 + END_SHORTSTRING_DOUBLE,
178.130 + /** We've processed the string content in a single-quoted short string */
178.131 + END_SHORTSTRING_SINGLE,
178.132 + /** We've processed the string content in a double-quoted long string */
178.133 + END_LONGSTRING_DOUBLE,
178.134 + /** We've processed the string content in a single-quoted long string */
178.135 + END_LONGSTRING_SINGLE,
178.136 + };
178.137 + private State state;
178.138 +
178.139 + public PythonLexer(LexerRestartInfo<PythonTokenId> info) {
178.140 + this.input = info.input();
178.141 + this.tokenFactory = info.tokenFactory();
178.142 +
178.143 + state = (State)info.state();
178.144 + if (state == null) {
178.145 + state = State.INIT;
178.146 + }
178.147 + }
178.148 +
178.149 + @Override
178.150 + public Object state() {
178.151 + return state;
178.152 + }
178.153 +
178.154 + private Token<PythonTokenId> createToken(PythonTokenId id, int tokenLength) {
178.155 + String fixedText = id.fixedText();
178.156 + return (fixedText != null) ? tokenFactory.getFlyweightToken(id, fixedText)
178.157 + : tokenFactory.createToken(id, tokenLength);
178.158 + }
178.159 +
178.160 + @SuppressWarnings("fallthrough")
178.161 + @Override
178.162 + public Token<PythonTokenId> nextToken() {
178.163 + switch (state) {
178.164 + case INIT: {
178.165 + int ch = input.read();
178.166 + switch (ch) {
178.167 + case EOF:
178.168 + return null;
178.169 +
178.170 + // Newline
178.171 + case '\n':
178.172 + assert input.readLength() == 1;
178.173 + return createToken(PythonTokenId.NEWLINE, 1);
178.174 +
178.175 + // Whitespace
178.176 + case ' ':
178.177 + case '\t': {
178.178 + for (; ch != EOF; ch = input.read()) {
178.179 + if (ch != ' ' && ch != '\t') {
178.180 + break;
178.181 + }
178.182 + }
178.183 + input.backup(1);
178.184 + return createToken(PythonTokenId.WHITESPACE, input.readLength());
178.185 + }
178.186 +
178.187 + // Comment
178.188 + case '#': {
178.189 + ch = input.read();
178.190 + while (ch != EOF && ch != '\n') {
178.191 + ch = input.read();
178.192 + }
178.193 + input.backup(1);
178.194 + return createToken(PythonTokenId.COMMENT, input.readLength());
178.195 + }
178.196 +
178.197 + case '.': {
178.198 + assert input.readLength() == 1;
178.199 + int peek = input.read();
178.200 + input.backup(1);
178.201 + if (!Character.isDigit(peek)) {
178.202 + return createToken(PythonTokenId.DOT, 1);
178.203 + } // else: Fallthrough to process the number!!
178.204 + } // FALLTHROUGH
178.205 + // FALLTHROUGH!!!!
178.206 +
178.207 + // Number (integer, float, complex)
178.208 + case '0':
178.209 + case '1':
178.210 + case '2':
178.211 + case '3':
178.212 + case '4':
178.213 + case '5':
178.214 + case '6':
178.215 + case '7':
178.216 + case '8':
178.217 + case '9': {
178.218 + if (ch == '0') {
178.219 + int peek = input.read();
178.220 + if (peek == 'x' || peek == 'X') {
178.221 + // Hex
178.222 + ch = input.read();
178.223 + while (ch != EOF) {
178.224 + if (!(Character.isDigit(ch) ||
178.225 + (ch >= 'a' && ch <= 'f') ||
178.226 + (ch >= 'A' && ch <= 'F'))) {
178.227 + break;
178.228 + }
178.229 + ch = input.read();
178.230 + }
178.231 + if (ch != 'l' && (ch != 'L')) {
178.232 + input.backup(1);
178.233 + }
178.234 + return createToken(PythonTokenId.INT_LITERAL, input.readLength());
178.235 + }
178.236 + input.backup(1);
178.237 + }
178.238 + boolean isFloat = false;
178.239 + digitLoop:
178.240 + for (; ch != EOF; ch = input.read()) {
178.241 + switch (ch) {
178.242 + case '0':
178.243 + case '1':
178.244 + case '2':
178.245 + case '3':
178.246 + case '4':
178.247 + case '5':
178.248 + case '6':
178.249 + case '7':
178.250 + case '8':
178.251 + case '9':
178.252 + continue;
178.253 + case '.':
178.254 + isFloat = true;
178.255 + continue;
178.256 + case 'e': // Exponent
178.257 + case 'E': {
178.258 + int peek = input.read();
178.259 + if (peek != '+' && peek != '-') {
178.260 + input.backup(1);
178.261 + }
178.262 + ch = input.read();
178.263 + while (ch != EOF) {
178.264 + if (!Character.isDigit(ch)) {
178.265 + break;
178.266 + }
178.267 + ch = input.read();
178.268 + }
178.269 + if (ch != 'j' && ch != 'J') {
178.270 + input.backup(1);
178.271 + }
178.272 + return createToken(PythonTokenId.FLOAT_LITERAL, input.readLength());
178.273 + }
178.274 + case 'j': // Imaginary
178.275 + case 'J':
178.276 + isFloat = true;
178.277 + break digitLoop;
178.278 + case 'l': // Long
178.279 + case 'L':
178.280 + break digitLoop;
178.281 + case EOF:
178.282 + default:
178.283 + input.backup(1);
178.284 + break digitLoop;
178.285 +
178.286 + }
178.287 + }
178.288 +
178.289 + return createToken(isFloat ? PythonTokenId.FLOAT_LITERAL : PythonTokenId.INT_LITERAL, input.readLength());
178.290 + }
178.291 +
178.292 + // Operators and delimiters
178.293 + case '+': // +,+=
178.294 + if (input.read() != '=') {
178.295 + input.backup(1);
178.296 + }
178.297 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.298 + case '-': // -,-=
178.299 + if (input.read() != '=') {
178.300 + input.backup(1);
178.301 + }
178.302 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.303 + case '*': { // *,**,*=, **=
178.304 + int peek = input.read();
178.305 + if (peek == '=') {
178.306 + // No need to back up, include it
178.307 + } else if (peek == '*') {
178.308 + peek = input.read();
178.309 + if (peek != '=') {
178.310 + input.backup(1);
178.311 + }
178.312 + } else {
178.313 + input.backup(1);
178.314 + }
178.315 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.316 + }
178.317 + case '/': {
178.318 + // Look for /,//, /=, //=
178.319 + int peek = input.read();
178.320 + if (peek == '=') {
178.321 + // No need to back up, include it
178.322 + } else if (peek == '/') {
178.323 + peek = input.read();
178.324 + if (peek != '=') {
178.325 + input.backup(1);
178.326 + }
178.327 + } else {
178.328 + input.backup(1);
178.329 + }
178.330 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.331 + }
178.332 + case '%': { // Look for %, %=
178.333 + if (input.read() != '=') {
178.334 + input.backup(1);
178.335 + }
178.336 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.337 + }
178.338 + case '<': {
178.339 + // Look for <, <<, <=, <>, <<=
178.340 + int peek = input.read();
178.341 + if (peek == '=') {
178.342 + // No need to back up, include it
178.343 + } else if (peek == '<') {
178.344 + peek = input.read();
178.345 + if (peek != '=') {
178.346 + input.backup(1);
178.347 + }
178.348 + } else if (peek != '>') {
178.349 + input.backup(1);
178.350 + }
178.351 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.352 + }
178.353 + case '>': {
178.354 + // Look for >, >>, >=, >>=
178.355 + int peek = input.read();
178.356 + if (peek == '=') {
178.357 + // No need to back up, include it
178.358 + } else if (peek == '>') {
178.359 + peek = input.read();
178.360 + if (peek != '=') {
178.361 + input.backup(1);
178.362 + }
178.363 + } else {
178.364 + input.backup(1);
178.365 + }
178.366 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.367 + }
178.368 + case '&': { // Look for &,&=
178.369 + if (input.read() != '=') {
178.370 + input.backup(1);
178.371 + }
178.372 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.373 + }
178.374 + case '|': { // Look for |, |=
178.375 + if (input.read() != '=') {
178.376 + input.backup(1);
178.377 + }
178.378 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.379 + }
178.380 + case '^': { // ^,^=
178.381 + if (input.read() != '=') {
178.382 + input.backup(1);
178.383 + }
178.384 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.385 + }
178.386 + case '=': {
178.387 + // Look for =,==
178.388 + if (input.read() != '=') {
178.389 + input.backup(1);
178.390 + }
178.391 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.392 + }
178.393 + case '!': {
178.394 + // Look for !=
178.395 + if (input.read() != '=') {
178.396 + input.backup(1);
178.397 + }
178.398 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.399 + }
178.400 + case '~':
178.401 + case '`':
178.402 + case ';':
178.403 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
178.404 +
178.405 + case ':':
178.406 + assert input.readLength() == 1;
178.407 + return createToken(PythonTokenId.COLON, 1);
178.408 + case '(':
178.409 + assert input.readLength() == 1;
178.410 + return createToken(PythonTokenId.LPAREN, 1);
178.411 + case ')':
178.412 + assert input.readLength() == 1;
178.413 + return createToken(PythonTokenId.RPAREN, 1);
178.414 + case '[':
178.415 + assert input.readLength() == 1;
178.416 + return createToken(PythonTokenId.LBRACKET, 1);
178.417 + case ']':
178.418 + assert input.readLength() == 1;
178.419 + return createToken(PythonTokenId.RBRACKET, 1);
178.420 + case '{':
178.421 + assert input.readLength() == 1;
178.422 + return createToken(PythonTokenId.LBRACE, 1);
178.423 + case '}':
178.424 + assert input.readLength() == 1;
178.425 + return createToken(PythonTokenId.RBRACE, 1);
178.426 + case ',':
178.427 + assert input.readLength() == 1;
178.428 + return createToken(PythonTokenId.COMMA, 1);
178.429 + case '\\':
178.430 + assert input.readLength() == 1;
178.431 + return createToken(PythonTokenId.ESC, 1);
178.432 +
178.433 + case '$':
178.434 + case '?':
178.435 + assert input.readLength() == 1;
178.436 + return createToken(PythonTokenId.ERROR, 1);
178.437 +
178.438 + // String?
178.439 + case '\'':
178.440 + case '"': {
178.441 + int peek = input.read();
178.442 + if (peek != ch) {
178.443 + input.backup(1);
178.444 + assert input.readLength() == 1;
178.445 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
178.446 + return createToken(PythonTokenId.STRING_BEGIN, 1);
178.447 + }
178.448 + // We've seen two quotes... it's either an empty string,
178.449 + // or the beginning of a longstring
178.450 + int peek2 = input.read();
178.451 + if (peek2 == peek) {
178.452 + // It's a longstring!
178.453 + assert input.readLength() == 3;
178.454 + state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
178.455 + return createToken(PythonTokenId.STRING_BEGIN, 3);
178.456 + } else {
178.457 + input.backup(2);
178.458 + assert input.readLength() == 1;
178.459 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
178.460 + return createToken(PythonTokenId.STRING_BEGIN, 1);
178.461 + }
178.462 + }
178.463 + case '@': { // Decorator
178.464 + // Identifier or keyword?
178.465 + ch = input.read();
178.466 + if (Character.isJavaIdentifierStart(ch)) {
178.467 + while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
178.468 + ch = input.read();
178.469 + }
178.470 + input.backup(1);
178.471 +
178.472 + return createToken(PythonTokenId.DECORATOR, input.readLength());
178.473 + }
178.474 + input.backup(1); // Remove the peeked char
178.475 +
178.476 + assert input.readLength() == 1;
178.477 + return createToken(PythonTokenId.DECORATOR, 1);
178.478 + }
178.479 +
178.480 + case 'r':
178.481 + case 'R':
178.482 + case 'u':
178.483 + case 'U': {
178.484 + // Digest the "u" and the "r" and position the input
178.485 + // before the following ' or "
178.486 + boolean isStringPrefix = false;
178.487 + int peek = input.read();
178.488 + if (ch == 'r' || ch == 'R') {
178.489 + if (peek == '\'' || peek == '"') {
178.490 + isStringPrefix = true;
178.491 + }
178.492 + input.backup(1);
178.493 + } else {
178.494 + assert ch == 'u' || ch == 'U';
178.495 + if (peek == 'r' || peek == 'R') {
178.496 + int peek2 = input.read();
178.497 + if (peek2 == '\'' || peek2 == '"') {
178.498 + isStringPrefix = true;
178.499 + }
178.500 + input.backup(1);
178.501 + } else if (peek == '\'' || peek == '"') {
178.502 + isStringPrefix = true;
178.503 + input.backup(1);
178.504 + }
178.505 + if (!isStringPrefix) {
178.506 + input.backup(1);
178.507 + }
178.508 + }
178.509 + if (isStringPrefix) {
178.510 + ch = input.read();
178.511 + assert ch == '\'' || ch == '"';
178.512 +
178.513 + peek = input.read();
178.514 + if (peek != ch) {
178.515 + input.backup(1);
178.516 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
178.517 + return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
178.518 + }
178.519 + // We've seen two quotes... it's either an empty string,
178.520 + // or the beginning of a longstring
178.521 + int peek2 = input.read();
178.522 + if (peek2 == peek) {
178.523 + // It's a longstring!
178.524 + state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
178.525 + return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
178.526 + } else {
178.527 + input.backup(2);
178.528 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
178.529 + return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
178.530 + }
178.531 + }// else: FALLTHROUGH!!! The "u" or "r" is probably an identifier prefix!!
178.532 + }
178.533 + // Fallthrough...
178.534 +
178.535 + default: {
178.536 + // Identifier or keyword?
178.537 + if (Character.isJavaIdentifierStart(ch)) {
178.538 + while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
178.539 + ch = input.read();
178.540 + }
178.541 + input.backup(1);
178.542 +
178.543 + // See if it's a keyword
178.544 + PythonTokenId pid = getKeywordToken(input.readText());
178.545 + if (pid != null) {
178.546 + return createToken(pid, input.readLength());
178.547 + } else {
178.548 + return createToken(PythonTokenId.IDENTIFIER, input.readLength());
178.549 + }
178.550 + }
178.551 +
178.552 + assert input.readLength() == 1;
178.553 + return createToken(PythonTokenId.ANY_OPERATOR, 1);
178.554 + }
178.555 + }
178.556 + }
178.557 +
178.558 + case BEGIN_LONGSTRING_SINGLE:
178.559 + case BEGIN_LONGSTRING_DOUBLE: {
178.560 + // In a long string. Look for the end.
178.561 + int ch = input.read();
178.562 + if (ch == EOF) {
178.563 + return null;
178.564 + }
178.565 + int term = (state == State.BEGIN_LONGSTRING_DOUBLE) ? '"' : '\'';
178.566 + while (ch != EOF) {
178.567 + if (ch == '\\') {
178.568 + // It's an escape - read escaped char
178.569 + input.read();
178.570 + } else if (ch == term) {
178.571 + int peek = input.read();
178.572 + if (peek == term) {
178.573 + int peek2 = input.read();
178.574 + if (peek2 == term) {
178.575 + // Found the end
178.576 + if (input.readLength() == 3) {
178.577 + // Empty string - go straight to closed state
178.578 + state = State.INIT;
178.579 + return createToken(PythonTokenId.STRING_END, input.readLength());
178.580 + }
178.581 + input.backup(3);
178.582 + if (state == State.BEGIN_LONGSTRING_DOUBLE) {
178.583 + state = State.END_LONGSTRING_DOUBLE;
178.584 + } else {
178.585 + assert state == State.BEGIN_LONGSTRING_SINGLE;
178.586 + state = State.END_LONGSTRING_SINGLE;
178.587 + }
178.588 + return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
178.589 + }
178.590 + input.backup(1);
178.591 + }
178.592 + input.backup(1);
178.593 + }
178.594 + ch = input.read();
178.595 + }
178.596 + // Literal not terminated
178.597 + state = State.INIT;
178.598 + return createToken(PythonTokenId.ERROR, input.readLength());
178.599 + }
178.600 + case BEGIN_SHORTSTRING_SINGLE:
178.601 + case BEGIN_SHORTSTRING_DOUBLE: {
178.602 + // In a short string. Look for the end.
178.603 + int ch = input.read();
178.604 + if (ch == EOF) {
178.605 + return null;
178.606 + }
178.607 + int term = (state == State.BEGIN_SHORTSTRING_DOUBLE) ? '"' : '\'';
178.608 + while (ch != EOF) {
178.609 + if (ch == '\\') {
178.610 + // It's an escape - read escaped char
178.611 + input.read();
178.612 + } else if (ch == '\n') {
178.613 + // Literal not terminated
178.614 + state = State.INIT;
178.615 + return createToken(PythonTokenId.ERROR, input.readLength());
178.616 + } else if (ch == term) {
178.617 + if (input.readLength() == 1) {
178.618 + // It's an empty string! Skip straight to the end state
178.619 + state = State.INIT;
178.620 + return createToken(PythonTokenId.STRING_END, input.readLength());
178.621 + }
178.622 + input.backup(1);
178.623 + if (state == State.BEGIN_SHORTSTRING_DOUBLE) {
178.624 + state = State.END_SHORTSTRING_DOUBLE;
178.625 + } else {
178.626 + assert state == State.BEGIN_SHORTSTRING_SINGLE;
178.627 + state = State.END_SHORTSTRING_SINGLE;
178.628 + }
178.629 + return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
178.630 + }
178.631 + ch = input.read();
178.632 + }
178.633 + // Literal not terminated
178.634 + state = State.INIT;
178.635 + return createToken(PythonTokenId.ERROR, input.readLength());
178.636 + }
178.637 +
178.638 + case END_LONGSTRING_SINGLE:
178.639 + case END_LONGSTRING_DOUBLE: {
178.640 + // In a long string. Look for the end.
178.641 + int ch = input.read();
178.642 + if (ch == EOF) {
178.643 + return null;
178.644 + }
178.645 + int term = (state == State.END_LONGSTRING_DOUBLE) ? '"' : '\'';
178.646 + while (ch != EOF) {
178.647 + if (ch == term) {
178.648 + int peek = input.read();
178.649 + if (peek == term) {
178.650 + int peek2 = input.read();
178.651 + if (peek2 == term) {
178.652 + // Found the end
178.653 + state = State.INIT;
178.654 + return createToken(PythonTokenId.STRING_END, input.readLength());
178.655 + }
178.656 + input.backup(1);
178.657 + }
178.658 + input.backup(1);
178.659 + }
178.660 + ch = input.read();
178.661 + }
178.662 + // Literal not terminated
178.663 + state = State.INIT;
178.664 + return createToken(PythonTokenId.ERROR, input.readLength());
178.665 + }
178.666 + case END_SHORTSTRING_SINGLE:
178.667 + case END_SHORTSTRING_DOUBLE: {
178.668 + // In a short string. Look for the end.
178.669 + int ch = input.read();
178.670 + if (ch == EOF) {
178.671 + return null;
178.672 + }
178.673 + int term = (state == State.END_SHORTSTRING_DOUBLE) ? '"' : '\'';
178.674 + if (ch == term) {
178.675 + state = State.INIT;
178.676 + return createToken(PythonTokenId.STRING_END, input.readLength());
178.677 + }
178.678 + state = State.INIT;
178.679 + return createToken(PythonTokenId.ERROR, input.readLength());
178.680 + }
178.681 +
178.682 + default:
178.683 + assert false : state;
178.684 + }
178.685 +
178.686 + return null;
178.687 + }
178.688 +
178.689 + @Override
178.690 + public void release() {
178.691 + }
178.692 +
178.693 + private static PythonTokenId getKeywordToken(CharSequence s) {
178.694 + int length = s.length();
178.695 + if (length < 2) {
178.696 + return null;
178.697 + }
178.698 +
178.699 + if (BuiltinException.isBuiltInException(s)) {
178.700 + return PythonTokenId.ERROR;
178.701 + }
178.702 +
178.703 + char c1 = s.charAt(0);
178.704 + char c2 = s.charAt(1);
178.705 +
178.706 + switch (c1) {
178.707 + case 'a': // and, as, assert, async, await
178.708 + switch (c2) {
178.709 + case 'b': // abs
178.710 + if (length == 3 && TokenUtilities.textEquals(s, "abs")) { // NOI18N
178.711 + return PythonTokenId.BUILTIN_FUNCTION;
178.712 + }
178.713 + case 'l': // all
178.714 + if (length == 3 && TokenUtilities.textEquals(s, "all")) { // NOI18N
178.715 + return PythonTokenId.BUILTIN_FUNCTION;
178.716 + }
178.717 + case 'n': // and, any
178.718 + if (length == 3 && TokenUtilities.textEquals(s, "and")) { // NOI18N
178.719 + return PythonTokenId.ANY_KEYWORD;
178.720 + } else if (TokenUtilities.textEquals(s, "any")) { // NOI18N
178.721 + return PythonTokenId.BUILTIN_FUNCTION;
178.722 + }
178.723 + break;
178.724 + case 's': // as, ascii, assert, async
178.725 + if (length == 2) { // as
178.726 + return PythonTokenId.ANY_KEYWORD;
178.727 + }
178.728 + if (length == 5 && TokenUtilities.textEquals(s, "ascii")) { // NOI18N
178.729 + return PythonTokenId.BUILTIN_FUNCTION;
178.730 + }
178.731 + if (length == 6 && TokenUtilities.textEquals(s, "assert")) { // NOI18N
178.732 + return PythonTokenId.ANY_KEYWORD;
178.733 + }
178.734 + if (length == 5 && TokenUtilities.textEquals(s, "async")) { // NOI18N
178.735 + return PythonTokenId.ANY_KEYWORD;
178.736 + }
178.737 + break;
178.738 + case 'w': // await
178.739 + if (length == 5 && TokenUtilities.textEquals(s, "await")) { // NOI18N
178.740 + return PythonTokenId.ANY_KEYWORD;
178.741 + }
178.742 + }
178.743 + break;
178.744 + case 'b': // basestring, bin, bool, break, bytearray, bytes
178.745 + if (length == 10 && TokenUtilities.textEquals(s, "basestring")) { // NOI18N
178.746 + return PythonTokenId.BUILTIN_FUNCTION;
178.747 + }
178.748 + if (length == 3 && TokenUtilities.textEquals(s, "bin")) { // NOI18N
178.749 + return PythonTokenId.BUILTIN_FUNCTION;
178.750 + }
178.751 + if (length == 4 && TokenUtilities.textEquals(s, "bool")) { // NOI18N
178.752 + return PythonTokenId.BUILTIN_FUNCTION;
178.753 + }
178.754 + if (length == 5 && TokenUtilities.textEquals(s, "break")) { // NOI18N
178.755 + return PythonTokenId.ANY_KEYWORD;
178.756 + }
178.757 + if (length == 9 && TokenUtilities.textEquals(s, "bytearray")) { // NOI18N
178.758 + return PythonTokenId.BUILTIN_FUNCTION;
178.759 + }
178.760 + if (length == 5 && TokenUtilities.textEquals(s, "bytes")) { // NOI18N
178.761 + return PythonTokenId.BUILTIN_FUNCTION;
178.762 + }
178.763 + break;
178.764 + case 'c': // callable, chr, class, classmethod, continue
178.765 + switch (c2) {
178.766 + case 'a': // callable
178.767 + if (length == 8 && TokenUtilities.textEquals(s, "callable")) { // NOI18N
178.768 + return PythonTokenId.BUILTIN_FUNCTION;
178.769 + }
178.770 + break;
178.771 + case 'h': // chr
178.772 + if (length == 3 && TokenUtilities.textEquals(s, "chr")) { // NOI18N
178.773 + return PythonTokenId.BUILTIN_FUNCTION;
178.774 + }
178.775 + break;
178.776 + case 'l': // class, classmethod
178.777 + if (length == 5 && TokenUtilities.textEquals(s, "class")) { // NOI18N
178.778 + return PythonTokenId.CLASS;
178.779 + }
178.780 + if (length == 11 && TokenUtilities.textEquals(s, "classmethod")) { // NOI18N
178.781 + return PythonTokenId.BUILTIN_FUNCTION;
178.782 + }
178.783 + break;
178.784 + case 'm': // cmp
178.785 + if (length == 3 && TokenUtilities.textEquals(s, "cmp")) { // NOI18N
178.786 + return PythonTokenId.BUILTIN_FUNCTION;
178.787 + }
178.788 + break;
178.789 + case 'o': // compile, complex, continue
178.790 + if (length == 7 && TokenUtilities.textEquals(s, "compile")) { // NOI18N
178.791 + return PythonTokenId.BUILTIN_FUNCTION;
178.792 + }
178.793 + if (length == 7 && TokenUtilities.textEquals(s, "complex")) { // NOI18N
178.794 + return PythonTokenId.BUILTIN_FUNCTION;
178.795 + }
178.796 + if (length == 8 && TokenUtilities.textEquals(s, "continue")) { // NOI18N
178.797 + return PythonTokenId.ANY_KEYWORD;
178.798 + }
178.799 + break;
178.800 + }
178.801 + break;
178.802 + case 'd': // def, del
178.803 + switch (c2) {
178.804 + case 'e': // def, del, delattr
178.805 + if (length == 3 && TokenUtilities.textEquals(s, "def")) { // NOI18N
178.806 + return PythonTokenId.DEF;
178.807 + }
178.808 + if (length == 3 && TokenUtilities.textEquals(s, "del")) { // NOI18N
178.809 + return PythonTokenId.ANY_KEYWORD;
178.810 + }
178.811 + if (length == 7 && TokenUtilities.textEquals(s, "delattr")) { // NOI18N
178.812 + return PythonTokenId.BUILTIN_FUNCTION;
178.813 + }
178.814 + break;
178.815 + case 'i': // dict, dir, divmod
178.816 + if (length == 4 && TokenUtilities.textEquals(s, "dict")) { // NOI18N
178.817 + return PythonTokenId.BUILTIN_FUNCTION;
178.818 + }
178.819 + if (length == 3 && TokenUtilities.textEquals(s, "dir")) { // NOI18N
178.820 + return PythonTokenId.BUILTIN_FUNCTION;
178.821 + }
178.822 + if (length == 6 && TokenUtilities.textEquals(s, "divmod")) { // NOI18N
178.823 + return PythonTokenId.BUILTIN_FUNCTION;
178.824 + }
178.825 + break;
178.826 + }
178.827 + break;
178.828 + case 'e': // elif, else, enumerate, eval, except, exec, execfile
178.829 + switch (c2) {
178.830 + case 'l': // elif, else
178.831 + if (length == 4) {
178.832 + if (TokenUtilities.textEquals(s, "elif")) { // NOI18N
178.833 + return PythonTokenId.ELIF;
178.834 + }
178.835 + if (TokenUtilities.textEquals(s, "else")) { // NOI18N
178.836 + return PythonTokenId.ELSE;
178.837 + }
178.838 + }
178.839 + break;
178.840 + case 'n': // enumerate
178.841 + if (length == 9 && TokenUtilities.textEquals(s, "enumerate")) { // NOI18N
178.842 + return PythonTokenId.BUILTIN_FUNCTION;
178.843 + }
178.844 + break;
178.845 + case 'v': // eval
178.846 + if (length == 4 && TokenUtilities.textEquals(s, "eval")) { // NOI18N
178.847 + return PythonTokenId.BUILTIN_FUNCTION;
178.848 + }
178.849 + break;
178.850 + case 'x': // except, exec, execfile
178.851 + if (length == 4 && TokenUtilities.textEquals(s, "exec")) { // NOI18N
178.852 + return PythonTokenId.ANY_KEYWORD;
178.853 + }
178.854 + if (length == 8 && TokenUtilities.textEquals(s, "execfile")) { // NOI18N
178.855 + return PythonTokenId.BUILTIN_FUNCTION;
178.856 + }
178.857 + if (length == 6 && TokenUtilities.textEquals(s, "except")) { // NOI18N
178.858 + return PythonTokenId.EXCEPT;
178.859 + }
178.860 + break;
178.861 + }
178.862 + break;
178.863 + case 'f': // file, filter, finally, for, from
178.864 + switch (c2) {
178.865 + case 'i': // file, filter, finally
178.866 + if (length == 4 && TokenUtilities.textEquals(s, "file")) { // NOI18N
178.867 + return PythonTokenId.BUILTIN_FUNCTION;
178.868 + }
178.869 + if (length == 6 && TokenUtilities.textEquals(s, "filter")) { // NOI18N
178.870 + return PythonTokenId.BUILTIN_FUNCTION;
178.871 + }
178.872 + if (length == 7 && TokenUtilities.textEquals(s, "finally")) { // NOI18N
178.873 + return PythonTokenId.FINALLY;
178.874 + }
178.875 + break;
178.876 + case 'o': // for, format
178.877 + if (length == 3 && TokenUtilities.textEquals(s, "for")) { // NOI18N
178.878 + return PythonTokenId.ANY_KEYWORD;
178.879 + }
178.880 + if (length == 6 && TokenUtilities.textEquals(s, "format")) { // NOI18N
178.881 + return PythonTokenId.BUILTIN_FUNCTION;
178.882 + }
178.883 + break;
178.884 + case 'r': // from, frozenset
178.885 + if (length == 4 && TokenUtilities.textEquals(s, "from")) { // NOI18N
178.886 + return PythonTokenId.FROM;
178.887 + }
178.888 + if (length == 9 && TokenUtilities.textEquals(s, "frozenset")) { // NOI18N
178.889 + return PythonTokenId.BUILTIN_FUNCTION;
178.890 + }
178.891 + break;
178.892 + case 'l':
178.893 + if (length == 5 && TokenUtilities.textEquals(s, "float")) {
178.894 + return PythonTokenId.BUILTIN_FUNCTION;
178.895 + }
178.896 + break;
178.897 + }
178.898 + break;
178.899 + case 'g': // getattr, global, globals
178.900 + if (length == 7 && TokenUtilities.textEquals(s, "getattr")) { // NOI18N
178.901 + return PythonTokenId.BUILTIN_FUNCTION;
178.902 + }
178.903 + if (length == 6 && TokenUtilities.textEquals(s, "global")) { // NOI18N
178.904 + return PythonTokenId.ANY_KEYWORD;
178.905 + }
178.906 + if (length == 7 && TokenUtilities.textEquals(s, "globals")) { // NOI18N
178.907 + return PythonTokenId.BUILTIN_FUNCTION;
178.908 + }
178.909 + break;
178.910 + case 'h': // hasattr, hash, help, hex
178.911 + if (length == 7 && TokenUtilities.textEquals(s, "hasattr")) { // NOI18N
178.912 + return PythonTokenId.BUILTIN_FUNCTION;
178.913 + }
178.914 + if (length == 4 && TokenUtilities.textEquals(s, "hash")) { // NOI18N
178.915 + return PythonTokenId.BUILTIN_FUNCTION;
178.916 + }
178.917 + if (length == 4 && TokenUtilities.textEquals(s, "help")) { // NOI18N
178.918 + return PythonTokenId.BUILTIN_FUNCTION;
178.919 + }
178.920 + if (length == 3 && TokenUtilities.textEquals(s, "hex")) { // NOI18N
178.921 + return PythonTokenId.BUILTIN_FUNCTION;
178.922 + }
178.923 + break;
178.924 + case 'i': // id, if, import, in, input, int, is, issubclass, iter
178.925 + if (length == 2) {
178.926 + switch (c2) {
178.927 + case 'd': // id
178.928 + return PythonTokenId.BUILTIN_FUNCTION;
178.929 + case 'f': // if
178.930 + return PythonTokenId.IF;
178.931 + case 'n': // in
178.932 + if (length == 2 && TokenUtilities.textEquals(s, "in")) { //NOI18N
178.933 + return PythonTokenId.ANY_KEYWORD;
178.934 + }
178.935 + case 's': // is
178.936 + return PythonTokenId.ANY_KEYWORD;
178.937 + }
178.938 + } else if (c2 == 'm' && length == 6 && TokenUtilities.textEquals(s, "import")) { // NOI18N
178.939 + return PythonTokenId.IMPORT;
178.940 + } else if (length == 5 && TokenUtilities.textEquals(s, "input")) { // NOI18N
178.941 + return PythonTokenId.BUILTIN_FUNCTION;
178.942 + } else if (length == 3 && TokenUtilities.textEquals(s, "int")) { // NOI18N
178.943 + return PythonTokenId.BUILTIN_FUNCTION;
178.944 + } else if (length == 10 && TokenUtilities.textEquals(s, "isinstance")) { // NOI18N
178.945 + return PythonTokenId.BUILTIN_FUNCTION;
178.946 + } else if (length == 10 && TokenUtilities.textEquals(s, "issubclass")) { // NOI18N
178.947 + return PythonTokenId.BUILTIN_FUNCTION;
178.948 + } else if (length == 4 && TokenUtilities.textEquals(s, "iter")) { // NOI18N
178.949 + return PythonTokenId.BUILTIN_FUNCTION;
178.950 + }
178.951 + break;
178.952 + case 'l': // lambda, len, list, locals, long
178.953 + if (length == 6 && TokenUtilities.textEquals(s, "lambda")) { // NOI18N
178.954 + return PythonTokenId.ANY_KEYWORD;
178.955 + } else if (length == 3 && TokenUtilities.textEquals(s, "len")) { // NOI18N
178.956 + return PythonTokenId.BUILTIN_FUNCTION;
178.957 + } else if (length == 4 && TokenUtilities.textEquals(s, "list")) { // NOI18N
178.958 + return PythonTokenId.BUILTIN_FUNCTION;
178.959 + } else if (length == 6 && TokenUtilities.textEquals(s, "locals")) { // NOI18N
178.960 + return PythonTokenId.BUILTIN_FUNCTION;
178.961 + } else if (length == 4 && TokenUtilities.textEquals(s, "long")) { // NOI18N
178.962 + return PythonTokenId.BUILTIN_FUNCTION;
178.963 + }
178.964 + break;
178.965 + case 'm': // map, max, memoryview, min
178.966 + if (length == 3 && TokenUtilities.textEquals(s, "map")) { // NOI18N
178.967 + return PythonTokenId.BUILTIN_FUNCTION;
178.968 + }
178.969 + if (length == 3 && TokenUtilities.textEquals(s, "max")) { // NOI18N
178.970 + return PythonTokenId.BUILTIN_FUNCTION;
178.971 + }
178.972 + if (length == 10 && TokenUtilities.textEquals(s, "memoryview")) { // NOI18N
178.973 + return PythonTokenId.BUILTIN_FUNCTION;
178.974 + }
178.975 + if (length == 3 && TokenUtilities.textEquals(s, "min")) { // NOI18N
178.976 + return PythonTokenId.BUILTIN_FUNCTION;
178.977 + }
178.978 + break;
178.979 + case 'n': // next, nonlocal, not
178.980 + if (length == 4 && TokenUtilities.textEquals(s, "next")) { // NOI18N
178.981 + return PythonTokenId.BUILTIN_FUNCTION;
178.982 + }
178.983 + if (length == 8 && TokenUtilities.textEquals(s, "nonlocal")) { // NOI18N
178.984 + return PythonTokenId.ANY_KEYWORD;
178.985 + }
178.986 + if (length == 3 && TokenUtilities.textEquals(s, "not")) { // NOI18N
178.987 + return PythonTokenId.ANY_KEYWORD;
178.988 + }
178.989 + break;
178.990 + case 'o': // or, object, oct, open, ord
178.991 + if (length == 2 && TokenUtilities.textEquals(s, "or")) { // NOI18N
178.992 + return PythonTokenId.ANY_KEYWORD;
178.993 + }
178.994 + if (length == 6 && TokenUtilities.textEquals(s, "object")) { // NOI18N
178.995 + return PythonTokenId.BUILTIN_FUNCTION;
178.996 + }
178.997 + if (length == 3 && TokenUtilities.textEquals(s, "oct")) { // NOI18N
178.998 + return PythonTokenId.BUILTIN_FUNCTION;
178.999 + }
178.1000 + if (length == 4 && TokenUtilities.textEquals(s, "open")) { // NOI18N
178.1001 + return PythonTokenId.BUILTIN_FUNCTION;
178.1002 + }
178.1003 + if (length == 3 && TokenUtilities.textEquals(s, "ord")) { // NOI18N
178.1004 + return PythonTokenId.BUILTIN_FUNCTION;
178.1005 + }
178.1006 + break;
178.1007 + case 'p': // pass, pow, print, property
178.1008 + if (c2 == 'a') { // pass
178.1009 + if (length == 4 && TokenUtilities.textEquals(s, "pass")) { // NOI18N
178.1010 + return PythonTokenId.PASS;
178.1011 + }
178.1012 + }
178.1013 + if (length == 3 && TokenUtilities.textEquals(s, "pow")) { // NOI18N
178.1014 + return PythonTokenId.BUILTIN_FUNCTION;
178.1015 + }
178.1016 + if (c2 == 'r') { // print, property
178.1017 + if (length == 5 && TokenUtilities.textEquals(s, "print")) { // NOI18N
178.1018 + return PythonTokenId.ANY_KEYWORD;
178.1019 + }
178.1020 + if (length == 8 && TokenUtilities.textEquals(s, "property")) { // NOI18N
178.1021 + return PythonTokenId.BUILTIN_FUNCTION;
178.1022 + }
178.1023 + }
178.1024 + break;
178.1025 + case 'r': // raise, range, raise, raw_input, reduce, reload, repr, return, reversed, round
178.1026 + if (c2 == 'a') { // raise, range
178.1027 + if (length == 5 && TokenUtilities.textEquals(s, "range")) { // NOI18N
178.1028 + return PythonTokenId.BUILTIN_FUNCTION;
178.1029 + }
178.1030 + if (length == 5 && TokenUtilities.textEquals(s, "raise")) { // NOI18N
178.1031 + return PythonTokenId.RAISE;
178.1032 + }
178.1033 + if (length == 9 && TokenUtilities.textEquals(s, "raw_input")) { // NOI18N
178.1034 + return PythonTokenId.BUILTIN_FUNCTION;
178.1035 + }
178.1036 + } else if (c2 == 'e') { // reduce, reload, repr, return, reversed
178.1037 + if (length == 6 && TokenUtilities.textEquals(s, "reduce")) { // NOI18N
178.1038 + return PythonTokenId.BUILTIN_FUNCTION;
178.1039 + }
178.1040 + if (length == 6 && TokenUtilities.textEquals(s, "reload")) { // NOI18N
178.1041 + return PythonTokenId.BUILTIN_FUNCTION;
178.1042 + }
178.1043 + if (length == 4 && TokenUtilities.textEquals(s, "repr")) { // NOI18N
178.1044 + return PythonTokenId.BUILTIN_FUNCTION;
178.1045 + }
178.1046 + if (length == 6 && TokenUtilities.textEquals(s, "return")) { // NOI18N
178.1047 + return PythonTokenId.RETURN;
178.1048 + }
178.1049 + if (length == 8 && TokenUtilities.textEquals(s, "reversed")) { // NOI18N
178.1050 + return PythonTokenId.BUILTIN_FUNCTION;
178.1051 + }
178.1052 + } else if (length == 5 && TokenUtilities.textEquals(s, "round")) { // NOI18N
178.1053 + return PythonTokenId.BUILTIN_FUNCTION;
178.1054 + }
178.1055 + break;
178.1056 + case 's': // self, set, setattr, slice, sorted, staticmethod, str, sum, super
178.1057 + if (length == 4 && TokenUtilities.textEquals(s, "self")) { // NOI18N
178.1058 + return PythonTokenId.ANY_KEYWORD;
178.1059 + }
178.1060 + if (length == 3 && TokenUtilities.textEquals(s, "set")) { // NOI18N
178.1061 + return PythonTokenId.BUILTIN_FUNCTION;
178.1062 + }
178.1063 + if (length == 7 && TokenUtilities.textEquals(s, "setattr")) { // NOI18N
178.1064 + return PythonTokenId.BUILTIN_FUNCTION;
178.1065 + }
178.1066 + if (length == 5 && TokenUtilities.textEquals(s, "slice")) { // NOI18N
178.1067 + return PythonTokenId.BUILTIN_FUNCTION;
178.1068 + }
178.1069 + if (length == 6 && TokenUtilities.textEquals(s, "sorted")) { // NOI18N
178.1070 + return PythonTokenId.BUILTIN_FUNCTION;
178.1071 + }
178.1072 + if (length == 12 && TokenUtilities.textEquals(s, "staticmethod")) { // NOI18N
178.1073 + return PythonTokenId.BUILTIN_FUNCTION;
178.1074 + }
178.1075 + if (length == 3 && TokenUtilities.textEquals(s, "str")) { // NOI18N
178.1076 + return PythonTokenId.BUILTIN_FUNCTION;
178.1077 + }
178.1078 + if (length == 3 && TokenUtilities.textEquals(s, "sum")) { // NOI18N
178.1079 + return PythonTokenId.BUILTIN_FUNCTION;
178.1080 + }
178.1081 + if (length == 5 && TokenUtilities.textEquals(s, "super")) { // NOI18N
178.1082 + return PythonTokenId.BUILTIN_FUNCTION;
178.1083 + }
178.1084 + break;
178.1085 + case 't': // try, tuple, type
178.1086 + if (length == 3 && TokenUtilities.textEquals(s, "try")) { // NOI18N
178.1087 + return PythonTokenId.TRY;
178.1088 + } else if (length == 5 && TokenUtilities.textEquals(s, "tuple")) { // NOI18N
178.1089 + return PythonTokenId.BUILTIN_FUNCTION;
178.1090 + } else if (length == 4 && TokenUtilities.textEquals(s, "type")) { // NOI18N
178.1091 + return PythonTokenId.BUILTIN_FUNCTION;
178.1092 + }
178.1093 + break;
178.1094 + case 'u': // unichr, unicode
178.1095 + if (length == 6 && TokenUtilities.textEquals(s, "unichr")) { // NOI18N
178.1096 + return PythonTokenId.BUILTIN_FUNCTION;
178.1097 + }
178.1098 + if (length == 7 && TokenUtilities.textEquals(s, "unicode")) { // NOI18N
178.1099 + return PythonTokenId.BUILTIN_FUNCTION;
178.1100 + }
178.1101 + break;
178.1102 + case 'v': // vars
178.1103 + if (length == 4 && TokenUtilities.textEquals(s, "vars")) { // NOI18N
178.1104 + return PythonTokenId.BUILTIN_FUNCTION;
178.1105 + }
178.1106 + break;
178.1107 + case 'w': // while,with
178.1108 + if (c2 == 'h') { // while
178.1109 + if (length == 5 && TokenUtilities.textEquals(s, "while")) { // NOI18N
178.1110 + return PythonTokenId.ANY_KEYWORD;
178.1111 + }
178.1112 + } else if (c2 == 'i') { // with
178.1113 + if (length == 4 && TokenUtilities.textEquals(s, "with")) { // NOI18N
178.1114 + return PythonTokenId.ANY_KEYWORD;
178.1115 + }
178.1116 + }
178.1117 + break;
178.1118 + case 'x': // xrange
178.1119 + if (length == 6 && TokenUtilities.textEquals(s, "xrange")) { // NOI18N
178.1120 + return PythonTokenId.BUILTIN_FUNCTION;
178.1121 + }
178.1122 + break;
178.1123 + case 'y': // yield
178.1124 + if (length == 5 && TokenUtilities.textEquals(s, "yield")) { // NOI18N
178.1125 + return PythonTokenId.ANY_KEYWORD;
178.1126 + }
178.1127 + break;
178.1128 + case 'z': // zip
178.1129 + if (length == 3 && TokenUtilities.textEquals(s, "zip")) { // NOI18N
178.1130 + return PythonTokenId.BUILTIN_FUNCTION;
178.1131 + }
178.1132 + break;
178.1133 + case 'F': // False
178.1134 + if (length == 5 && TokenUtilities.textEquals(s, "False")) { // NOI18N
178.1135 + return PythonTokenId.FALSE;
178.1136 + }
178.1137 + break;
178.1138 + case 'N': // None
178.1139 + if (length == 4 && TokenUtilities.textEquals(s, "None")) { // NOI18N
178.1140 + return PythonTokenId.NONE;
178.1141 + }
178.1142 + break;
178.1143 + case 'T': // True
178.1144 + if (length == 4 && TokenUtilities.textEquals(s, "True")) { // NOI18N
178.1145 + return PythonTokenId.TRUE;
178.1146 + }
178.1147 + break;
178.1148 + case '_': // Special symbols of python
178.1149 + if (length > 4 && TokenUtilities.startsWith(s, "__") && TokenUtilities.endsWith(s, "__")) { // NOI18N
178.1150 + return PythonTokenId.BUILTIN_FUNCTION;
178.1151 + }
178.1152 + break;
178.1153 + }
178.1154 +
178.1155 + return null;
178.1156 + }
178.1157 +
178.1158 + public static boolean isKeywordOrBuiltin(CharSequence name) {
178.1159 + return getKeywordToken(name) != null;
178.1160 + }
178.1161 +}
179.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
179.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonLexerUtils.java Mon Sep 21 13:01:16 2015 +0200
179.3 @@ -0,0 +1,562 @@
179.4 +/*
179.5 + * To change this template, choose Tools | Templates
179.6 + * and open the template in the editor.
179.7 + */
179.8 +package org.netbeans.modules.python.source.lexer;
179.9 +
179.10 +import java.util.Arrays;
179.11 +import java.util.List;
179.12 +import java.util.regex.Matcher;
179.13 +import java.util.regex.Pattern;
179.14 +import javax.swing.text.BadLocationException;
179.15 +import javax.swing.text.Document;
179.16 +import org.netbeans.api.lexer.Token;
179.17 +import org.netbeans.api.lexer.TokenHierarchy;
179.18 +import org.netbeans.api.lexer.TokenId;
179.19 +import org.netbeans.api.lexer.TokenSequence;
179.20 +import org.netbeans.editor.BaseDocument;
179.21 +import org.netbeans.editor.Utilities;
179.22 +import org.netbeans.modules.csl.api.OffsetRange;
179.23 +import org.netbeans.modules.python.source.PythonParserResult;
179.24 +import org.openide.filesystems.FileUtil;
179.25 +import org.openide.loaders.DataObject;
179.26 +import org.openide.util.Exceptions;
179.27 +import org.python.antlr.PythonTree;
179.28 +
179.29 +/**
179.30 + * Utility functions around the Python lexer
179.31 + *
179.32 + * @author Tor Norbye
179.33 + */
179.34 +public class PythonLexerUtils {
179.35 + /**
179.36 + * Try to produce a more accurate location for the given name in the given import statement, located
179.37 + * at the lexRange provided
179.38 + */
179.39 + public static OffsetRange getImportNameOffset(BaseDocument doc, OffsetRange lexRange, PythonTree node, String name) {
179.40 + int docLength = doc.getLength();
179.41 + int start = Math.min(docLength, lexRange.getStart());
179.42 + int end = Math.min(docLength, lexRange.getEnd());
179.43 + try {
179.44 + String s = doc.getText(start, end - start);
179.45 +
179.46 + Pattern p = Pattern.compile(".*import\\s+\\b(" + name + ")\\b.*");
179.47 + Matcher m = p.matcher(s);
179.48 + if (m.matches()) {
179.49 + int offset = start + m.start(1);
179.50 + return new OffsetRange(offset, offset + name.length());
179.51 + }
179.52 +
179.53 + // Lame
179.54 + int searchIndex = s.indexOf("import ");
179.55 + if (searchIndex == -1) {
179.56 + searchIndex = 0;
179.57 + } else {
179.58 + searchIndex += 7;
179.59 + }
179.60 + int match = s.indexOf(name, searchIndex + 7);
179.61 + if (match != -1) {
179.62 + int offset = start + match;
179.63 + return new OffsetRange(offset, offset + name.length());
179.64 + }
179.65 +
179.66 + // Give up - use the whole range
179.67 + } catch (BadLocationException ex) {
179.68 + Exceptions.printStackTrace(ex);
179.69 + }
179.70 +
179.71 + return lexRange;
179.72 + }
179.73 +
179.74 + /** For a possibly generated offset in an AST, return the corresponding lexing/true document offset */
179.75 + public static int getLexerOffset(PythonParserResult result, int astOffset) {
179.76 + return result.getSnapshot().getOriginalOffset(astOffset);
179.77 + }
179.78 +
179.79 + public static OffsetRange getLexerOffsets(PythonParserResult result, OffsetRange astRange) {
179.80 + if (result != null) {
179.81 + int rangeStart = astRange.getStart();
179.82 + int start = result.getSnapshot().getOriginalOffset(rangeStart);
179.83 + if (start == rangeStart) {
179.84 + return astRange;
179.85 + } else if (start == -1) {
179.86 + return OffsetRange.NONE;
179.87 + } else {
179.88 + // Assumes the translated range maintains size
179.89 + return new OffsetRange(start, start + astRange.getLength());
179.90 + }
179.91 + }
179.92 +
179.93 + return astRange;
179.94 + }
179.95 +
179.96 + /**
179.97 + * Narrow a given lexical offset range to the closest AST-relevant offsets.
179.98 + * This means it will pass over things like comments and whitespace.
179.99 + * @param doc The document containing the range
179.100 + * @param range The start/end lexical range we want to narrow
179.101 + * @return An OffsetRange where the offsets begin and end at AST-relevant tokens
179.102 + */
179.103 + public static OffsetRange narrow(BaseDocument doc, OffsetRange range, boolean skipComments) {
179.104 + try {
179.105 + doc.readLock(); // For token hiearchy use
179.106 + // For token hiearchy use
179.107 + int start = range.getStart();
179.108 + TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, start);
179.109 + if (ts != null) {
179.110 + int delta = ts.move(start);
179.111 + while (ts.moveNext()) {
179.112 + Token<? extends PythonTokenId> token = ts.token();
179.113 + PythonTokenId id = token.id();
179.114 + if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
179.115 + if (delta != 0) {
179.116 + return OffsetRange.NONE;
179.117 + }
179.118 + start = ts.offset();
179.119 + break;
179.120 + } else {
179.121 + delta = 0;
179.122 + }
179.123 + }
179.124 + }
179.125 + int end = range.getEnd();
179.126 + ts = getPositionedSequence(doc, end);
179.127 + if (ts != null) {
179.128 + int delta = ts.move(end);
179.129 + while (delta > 0 ? ts.moveNext() : ts.movePrevious()) {
179.130 + Token<? extends PythonTokenId> token = ts.token();
179.131 + PythonTokenId id = token.id();
179.132 + if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
179.133 + if (delta != 0) {
179.134 + return OffsetRange.NONE;
179.135 + }
179.136 + end = ts.offset() + token.length();
179.137 + break;
179.138 + } else {
179.139 + delta = 0;
179.140 + }
179.141 + }
179.142 + }
179.143 +
179.144 + if (end < start) {
179.145 + return OffsetRange.NONE;
179.146 + }
179.147 +
179.148 + return new OffsetRange(start, end);
179.149 + } finally {
179.150 + doc.readUnlock();
179.151 + }
179.152 + }
179.153 +
179.154 + /** Find the ruby token sequence (in case it's embedded in something else at the top level */
179.155 + @SuppressWarnings("unchecked")
179.156 + public static TokenSequence<? extends PythonTokenId> getPythonSequence(BaseDocument doc, int offset) {
179.157 + TokenHierarchy<Document> th = TokenHierarchy.get((Document)doc);
179.158 + return getPythonSequence(th, offset);
179.159 + }
179.160 +
179.161 + @SuppressWarnings("unchecked")
179.162 + public static TokenSequence<? extends PythonTokenId> getPythonSequence(TokenHierarchy<Document> th, int offset) {
179.163 + TokenSequence<? extends PythonTokenId> ts = th.tokenSequence(PythonTokenId.language());
179.164 +
179.165 + if (ts == null) {
179.166 + // Possibly an embedding scenario such as an RHTML file
179.167 + // First try with backward bias true
179.168 + List<TokenSequence<?>> list = th.embeddedTokenSequences(offset, true);
179.169 +
179.170 + for (TokenSequence t : list) {
179.171 + if (t.language() == PythonTokenId.language()) {
179.172 + ts = t;
179.173 +
179.174 + break;
179.175 + }
179.176 + }
179.177 +
179.178 + if (ts == null) {
179.179 + list = th.embeddedTokenSequences(offset, false);
179.180 +
179.181 + for (TokenSequence t : list) {
179.182 + if (t.language() == PythonTokenId.language()) {
179.183 + ts = t;
179.184 +
179.185 + break;
179.186 + }
179.187 + }
179.188 + }
179.189 + }
179.190 +
179.191 + return ts;
179.192 + }
179.193 +
179.194 + public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset) {
179.195 + return getPositionedSequence(doc, offset, true);
179.196 + }
179.197 +
179.198 + public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset, boolean lookBack) {
179.199 + TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, offset);
179.200 +
179.201 + if (ts != null) {
179.202 + try {
179.203 + ts.move(offset);
179.204 + } catch (AssertionError e) {
179.205 + DataObject dobj = (DataObject)doc.getProperty(Document.StreamDescriptionProperty);
179.206 +
179.207 + if (dobj != null) {
179.208 + Exceptions.attachMessage(e, FileUtil.getFileDisplayName(dobj.getPrimaryFile()));
179.209 + }
179.210 +
179.211 + throw e;
179.212 + }
179.213 +
179.214 + if (!lookBack && !ts.moveNext()) {
179.215 + return null;
179.216 + } else if (lookBack && !ts.moveNext() && !ts.movePrevious()) {
179.217 + return null;
179.218 + }
179.219 +
179.220 + /* TODO - allow Python inside strings
179.221 + if (ts.token().id() == PythonTokenId.STRING_LITERAL) {
179.222 + TokenSequence<? extends PythonStringTokenId> ets = ts.embedded(PythonStringTokenId.language());
179.223 + if (ets != null) {
179.224 + ets.move(offset);
179.225 + if ((!lookBack && ets.moveNext()) || (lookBack && ets.movePrevious())) {
179.226 + TokenSequence<?extends PythonTokenId> epts = ets.embedded(PythonTokenId.language());
179.227 + if (epts != null) {
179.228 + epts.move(offset);
179.229 + if (!lookBack && !epts.moveNext()) {
179.230 + return null;
179.231 + } else if (lookBack && !epts.moveNext() && !epts.movePrevious()) {
179.232 + return null;
179.233 + }
179.234 + return epts;
179.235 + }
179.236 + }
179.237 + }
179.238 + }
179.239 + */
179.240 +
179.241 + return ts;
179.242 + }
179.243 +
179.244 + return null;
179.245 + }
179.246 +
179.247 + public static Token<? extends PythonTokenId> getToken(BaseDocument doc, int offset) {
179.248 + TokenSequence<? extends PythonTokenId> ts = getPositionedSequence(doc, offset);
179.249 +
179.250 + if (ts != null) {
179.251 + return ts.token();
179.252 + }
179.253 +
179.254 + return null;
179.255 + }
179.256 +
179.257 + public static char getTokenChar(BaseDocument doc, int offset) {
179.258 + Token<? extends PythonTokenId> token = getToken(doc, offset);
179.259 +
179.260 + if (token != null) {
179.261 + String text = token.text().toString();
179.262 +
179.263 + if (text.length() > 0) { // Usually true, but I could have gotten EOF right?
179.264 +
179.265 + return text.charAt(0);
179.266 + }
179.267 + }
179.268 +
179.269 + return 0;
179.270 + }
179.271 +
179.272 + public static Token<? extends PythonTokenId> findNextNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
179.273 + return findNext(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
179.274 + }
179.275 +
179.276 + public static Token<? extends PythonTokenId> findPreviousNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
179.277 + return findPrevious(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
179.278 + }
179.279 +
179.280 + public static Token<? extends PythonTokenId> findNext(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
179.281 + if (ignores.contains(ts.token().id())) {
179.282 + while (ts.moveNext() && ignores.contains(ts.token().id())) {
179.283 + }
179.284 + }
179.285 + return ts.token();
179.286 + }
179.287 +
179.288 + public static Token<? extends PythonTokenId> findNextIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
179.289 + while (ts.moveNext() && !includes.contains(ts.token().id())) {
179.290 + }
179.291 + return ts.token();
179.292 + }
179.293 +
179.294 + public static Token<? extends PythonTokenId> findPreviousIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
179.295 + while (ts.movePrevious() && !includes.contains(ts.token().id())) {
179.296 + }
179.297 + return ts.token();
179.298 + }
179.299 +
179.300 + public static Token<? extends PythonTokenId> findPrevious(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
179.301 + if (ignores.contains(ts.token().id())) {
179.302 + while (ts.movePrevious() && ignores.contains(ts.token().id())) {
179.303 + }
179.304 + }
179.305 + return ts.token();
179.306 + }
179.307 +
179.308 + static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts) {
179.309 + return skipParenthesis(ts, false);
179.310 + }
179.311 +
179.312 + /**
179.313 + * Tries to skip parenthesis
179.314 + */
179.315 + public static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts, boolean back) {
179.316 + int balance = 0;
179.317 +
179.318 + Token<? extends PythonTokenId> token = ts.token();
179.319 + if (token == null) {
179.320 + return false;
179.321 + }
179.322 +
179.323 + TokenId id = token.id();
179.324 +
179.325 + if (id == PythonTokenId.WHITESPACE || id == PythonTokenId.NEWLINE) {
179.326 + while ((back ? ts.movePrevious() : ts.moveNext()) && (ts.token().id() == PythonTokenId.WHITESPACE || ts.token().id() == PythonTokenId.NEWLINE)) {
179.327 + }
179.328 + }
179.329 +
179.330 + // if current token is not left parenthesis
179.331 + if (ts.token().id() != (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
179.332 + return false;
179.333 + }
179.334 +
179.335 + do {
179.336 + token = ts.token();
179.337 + id = token.id();
179.338 +
179.339 + if (id == (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
179.340 + balance++;
179.341 + } else if (id == (back ? PythonTokenId.LPAREN : PythonTokenId.RPAREN)) {
179.342 + if (balance == 0) {
179.343 + return false;
179.344 + } else if (balance == 1) {
179.345 + //int length = ts.offset() + token.length();
179.346 + if (back) {
179.347 + ts.movePrevious();
179.348 + } else {
179.349 + ts.moveNext();
179.350 + }
179.351 + return true;
179.352 + }
179.353 +
179.354 + balance--;
179.355 + }
179.356 + } while (back ? ts.movePrevious() : ts.moveNext());
179.357 +
179.358 + return false;
179.359 + }
179.360 +
179.361 + /** Search forwards in the token sequence until a token of type <code>down</code> is found */
179.362 + public static OffsetRange findFwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
179.363 + TokenId down) {
179.364 + int balance = 0;
179.365 +
179.366 + while (ts.moveNext()) {
179.367 + Token<? extends PythonTokenId> token = ts.token();
179.368 + TokenId id = token.id();
179.369 +
179.370 + if (id == up) {
179.371 + balance++;
179.372 + } else if (id == down) {
179.373 + if (balance == 0) {
179.374 + return new OffsetRange(ts.offset(), ts.offset() + token.length());
179.375 + }
179.376 +
179.377 + balance--;
179.378 + }
179.379 + }
179.380 +
179.381 + return OffsetRange.NONE;
179.382 + }
179.383 +
179.384 + /** Search backwards in the token sequence until a token of type <code>up</code> is found */
179.385 + public static OffsetRange findBwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
179.386 + TokenId down) {
179.387 + int balance = 0;
179.388 +
179.389 + while (ts.movePrevious()) {
179.390 + Token<? extends PythonTokenId> token = ts.token();
179.391 + TokenId id = token.id();
179.392 +
179.393 + if (id == up) {
179.394 + if (balance == 0) {
179.395 + return new OffsetRange(ts.offset(), ts.offset() + token.length());
179.396 + }
179.397 +
179.398 + balance++;
179.399 + } else if (id == down) {
179.400 + balance--;
179.401 + }
179.402 + }
179.403 +
179.404 + return OffsetRange.NONE;
179.405 + }
179.406 +
179.407 + /** Compute the balance of begin/end tokens on the line */
179.408 + public static int getLineBalance(BaseDocument doc, int offset, TokenId up, TokenId down) {
179.409 + try {
179.410 + int begin = Utilities.getRowStart(doc, offset);
179.411 + int end = Utilities.getRowEnd(doc, offset);
179.412 +
179.413 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, begin);
179.414 + if (ts == null) {
179.415 + return 0;
179.416 + }
179.417 +
179.418 + ts.move(begin);
179.419 +
179.420 + if (!ts.moveNext()) {
179.421 + return 0;
179.422 + }
179.423 +
179.424 + int balance = 0;
179.425 +
179.426 + do {
179.427 + Token<? extends PythonTokenId> token = ts.token();
179.428 + TokenId id = token.id();
179.429 +
179.430 + if (id == up) {
179.431 + balance++;
179.432 + } else if (id == down) {
179.433 + balance--;
179.434 + }
179.435 + } while (ts.moveNext() && (ts.offset() <= end));
179.436 +
179.437 + return balance;
179.438 + } catch (BadLocationException ble) {
179.439 + Exceptions.printStackTrace(ble);
179.440 +
179.441 + return 0;
179.442 + }
179.443 + }
179.444 +
179.445 + /**
179.446 + * The same as braceBalance but generalized to any pair of matching
179.447 + * tokens.
179.448 + * @param open the token that increses the count
179.449 + * @param close the token that decreses the count
179.450 + */
179.451 + public static int getTokenBalance(BaseDocument doc, TokenId open, TokenId close, int offset)
179.452 + throws BadLocationException {
179.453 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, 0);
179.454 + if (ts == null) {
179.455 + return 0;
179.456 + }
179.457 +
179.458 + // XXX Why 0? Why not offset?
179.459 + ts.moveIndex(0);
179.460 +
179.461 + if (!ts.moveNext()) {
179.462 + return 0;
179.463 + }
179.464 +
179.465 + int balance = 0;
179.466 +
179.467 + do {
179.468 + Token t = ts.token();
179.469 +
179.470 + if (t.id() == open) {
179.471 + balance++;
179.472 + } else if (t.id() == close) {
179.473 + balance--;
179.474 + }
179.475 + } while (ts.moveNext());
179.476 +
179.477 + return balance;
179.478 + }
179.479 +
179.480 + /**
179.481 + * Return true iff the line for the given offset is a JavaScript comment line.
179.482 + * This will return false for lines that contain comments (even when the
179.483 + * offset is within the comment portion) but also contain code.
179.484 + */
179.485 + public static boolean isCommentOnlyLine(BaseDocument doc, int offset)
179.486 + throws BadLocationException {
179.487 + int begin = Utilities.getRowFirstNonWhite(doc, offset);
179.488 +
179.489 + if (begin == -1) {
179.490 + return false; // whitespace only
179.491 + }
179.492 +
179.493 + Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, begin);
179.494 + if (token != null) {
179.495 + return token.id() == PythonTokenId.COMMENT;
179.496 + }
179.497 +
179.498 + return false;
179.499 + }
179.500 +
179.501 + /**
179.502 + * Back up to the first space character prior to the given offset - as long as
179.503 + * it's on the same line! If there's only leading whitespace on the line up
179.504 + * to the lex offset, return the offset itself
179.505 + * @todo Rewrite this now that I have a separate newline token, EOL, that I can
179.506 + * break on - no need to call Utilities.getRowStart.
179.507 + */
179.508 + public static int findSpaceBegin(BaseDocument doc, int lexOffset) {
179.509 + TokenSequence ts = getPythonSequence(doc, lexOffset);
179.510 + if (ts == null) {
179.511 + return lexOffset;
179.512 + }
179.513 + boolean allowPrevLine = false;
179.514 + int lineStart;
179.515 + try {
179.516 + lineStart = Utilities.getRowStart(doc, Math.min(lexOffset, doc.getLength()));
179.517 + int prevLast = lineStart - 1;
179.518 + if (lineStart > 0) {
179.519 + prevLast = Utilities.getRowLastNonWhite(doc, lineStart - 1);
179.520 + if (prevLast != -1) {
179.521 + char c = doc.getText(prevLast, 1).charAt(0);
179.522 + if (c == ',') {
179.523 + // Arglist continuation? // TODO : check lexing
179.524 + allowPrevLine = true;
179.525 + }
179.526 + }
179.527 + }
179.528 + if (!allowPrevLine) {
179.529 + int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
179.530 + if (lexOffset <= firstNonWhite || firstNonWhite == -1) {
179.531 + return lexOffset;
179.532 + }
179.533 + } else {
179.534 + // Make lineStart so small that Math.max won't cause any problems
179.535 + int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
179.536 + if (prevLast >= 0 && (lexOffset <= firstNonWhite || firstNonWhite == -1)) {
179.537 + return prevLast + 1;
179.538 + }
179.539 + lineStart = 0;
179.540 + }
179.541 + } catch (BadLocationException ble) {
179.542 + Exceptions.printStackTrace(ble);
179.543 + return lexOffset;
179.544 + }
179.545 + ts.move(lexOffset);
179.546 + if (ts.moveNext()) {
179.547 + if (lexOffset > ts.offset()) {
179.548 + // We're in the middle of a token
179.549 + return Math.max((ts.token().id() == PythonTokenId.WHITESPACE) ? ts.offset() : lexOffset, lineStart);
179.550 + }
179.551 + while (ts.movePrevious()) {
179.552 + Token token = ts.token();
179.553 + if (token.id() != PythonTokenId.WHITESPACE) {
179.554 + return Math.max(ts.offset() + token.length(), lineStart);
179.555 + }
179.556 + }
179.557 + }
179.558 +
179.559 + return lexOffset;
179.560 + }
179.561 +
179.562 + public static boolean isKeywordOrBuiltin(CharSequence name) {
179.563 + return PythonLexer.isKeywordOrBuiltin(name);
179.564 + }
179.565 +}
180.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonStringLexer.java Mon Sep 21 13:01:16 2015 +0200
180.3 @@ -0,0 +1,292 @@
180.4 +/*
180.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
180.6 + *
180.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
180.8 + *
180.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
180.10 + * Other names may be trademarks of their respective owners.
180.11 + *
180.12 + * The contents of this file are subject to the terms of either the GNU
180.13 + * General Public License Version 2 only ("GPL") or the Common
180.14 + * Development and Distribution License("CDDL") (collectively, the
180.15 + * "License"). You may not use this file except in compliance with the
180.16 + * License. You can obtain a copy of the License at
180.17 + * http://www.netbeans.org/cddl-gplv2.html
180.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
180.19 + * specific language governing permissions and limitations under the
180.20 + * License. When distributing the software, include this License Header
180.21 + * Notice in each file and include the License file at
180.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
180.23 + * particular file as subject to the "Classpath" exception as provided
180.24 + * by Oracle in the GPL Version 2 section of the License file that
180.25 + * accompanied this code. If applicable, add the following below the
180.26 + * License Header, with the fields enclosed by brackets [] replaced by
180.27 + * your own identifying information:
180.28 + * "Portions Copyrighted [year] [name of copyright owner]"
180.29 + *
180.30 + * Contributor(s):
180.31 + *
180.32 + * The Original Software is NetBeans. The Initial Developer of the Original
180.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
180.34 + * Microsystems, Inc. All Rights Reserved.
180.35 + *
180.36 + * If you wish your version of this file to be governed by only the CDDL
180.37 + * or only the GPL Version 2, indicate your decision by adding
180.38 + * "[Contributor] elects to include this software in this distribution
180.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
180.40 + * single choice of license, a recipient has the option to distribute
180.41 + * your version of this file under either the CDDL, the GPL Version 2 or
180.42 + * to extend the choice of license to its licensees as provided above.
180.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
180.44 + * Version 2 license, then the option applies only if the new code is
180.45 + * made subject to such option by the copyright holder.
180.46 + */
180.47 +package org.netbeans.modules.python.source.lexer;
180.48 +
180.49 +import org.netbeans.api.lexer.Token;
180.50 +import org.netbeans.spi.lexer.Lexer;
180.51 +import org.netbeans.spi.lexer.LexerInput;
180.52 +import org.netbeans.spi.lexer.LexerRestartInfo;
180.53 +import org.netbeans.spi.lexer.TokenFactory;
180.54 +
180.55 +/**
180.56 + * A lexer for python strings. Highlights escape sequences, and recognizes
180.57 + * doctest sections and highlights these as well.
180.58 + * http://docs.python.org/lib/module-doctest.html
180.59 + *
180.60 + * @todo Track whether strings are raw or not, and don't do escape sequence
180.61 + * highlighting in raw strings
180.62 + *
180.63 + * @author Tor Norbye
180.64 + */
180.65 +public class PythonStringLexer implements Lexer<PythonStringTokenId> {
180.66 + private static final int EOF = LexerInput.EOF;
180.67 + private final LexerInput input;
180.68 + private final TokenFactory<PythonStringTokenId> tokenFactory;
180.69 + private final boolean substituting;
180.70 +
180.71 + /**
180.72 + * A Lexer for Python strings
180.73 + * @param substituting If true, handle substitution rules for double quoted strings, otherwise
180.74 + * single quoted strings.
180.75 + */
180.76 + public PythonStringLexer(LexerRestartInfo<PythonStringTokenId> info, boolean substituting) {
180.77 + this.input = info.input();
180.78 + this.tokenFactory = info.tokenFactory();
180.79 + this.substituting = substituting;
180.80 + assert (info.state() == null); // passed argument always null
180.81 + }
180.82 +
180.83 + @Override
180.84 + public Object state() {
180.85 + return null;
180.86 + }
180.87 +
180.88 + @Override
180.89 + public Token<PythonStringTokenId> nextToken() {
180.90 + boolean inWord = false;
180.91 + while (true) {
180.92 + int ch = input.read();
180.93 +
180.94 + switch (ch) {
180.95 + case EOF:
180.96 +
180.97 + if (input.readLength() > 0) {
180.98 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
180.99 + input.readLength());
180.100 + } else {
180.101 + return null;
180.102 + }
180.103 +
180.104 + case '>':
180.105 + // Look for doctest: \n, whitespace, >>>{embedded python}\n
180.106 + int initialReadLength = input.readLength();
180.107 + input.read();
180.108 + if (ch == '>') {
180.109 + ch = input.read();
180.110 + if (ch == '>') {
180.111 + if (input.readLength() > 3) {
180.112 + input.backup(3);
180.113 + // Finish this token such that we can do a dedicated token for the ">>>" line.
180.114 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
180.115 + input.readLength());
180.116 + }
180.117 + // Find end...
180.118 + boolean nonempty = false;
180.119 + while (true) {
180.120 + ch = input.read();
180.121 + if (ch == EOF) {
180.122 + break;
180.123 + } else if (ch == '\n') {
180.124 + if (nonempty) {
180.125 + input.backup(1); // Don't include the \n
180.126 + return tokenFactory.createToken(PythonStringTokenId.EMBEDDED_PYTHON,
180.127 + input.readLength());
180.128 +
180.129 + }
180.130 + break;
180.131 + } else if (!Character.isWhitespace(ch)) {
180.132 + nonempty = true;
180.133 + }
180.134 + }
180.135 + }
180.136 + }
180.137 + if (input.readLength() > initialReadLength) {
180.138 + input.backup(input.readLength() - initialReadLength);
180.139 + } else {
180.140 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
180.141 + input.readLength());
180.142 + }
180.143 + break;
180.144 +
180.145 + case '\\':
180.146 +
180.147 + if (input.readLength() > 1) { // already read some text
180.148 + input.backup(1);
180.149 +
180.150 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
180.151 + input.readLength());
180.152 + }
180.153 +
180.154 + ch = input.read();
180.155 + if (ch == EOF) {
180.156 + return tokenFactory.createToken(PythonStringTokenId.STRING_INVALID,
180.157 + input.readLength());
180.158 + } else {
180.159 + return tokenFactory.createToken(PythonStringTokenId.STRING_ESCAPE,
180.160 + input.readLength());
180.161 + }
180.162 +
180.163 + case 'f': // ftp:
180.164 + case 'm': // mailto:
180.165 + case 'w': // www.
180.166 + case 'h': { // http links. TODO: link:, ftp:, mailto:, and www.
180.167 +
180.168 + if (inWord) {
180.169 + break;
180.170 + }
180.171 +
180.172 + int originalLength = input.readLength();
180.173 + boolean foundLinkBegin = false;
180.174 +
180.175 + if (ch == 'h') { // http:
180.176 +
180.177 + if (input.read() == 't') {
180.178 + if (input.read() == 't') {
180.179 + if (input.read() == 'p') {
180.180 + int r = input.read();
180.181 + if (r == ':') {
180.182 + foundLinkBegin = true;
180.183 + } else if (r == 's') {
180.184 + if (input.read() == ':') {
180.185 + foundLinkBegin = true;
180.186 + } else {
180.187 + input.backup(5);
180.188 + }
180.189 + } else {
180.190 + input.backup(4);
180.191 + }
180.192 + } else {
180.193 + input.backup(3);
180.194 + }
180.195 + } else {
180.196 + input.backup(2);
180.197 + }
180.198 + } else {
180.199 + input.backup(1);
180.200 + }
180.201 + } else if (ch == 'f') { // ftp:
180.202 +
180.203 + if (input.read() == 't') {
180.204 + if (input.read() == 'p') {
180.205 + if (input.read() == ':') {
180.206 + foundLinkBegin = true;
180.207 + } else {
180.208 + input.backup(3);
180.209 + }
180.210 + } else {
180.211 + input.backup(2);
180.212 + }
180.213 + } else {
180.214 + input.backup(1);
180.215 + }
180.216 + } else if (ch == 'm') { // mailto:
180.217 +
180.218 + if (input.read() == 'a') {
180.219 + if (input.read() == 'i') {
180.220 + if (input.read() == 'l') {
180.221 + if (input.read() == 't') {
180.222 + if (input.read() == 'o') {
180.223 + if (input.read() == ':') {
180.224 + foundLinkBegin = true;
180.225 + } else {
180.226 + input.backup(6);
180.227 + }
180.228 + } else {
180.229 + input.backup(5);
180.230 + }
180.231 + } else {
180.232 + input.backup(4);
180.233 + }
180.234 + } else {
180.235 + input.backup(3);
180.236 + }
180.237 + } else {
180.238 + input.backup(2);
180.239 + }
180.240 + } else {
180.241 + input.backup(1);
180.242 + }
180.243 + } else if (ch == 'w') { // www.
180.244 +
180.245 + if (input.read() == 'w') {
180.246 + if (input.read() == 'w') {
180.247 + if (input.read() == '.') {
180.248 + foundLinkBegin = true;
180.249 + } else {
180.250 + input.backup(3);
180.251 + }
180.252 + } else {
180.253 + input.backup(2);
180.254 + }
180.255 + } else {
180.256 + input.backup(1);
180.257 + }
180.258 + }
180.259 +
180.260 + if (foundLinkBegin) {
180.261 + while (ch != EOF) {
180.262 + ch = input.read();
180.263 +
180.264 + if ((ch == ']') || (ch == ')') || Character.isWhitespace(ch) ||
180.265 + (ch == '\'') || (ch == '"')) {
180.266 + input.backup(1);
180.267 +
180.268 + break;
180.269 + }
180.270 + }
180.271 +
180.272 + if (originalLength > 1) {
180.273 + input.backup(input.readLengthEOF() - originalLength + 1);
180.274 +
180.275 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
180.276 + input.readLength());
180.277 + }
180.278 +
180.279 + if (input.readLength() > 2) {
180.280 + return tokenFactory.createToken(PythonStringTokenId.URL,
180.281 + input.readLength());
180.282 + }
180.283 + }
180.284 + break;
180.285 + }
180.286 + }
180.287 +
180.288 + inWord = Character.isJavaIdentifierPart(ch);
180.289 + }
180.290 + }
180.291 +
180.292 + @Override
180.293 + public void release() {
180.294 + }
180.295 +}
181.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
181.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonStringTokenId.java Mon Sep 21 13:01:16 2015 +0200
181.3 @@ -0,0 +1,125 @@
181.4 +/*
181.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
181.6 + *
181.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
181.8 + *
181.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
181.10 + * Other names may be trademarks of their respective owners.
181.11 + *
181.12 + * The contents of this file are subject to the terms of either the GNU
181.13 + * General Public License Version 2 only ("GPL") or the Common
181.14 + * Development and Distribution License("CDDL") (collectively, the
181.15 + * "License"). You may not use this file except in compliance with the
181.16 + * License. You can obtain a copy of the License at
181.17 + * http://www.netbeans.org/cddl-gplv2.html
181.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
181.19 + * specific language governing permissions and limitations under the
181.20 + * License. When distributing the software, include this License Header
181.21 + * Notice in each file and include the License file at
181.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
181.23 + * particular file as subject to the "Classpath" exception as provided
181.24 + * by Oracle in the GPL Version 2 section of the License file that
181.25 + * accompanied this code. If applicable, add the following below the
181.26 + * License Header, with the fields enclosed by brackets [] replaced by
181.27 + * your own identifying information:
181.28 + * "Portions Copyrighted [year] [name of copyright owner]"
181.29 + *
181.30 + * Contributor(s):
181.31 + *
181.32 + * The Original Software is NetBeans. The Initial Developer of the Original
181.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
181.34 + * Microsystems, Inc. All Rights Reserved.
181.35 + *
181.36 + * If you wish your version of this file to be governed by only the CDDL
181.37 + * or only the GPL Version 2, indicate your decision by adding
181.38 + * "[Contributor] elects to include this software in this distribution
181.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
181.40 + * single choice of license, a recipient has the option to distribute
181.41 + * your version of this file under either the CDDL, the GPL Version 2 or
181.42 + * to extend the choice of license to its licensees as provided above.
181.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
181.44 + * Version 2 license, then the option applies only if the new code is
181.45 + * made subject to such option by the copyright holder.
181.46 + */
181.47 +package org.netbeans.modules.python.source.lexer;
181.48 +
181.49 +import java.util.Collection;
181.50 +import java.util.EnumSet;
181.51 +import java.util.Map;
181.52 +
181.53 +import org.netbeans.api.lexer.InputAttributes;
181.54 +import org.netbeans.api.lexer.Language;
181.55 +import org.netbeans.api.lexer.LanguagePath;
181.56 +import org.netbeans.api.lexer.Token;
181.57 +import org.netbeans.api.lexer.TokenId;
181.58 +import org.netbeans.api.lexer.TokenUtilities;
181.59 +import org.netbeans.spi.lexer.LanguageEmbedding;
181.60 +import org.netbeans.spi.lexer.LanguageHierarchy;
181.61 +import org.netbeans.spi.lexer.Lexer;
181.62 +import org.netbeans.spi.lexer.LexerRestartInfo;
181.63 +
181.64 +/**
181.65 + *
181.66 + * @author Tor Norbye
181.67 + */
181.68 +public enum PythonStringTokenId implements TokenId {
181.69 + STRING_TEXT("string"),
181.70 + STRING_ESCAPE("string-escape"),
181.71 + STRING_INVALID("string-escape-invalid"),
181.72 + URL("url"),
181.73 + EMBEDDED_PYTHON("string");
181.74 + private final String primaryCategory;
181.75 +
181.76 + PythonStringTokenId() {
181.77 + this(null);
181.78 + }
181.79 +
181.80 + PythonStringTokenId(String primaryCategory) {
181.81 + this.primaryCategory = primaryCategory;
181.82 + }
181.83 +
181.84 + @Override
181.85 + public String primaryCategory() {
181.86 + return primaryCategory;
181.87 + }
181.88 + public static final Language<PythonStringTokenId> language =
181.89 + new LanguageHierarchy<PythonStringTokenId>() {
181.90 + @Override
181.91 + protected Collection<PythonStringTokenId> createTokenIds() {
181.92 + return EnumSet.allOf(PythonStringTokenId.class);
181.93 + }
181.94 +
181.95 + @Override
181.96 + protected Map<String, Collection<PythonStringTokenId>> createTokenCategories() {
181.97 + return null; // no extra categories
181.98 + }
181.99 +
181.100 + @Override
181.101 + protected Lexer<PythonStringTokenId> createLexer(
181.102 + LexerRestartInfo<PythonStringTokenId> info) {
181.103 + return new PythonStringLexer(info, true);
181.104 + }
181.105 +
181.106 + @Override
181.107 + protected LanguageEmbedding<?> embedding(
181.108 + Token<PythonStringTokenId> token, LanguagePath languagePath,
181.109 + InputAttributes inputAttributes) {
181.110 + PythonStringTokenId id = token.id();
181.111 +
181.112 + if (id == EMBEDDED_PYTHON && token.text() != null) {
181.113 + return LanguageEmbedding.create(PythonTokenId.language(), 3, 0); // 3: Exlude ">>>" prefix
181.114 + }
181.115 +
181.116 + return null; // No embedding
181.117 + }
181.118 +
181.119 + @Override
181.120 + public String mimeType() {
181.121 + return "text/x-python-string"; // NOI18N
181.122 + }
181.123 + }.language();
181.124 +
181.125 + public static Language<PythonStringTokenId> language() {
181.126 + return language;
181.127 + }
181.128 +}
182.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
182.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonTokenId.java Mon Sep 21 13:01:16 2015 +0200
182.3 @@ -0,0 +1,206 @@
182.4 +/*
182.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
182.6 + *
182.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
182.8 + *
182.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
182.10 + * Other names may be trademarks of their respective owners.
182.11 + *
182.12 + * The contents of this file are subject to the terms of either the GNU
182.13 + * General Public License Version 2 only ("GPL") or the Common
182.14 + * Development and Distribution License("CDDL") (collectively, the
182.15 + * "License"). You may not use this file except in compliance with the
182.16 + * License. You can obtain a copy of the License at
182.17 + * http://www.netbeans.org/cddl-gplv2.html
182.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
182.19 + * specific language governing permissions and limitations under the
182.20 + * License. When distributing the software, include this License Header
182.21 + * Notice in each file and include the License file at
182.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
182.23 + * particular file as subject to the "Classpath" exception as provided
182.24 + * by Oracle in the GPL Version 2 section of the License file that
182.25 + * accompanied this code. If applicable, add the following below the
182.26 + * License Header, with the fields enclosed by brackets [] replaced by
182.27 + * your own identifying information:
182.28 + * "Portions Copyrighted [year] [name of copyright owner]"
182.29 + *
182.30 + * Contributor(s):
182.31 + *
182.32 + * The Original Software is NetBeans. The Initial Developer of the Original
182.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
182.34 + * Microsystems, Inc. All Rights Reserved.
182.35 + *
182.36 + * If you wish your version of this file to be governed by only the CDDL
182.37 + * or only the GPL Version 2, indicate your decision by adding
182.38 + * "[Contributor] elects to include this software in this distribution
182.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
182.40 + * single choice of license, a recipient has the option to distribute
182.41 + * your version of this file under either the CDDL, the GPL Version 2 or
182.42 + * to extend the choice of license to its licensees as provided above.
182.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
182.44 + * Version 2 license, then the option applies only if the new code is
182.45 + * made subject to such option by the copyright holder.
182.46 + */
182.47 +package org.netbeans.modules.python.source.lexer;
182.48 +
182.49 +import java.util.Collection;
182.50 +import java.util.EnumSet;
182.51 +import java.util.HashMap;
182.52 +import java.util.Map;
182.53 +import org.netbeans.api.lexer.InputAttributes;
182.54 +import org.netbeans.api.lexer.Language;
182.55 +import org.netbeans.api.lexer.LanguagePath;
182.56 +import org.netbeans.api.lexer.Token;
182.57 +import org.netbeans.api.lexer.TokenId;
182.58 +import org.netbeans.modules.python.api.PythonMIMEResolver;
182.59 +import org.netbeans.modules.python.source.PythonUtils;
182.60 +import org.netbeans.spi.lexer.LanguageEmbedding;
182.61 +import org.netbeans.spi.lexer.LanguageHierarchy;
182.62 +import org.netbeans.spi.lexer.Lexer;
182.63 +import org.netbeans.spi.lexer.LexerInput;
182.64 +import org.netbeans.spi.lexer.LexerRestartInfo;
182.65 +
182.66 +import org.netbeans.spi.lexer.TokenFactory;
182.67 +import org.openide.filesystems.FileObject;
182.68 +import static org.netbeans.modules.python.source.lexer.PythonLexer.*;
182.69 +
182.70 +/**
182.71 + * @todo add the rest of the tokens
182.72 + *
182.73 + * @author Martin Adamek
182.74 + * @author alley
182.75 + */
182.76 +public enum PythonTokenId implements TokenId {
182.77 + ERROR(null, ERROR_CAT),
182.78 + IDENTIFIER(null, IDENTIFIER_CAT),
182.79 + INT_LITERAL(null, NUMBER_CAT),
182.80 + FLOAT_LITERAL(null, NUMBER_CAT),
182.81 + STRING_LITERAL(null, STRING_CAT),
182.82 + WHITESPACE(null, WHITESPACE_CAT),
182.83 + NEWLINE(null, WHITESPACE_CAT),
182.84 + DECORATOR(null, OPERATOR_CAT), // NOI18N
182.85 + // CONTINUED_LINE(null, WHITESPACE_CAT), // NOI18N
182.86 + COMMENT(null, COMMENT_CAT),
182.87 + BUILTIN_FUNCTION(null, KEYWORD_CAT), // NOI18N
182.88 + LPAREN("(", SEPARATOR_CAT), // NOI18N
182.89 + RPAREN(")", SEPARATOR_CAT), // NOI18N
182.90 + LBRACE("{", SEPARATOR_CAT), // NOI18N
182.91 + RBRACE("}", SEPARATOR_CAT), // NOI18N
182.92 + LBRACKET("[", SEPARATOR_CAT), // NOI18N
182.93 + RBRACKET("]", SEPARATOR_CAT), // NOI18N
182.94 + STRING_BEGIN(null, STRING_CAT),
182.95 + STRING_END(null, STRING_CAT),
182.96 + // Cheating: out of laziness just map all keywords returning from Jython
182.97 + // into a single KEYWORD token; eventually we will have separate tokens
182.98 + // for each here such that the various helper methods for formatting,
182.99 + // smart indent, brace matching etc. can refer to specific keywords
182.100 + ANY_KEYWORD(null, KEYWORD_CAT),
182.101 + ANY_OPERATOR(null, OPERATOR_CAT),
182.102 + DEF("def", KEYWORD_CAT), // NOI18N
182.103 + CLASS("class", KEYWORD_CAT), // NOI18N
182.104 + IF("if", KEYWORD_CAT), // NOI18N
182.105 + ELSE("else", KEYWORD_CAT), // NOI18N
182.106 + ELIF("elif", KEYWORD_CAT), // NOI18N
182.107 + RAISE("raise", KEYWORD_CAT), // NOI18N
182.108 + PASS("pass", KEYWORD_CAT), // NOI18N
182.109 + RETURN("return", KEYWORD_CAT), // NOI18N
182.110 + EXCEPT("except", KEYWORD_CAT), // NOI18N
182.111 + FINALLY("finally", KEYWORD_CAT), // NOI18N
182.112 + IMPORT("import", KEYWORD_CAT), // NOI18N
182.113 + FROM("from", KEYWORD_CAT), // NOI18N
182.114 + TRUE("True", KEYWORD_CAT), // NOI18N
182.115 + FALSE("False", KEYWORD_CAT), // NOI18N
182.116 + NONE("None", KEYWORD_CAT), // NOI18N
182.117 + TRY("try", KEYWORD_CAT), // NOI18N
182.118 + DOT(".", OPERATOR_CAT), // NOI18N
182.119 + COMMA(",", OPERATOR_CAT), // NOI18N
182.120 + COLON(":", OPERATOR_CAT), // NOI18N
182.121 + ESC("\\", OPERATOR_CAT), // NOI18N
182.122 +
182.123 + // Non-unary operators which indicate a line continuation if used at the end of a line
182.124 + NONUNARY_OP(null, OPERATOR_CAT);
182.125 + private final String fixedText;
182.126 + private final String primaryCategory;
182.127 +
182.128 + PythonTokenId(String fixedText, String primaryCategory) {
182.129 + this.fixedText = fixedText;
182.130 + this.primaryCategory = primaryCategory;
182.131 + }
182.132 +
182.133 + @Override
182.134 + public String primaryCategory() {
182.135 + return primaryCategory;
182.136 + }
182.137 +
182.138 + public String fixedText() {
182.139 + return fixedText;
182.140 + }
182.141 + private static final Language<PythonTokenId> language =
182.142 + new LanguageHierarchy<PythonTokenId>() {
182.143 + @Override
182.144 + protected String mimeType() {
182.145 + return PythonMIMEResolver.PYTHON_MIME_TYPE;
182.146 + }
182.147 +
182.148 + @Override
182.149 + protected Collection<PythonTokenId> createTokenIds() {
182.150 + return EnumSet.allOf(PythonTokenId.class);
182.151 + }
182.152 +
182.153 + @Override
182.154 + protected Map<String, Collection<PythonTokenId>> createTokenCategories() {
182.155 + Map<String, Collection<PythonTokenId>> cats =
182.156 + new HashMap<>();
182.157 + return cats;
182.158 + }
182.159 +
182.160 + @Override
182.161 + protected Lexer<PythonTokenId> createLexer(LexerRestartInfo<PythonTokenId> info) {
182.162 + FileObject fileObject = (FileObject)info.getAttributeValue(FileObject.class);
182.163 + final TokenFactory<PythonTokenId> tokenFactory = info.tokenFactory();
182.164 + final LexerInput input = info.input();
182.165 + // Lex .rst files just as literal strings
182.166 + if (fileObject != null && PythonUtils.isRstFile(fileObject)) {
182.167 + return new Lexer<PythonTokenId>() {
182.168 + @Override
182.169 + public Token<PythonTokenId> nextToken() {
182.170 + if (input.read() == LexerInput.EOF) {
182.171 + return null;
182.172 + }
182.173 + while (input.read() != LexerInput.EOF) {
182.174 + ;
182.175 + }
182.176 + return tokenFactory.createToken(PythonTokenId.STRING_LITERAL, input.readLength());
182.177 + }
182.178 +
182.179 + @Override
182.180 + public Object state() {
182.181 + return null;
182.182 + }
182.183 +
182.184 + @Override
182.185 + public void release() {
182.186 + }
182.187 + };
182.188 + }
182.189 + return new PythonLexer(info);
182.190 + }
182.191 +
182.192 + @Override
182.193 + protected LanguageEmbedding<?> embedding(Token<PythonTokenId> token,
182.194 + LanguagePath languagePath, InputAttributes inputAttributes) {
182.195 + PythonTokenId id = token.id();
182.196 + if (id == STRING_LITERAL) {
182.197 + return LanguageEmbedding.create(PythonStringTokenId.language, 0, 0);
182.198 + } else if (id == COMMENT) {
182.199 + return LanguageEmbedding.create(PythonCommentTokenId.language(), 1, 0);
182.200 + }
182.201 +
182.202 + return null; // No embedding
182.203 + }
182.204 + }.language();
182.205 +
182.206 + public static Language<PythonTokenId> language() {
182.207 + return language;
182.208 + }
182.209 +}
183.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
183.2 +++ b/python.source/src/org/netbeans/modules/python/source/queries/DeprecationQuery.java Mon Sep 21 13:01:16 2015 +0200
183.3 @@ -0,0 +1,169 @@
183.4 +/*
183.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
183.6 + *
183.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
183.8 + *
183.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
183.10 + * Other names may be trademarks of their respective owners.
183.11 + *
183.12 + * The contents of this file are subject to the terms of either the GNU
183.13 + * General Public License Version 2 only ("GPL") or the Common
183.14 + * Development and Distribution License("CDDL") (collectively, the
183.15 + * "License"). You may not use this file except in compliance with the
183.16 + * License. You can obtain a copy of the License at
183.17 + * http://www.netbeans.org/cddl-gplv2.html
183.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
183.19 + * specific language governing permissions and limitations under the
183.20 + * License. When distributing the software, include this License Header
183.21 + * Notice in each file and include the License file at
183.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
183.23 + * particular file as subject to the "Classpath" exception as provided
183.24 + * by Oracle in the GPL Version 2 section of the License file that
183.25 + * accompanied this code. If applicable, add the following below the
183.26 + * License Header, with the fields enclosed by brackets [] replaced by
183.27 + * your own identifying information:
183.28 + * "Portions Copyrighted [year] [name of copyright owner]"
183.29 + *
183.30 + * If you wish your version of this file to be governed by only the CDDL
183.31 + * or only the GPL Version 2, indicate your decision by adding
183.32 + * "[Contributor] elects to include this software in this distribution
183.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
183.34 + * single choice of license, a recipient has the option to distribute
183.35 + * your version of this file under either the CDDL, the GPL Version 2 or
183.36 + * to extend the choice of license to its licensees as provided above.
183.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
183.38 + * Version 2 license, then the option applies only if the new code is
183.39 + * made subject to such option by the copyright holder.
183.40 + *
183.41 + * Contributor(s):
183.42 + *
183.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
183.44 + */
183.45 +package org.netbeans.modules.python.source.queries;
183.46 +
183.47 +import java.util.HashMap;
183.48 +import java.util.Map;
183.49 +
183.50 +/**
183.51 + *
183.52 + * @author Ralph Ruijs
183.53 + */
183.54 +public final class DeprecationQuery {
183.55 + private static final Map<String, String> DEPRECATED = new HashMap<>();
183.56 +
183.57 +
183.58 + static {
183.59 + for (String module : new String[]{"cl", "sv", "timing"}) {
183.60 + DEPRECATED.put(module, "Listed as obsolete in the library documentation");
183.61 + }
183.62 +
183.63 + for (String module : new String[]{
183.64 + "addpack", "cmp", "cmpcache", "codehack", "dircmp", "dump", "find", "fmt",
183.65 + "grep", "lockfile", "newdir", "ni", "packmail", "Para", "poly",
183.66 + "rand", "reconvert", "regex", "regsub", "statcache", "tb", "tzparse",
183.67 + "util", "whatsound", "whrandom", "zmod"}) {
183.68 + DEPRECATED.put(module, "Obsolete module, removed in Python 2.5");
183.69 +
183.70 + }
183.71 +
183.72 + for (String module : new String[]{"gopherlib", "rgbimg", "macfs"}) {
183.73 + DEPRECATED.put(module, "Obsolete module, removed in Python 2.6");
183.74 + }
183.75 +
183.76 + /*
183.77 + al.rst: The :mod:`al` module has been deprecated for removal in Python 3.0.
183.78 + al.rst: The :mod:`AL` module has been deprecated for removal in Python 3.0.
183.79 + bsddb.rst: The :mod:`bsddb` module has been deprecated for removal in Python 3.0.
183.80 + cd.rst: The :mod:`cd` module has been deprecated for removal in Python 3.0.
183.81 + dbhash.rst: The :mod:`dbhash` module has been deprecated for removal in Python 3.0.
183.82 + fl.rst: The :mod:`fl` module has been deprecated for removal in Python 3.0.
183.83 + fl.rst: The :mod:`FL` module has been deprecated for removal in Python 3.0.
183.84 + fl.rst: The :mod:`flp` module has been deprecated for removal in Python 3.0.
183.85 + fm.rst: The :mod:`fm` module has been deprecated for removal in Python 3.0.
183.86 + gl.rst: The :mod:`gl` module has been deprecated for removal in Python 3.0.
183.87 + gl.rst: The :mod:`DEVICE` module has been deprecated for removal in Python 3.0.
183.88 + gl.rst: The :mod:`GL` module has been deprecated for removal in Python 3.0.
183.89 + imgfile.rst: The :mod:`imgfile` module has been deprecated for removal in Python 3.0.
183.90 + jpeg.rst: The :mod:`jpeg` module has been deprecated for removal in Python 3.0.
183.91 + statvfs.rst: The :mod:`statvfs` module has been deprecated for removal in Python 3.0.
183.92 + sunaudio.rst: The :mod:`sunaudiodev` module has been deprecated for removal in Python 3.0.
183.93 + sunaudio.rst: The :mod:`SUNAUDIODEV` module has been deprecated for removal in Python 3.0.
183.94 + tarfile.rst: The :class:`TarFileCompat` class has been deprecated for removal in Python 3.0.
183.95 + */
183.96 +
183.97 + DEPRECATED.put("posixfile",
183.98 + "Locking is better done by fcntl.lockf().");
183.99 +
183.100 + DEPRECATED.put("gopherlib",
183.101 + "The gopher protocol is not in active use anymore.");
183.102 +
183.103 + DEPRECATED.put("rgbimgmodule",
183.104 + "");
183.105 +
183.106 + DEPRECATED.put("pre",
183.107 + "The underlying PCRE engine doesn't support Unicode, and has been unmaintained since Python 1.5.2.");
183.108 +
183.109 + DEPRECATED.put("whrandom",
183.110 + "The module's default seed computation was inherently insecure; the random module should be used instead.");
183.111 +
183.112 + DEPRECATED.put("rfc822",
183.113 + "Supplanted by Python 2.2's email package.");
183.114 +
183.115 + DEPRECATED.put("mimetools",
183.116 + "Supplanted by Python 2.2's email package.");
183.117 +
183.118 + DEPRECATED.put("MimeWriter",
183.119 + "Supplanted by Python 2.2's email package.");
183.120 +
183.121 + DEPRECATED.put("mimify",
183.122 + "Supplanted by Python 2.2's email package.");
183.123 +
183.124 + DEPRECATED.put("rotor",
183.125 + "Uses insecure algorithm.");
183.126 +
183.127 + DEPRECATED.put("TERMIOS.py",
183.128 + "The constants in this file are now in the 'termios' module.");
183.129 +
183.130 + DEPRECATED.put("statcache",
183.131 + "Using the cache can be fragile and error-prone; applications should just use os.stat() directly.");
183.132 +
183.133 + DEPRECATED.put("mpz",
183.134 + "Third-party packages provide similiar features and wrap more of GMP's API.");
183.135 +
183.136 +
183.137 + DEPRECATED.put("xreadlines",
183.138 + "Using 'for line in file', introduced in 2.3, is preferable.");
183.139 +
183.140 + DEPRECATED.put("multifile",
183.141 + "Supplanted by the email package.");
183.142 +
183.143 + DEPRECATED.put("sets",
183.144 + "The built-in set/frozenset types, introduced in Python 2.4, supplant the module.");
183.145 +
183.146 + DEPRECATED.put("buildtools",
183.147 + "");
183.148 +
183.149 + DEPRECATED.put("cfmfile",
183.150 + "");
183.151 +
183.152 + DEPRECATED.put("macfs",
183.153 + "");
183.154 +
183.155 + DEPRECATED.put("md5",
183.156 + "Replaced by the 'hashlib' module.");
183.157 +
183.158 + DEPRECATED.put("sha",
183.159 + "Replaced by the 'hashlib' module.");
183.160 + }
183.161 +
183.162 + public static boolean isDeprecatedModule(String module) {
183.163 + return DEPRECATED.containsKey(module);
183.164 + }
183.165 +
183.166 + public static String getDeprecatedModuleDescription(String module) {
183.167 + return DEPRECATED.get(module);
183.168 + }
183.169 +
183.170 + private DeprecationQuery() {
183.171 + }
183.172 +}
184.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
184.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ArgListCompiler.java Mon Sep 21 13:01:16 2015 +0200
184.3 @@ -0,0 +1,121 @@
184.4 +// Copyright (c) Corporation for National Research Initiatives
184.5 +package org.netbeans.modules.python.source.scopes;
184.6 +
184.7 +import java.util.ArrayList;
184.8 +
184.9 +import java.util.List;
184.10 +import org.python.antlr.PythonTree;
184.11 +import org.python.antlr.Visitor;
184.12 +import org.python.antlr.ast.Assign;
184.13 +import org.python.antlr.ast.Name;
184.14 +import org.python.antlr.ast.Suite;
184.15 +import org.python.antlr.ast.Tuple;
184.16 +import org.python.antlr.ast.arguments;
184.17 +import org.python.antlr.ast.expr_contextType;
184.18 +import org.python.antlr.base.expr;
184.19 +import org.python.antlr.base.stmt;
184.20 +
184.21 +/** Based on org.python.compiler.ArgListCompiler */
184.22 +public class ArgListCompiler extends Visitor {
184.23 + public boolean arglist, keywordlist;
184.24 + public List<expr> defaults;
184.25 + public List<String> names;
184.26 + public ArrayList<PythonTree> nodes;
184.27 + public List<String> fpnames;
184.28 + public List<stmt> init_code;
184.29 + private SymbolTable symbolTable;
184.30 +
184.31 + public ArgListCompiler(SymbolTable symbolTable) {
184.32 + this.symbolTable = symbolTable;
184.33 + arglist = keywordlist = false;
184.34 + defaults = null;
184.35 + names = new ArrayList<>();
184.36 + nodes = new ArrayList<>();
184.37 + fpnames = new ArrayList<>();
184.38 + init_code = new ArrayList<>();
184.39 + }
184.40 +
184.41 + public void reset() {
184.42 + arglist = keywordlist = false;
184.43 + defaults = null;
184.44 + names.clear();
184.45 + nodes.clear();
184.46 + init_code.clear();
184.47 + }
184.48 +
184.49 + public void appendInitCode(Suite node) {
184.50 + node.getInternalBody().addAll(0, init_code);
184.51 + }
184.52 +
184.53 + public List<expr> getDefaults() {
184.54 + return defaults;
184.55 + }
184.56 +
184.57 + public void visitArgs(arguments args) throws Exception {
184.58 + for (int i = 0; i < args.getInternalArgs().size(); i++) {
184.59 + expr node = args.getInternalArgs().get(i);
184.60 + String name = (String)visit(node);
184.61 + names.add(name);
184.62 + nodes.add(node);
184.63 + if (node instanceof Tuple) {
184.64 + List<expr> targets = new ArrayList<>();
184.65 + targets.add(node);
184.66 + Assign ass = new Assign(node,
184.67 + targets,
184.68 + new Name(node, name, expr_contextType.Load));
184.69 + init_code.add(ass);
184.70 + }
184.71 + }
184.72 + if (args.getInternalVararg() != null) {
184.73 + arglist = true;
184.74 + names.add(args.getInternalVararg());
184.75 + //nodes.add(null); // no corresponding node?
184.76 + nodes.add(args); // just use the corresponding args node instead
184.77 + }
184.78 + if (args.getInternalKwarg() != null) {
184.79 + keywordlist = true;
184.80 + names.add(args.getInternalKwarg());
184.81 + //nodes.add(null); // no corresponding node?
184.82 + nodes.add(args); // just use the corresponding args node instead
184.83 + }
184.84 +
184.85 + defaults = args.getInternalDefaults();
184.86 + for (int i = 0; i < defaults.size(); i++) {
184.87 + if (defaults.get(i) == null) {
184.88 + symbolTable.error("non-default argument follows default argument", true,
184.89 + args.getInternalArgs().get(args.getInternalArgs().size() - defaults.size() + i));
184.90 + }
184.91 + }
184.92 + }
184.93 +
184.94 + @Override
184.95 + public Object visitName(Name node) throws Exception {
184.96 + //FIXME: do we need Store and Param, or just Param?
184.97 + if (node.getInternalCtx() != expr_contextType.Store && node.getInternalCtx() != expr_contextType.Param) {
184.98 + return null;
184.99 + }
184.100 +
184.101 + if (fpnames.contains(node.getInternalId())) {
184.102 + symbolTable.error("duplicate argument name found: " +
184.103 + node.getInternalId(), true, node);
184.104 + }
184.105 + fpnames.add(node.getInternalId());
184.106 + return node.getInternalId();
184.107 + }
184.108 +
184.109 + @Override
184.110 + public Object visitTuple(Tuple node) throws Exception {
184.111 + StringBuffer name = new StringBuffer("(");
184.112 + List<expr> elts = node.getInternalElts();
184.113 + if (elts != null) {
184.114 + int n = elts.size();
184.115 + for (int i = 0; i < n - 1; i++) {
184.116 + name.append(visit(elts.get(i)));
184.117 + name.append(", ");
184.118 + }
184.119 + name.append(visit(elts.get(n - 1)));
184.120 + }
184.121 + name.append(")");
184.122 + return name.toString();
184.123 + }
184.124 +}
185.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
185.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ScopeConstants.java Mon Sep 21 13:01:16 2015 +0200
185.3 @@ -0,0 +1,28 @@
185.4 +package org.netbeans.modules.python.source.scopes;
185.5 +
185.6 +/** Based on org.python.compiler.ScopeConstants in Jython */
185.7 +public interface ScopeConstants {
185.8 + public final static int BOUND = 1 << 0;
185.9 + public final static int NGLOBAL = 1 << 1; // func scope expl global
185.10 + public final static int PARAM = 1 << 2;
185.11 + public final static int FROM_PARAM = 1 << 3;
185.12 + public final static int CELL = 1 << 4;
185.13 + public final static int FREE = 1 << 5;
185.14 + public final static int CLASS_GLOBAL = 1 << 6; // class scope expl global
185.15 + public final static int READ = 1 << 7;
185.16 + public final static int CALLED = 1 << 8;
185.17 + public final static int DEF = 1 << 9;
185.18 + public final static int IMPORTED = 1 << 10;
185.19 + public final static int CLASS = 1 << 11;
185.20 + public final static int FUNCTION = 1 << 12;
185.21 + public final static int MEMBER = 1 << 13;
185.22 + public final static int GENERATOR = 1 << 13; // it's a generator expression
185.23 + public final static int PRIVATE = 1 << 14;
185.24 + public final static int ALIAS = 1 << 15;
185.25 + public final static int PROTECTED = 1 << 16;
185.26 + public final static int BOUND_IN_CONSTRUCTOR = 1 << 17;
185.27 + public final static int GLOBAL = NGLOBAL | CLASS_GLOBAL; // all global
185.28 + public final static int TOPSCOPE = 0;
185.29 + public final static int FUNCSCOPE = 1;
185.30 + public final static int CLASSSCOPE = 2;
185.31 +}
186.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
186.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ScopeInfo.java Mon Sep 21 13:01:16 2015 +0200
186.3 @@ -0,0 +1,576 @@
186.4 +// (C) Copyright 2001 Samuele Pedroni
186.5 +package org.netbeans.modules.python.source.scopes;
186.6 +
186.7 +import java.util.ArrayList;
186.8 +import java.util.Collections;
186.9 +import java.util.HashMap;
186.10 +import java.util.LinkedHashMap;
186.11 +import java.util.Map;
186.12 +import java.util.List;
186.13 +
186.14 +import org.netbeans.modules.python.source.AstPath;
186.15 +import org.netbeans.modules.python.source.PythonAstUtils;
186.16 +import org.python.antlr.ParseException;
186.17 +import org.python.antlr.PythonTree;
186.18 +import org.python.antlr.ast.Assign;
186.19 +import org.python.antlr.ast.Attribute;
186.20 +import org.python.antlr.ast.ClassDef;
186.21 +import org.python.antlr.ast.Name;
186.22 +import org.python.antlr.ast.Return;
186.23 +import org.python.antlr.ast.Tuple;
186.24 +import org.python.antlr.base.expr;
186.25 +import static org.netbeans.modules.python.source.scopes.ScopeConstants.*;
186.26 +import org.netbeans.modules.python.source.NameStyle;
186.27 +
186.28 +/**
186.29 + * Based on org.python.compiler.ScopeInfo in Jython
186.30 + *
186.31 + * See {@link ScopesCompiler} for details on my modifications
186.32 + */
186.33 +@SuppressWarnings("unchecked")
186.34 +public class ScopeInfo extends Object {
186.35 + public PythonTree scope_node;
186.36 + public String scope_name;
186.37 + public int level;
186.38 + public int func_level;
186.39 + public boolean hidden;
186.40 +
186.41 + public String dump() {
186.42 + StringBuilder sb = new StringBuilder();
186.43 +
186.44 + for (int i = 0; i < level; i++) {
186.45 + sb.append(" ");
186.46 + }
186.47 + sb.append("=============================================\n");
186.48 + for (int i = 0; i < level; i++) {
186.49 + sb.append(" ");
186.50 + }
186.51 + sb.append(((kind != CLASSSCOPE) ? scope_name : "class " +
186.52 + scope_name) + ": " + scope_node + " : " + PythonAstUtils.getRange(scope_node) + "\n");
186.53 + //for(int i=0; i<level; i++) sb.append(" ");
186.54 + //sb.append("UP=" + up);
186.55 + //sb.append(" NESTED=" + nested);
186.56 + //sb.append("\n");
186.57 +
186.58 +
186.59 + // Sort to make test output stable
186.60 + List<String> keys = new ArrayList<>(tbl.keySet());
186.61 + Collections.sort(keys);
186.62 + for (String name : keys) {
186.63 + SymInfo info = tbl.get(name);
186.64 + for (int i = 0; i < level; i++) {
186.65 + sb.append(" ");
186.66 + }
186.67 + sb.append(name);
186.68 + sb.append(" ");
186.69 + sb.append(info.dumpFlags(this));
186.70 + sb.append("\n");
186.71 + }
186.72 +
186.73 + if (inner_free.size() > 0 || cellvars.size() > 0 || jy_paramcells.size() > 0 ||
186.74 + jy_npurecell != 0 /*|| cell != 0 || distance != 0 || up != null*/) {
186.75 + for (int i = 0; i < level; i++) {
186.76 + sb.append(" ");
186.77 + }
186.78 + sb.append("---------------------------------------------\n");
186.79 + }
186.80 +
186.81 + if (inner_free.size() > 0) {
186.82 + List<String> sorted = new ArrayList<>();
186.83 + for (String s : inner_free.keySet()) {
186.84 + sorted.add(s + "=" + inner_free.get(s));
186.85 + }
186.86 + Collections.sort(sorted);
186.87 +
186.88 + for (int i = 0; i < level; i++) {
186.89 + sb.append(" ");
186.90 + }
186.91 + sb.append("inner_free: {"); // NOI18N
186.92 + boolean first = true;
186.93 + for (String s : sorted) {
186.94 + if (first) {
186.95 + first = false;
186.96 + } else {
186.97 + sb.append(", "); // NOI18N
186.98 + }
186.99 + sb.append(s);
186.100 + }
186.101 + sb.append("}\n"); // NOI18N
186.102 + }
186.103 + if (cellvars.size() > 0) {
186.104 + Collections.sort(cellvars);
186.105 + for (int i = 0; i < level; i++) {
186.106 + sb.append(" ");
186.107 + }
186.108 + sb.append("cellvars: " + cellvars.toString() + "\n"); // TODO - sort
186.109 + }
186.110 + if (jy_paramcells.size() > 0) {
186.111 + Collections.sort(jy_paramcells);
186.112 + for (int i = 0; i < level; i++) {
186.113 + sb.append(" ");
186.114 + }
186.115 + sb.append("jy_paramcells: " + jy_paramcells.toString() + "\n"); // TODO - sort
186.116 + }
186.117 + if (jy_npurecell != 0) {
186.118 + for (int i = 0; i < level; i++) {
186.119 + sb.append(" ");
186.120 + }
186.121 + sb.append("jy_npurecell: " + jy_npurecell + "\n"); // TODO - sort
186.122 + }
186.123 + //if (cell != 0) {
186.124 + // for(int i=0; i<level; i++) sb.append(" ");
186.125 + // sb.append("cell: " + cell + "\n"); // TODO - sort
186.126 + //}
186.127 + //if (distance != 0) {
186.128 + // for(int i=0; i<level; i++) sb.append(" ");
186.129 + // sb.append("distance: " + distance + "\n"); // TODO - sort
186.130 + //}
186.131 + //if (up != null) {
186.132 + // for(int i=0; i<level; i++) sb.append(" ");
186.133 + // sb.append("up: " + up.scope_node);
186.134 + //}
186.135 +
186.136 + if (attributes.size() > 0) {
186.137 + for (int i = 0; i < level; i++) {
186.138 + sb.append(" ");
186.139 + }
186.140 + sb.append("------ Attributes ---------------------------------------\n"); // NOI18N
186.141 + // Sort
186.142 + List<String> attributeNames = new ArrayList<>(attributes.keySet());
186.143 + Collections.sort(attributeNames);
186.144 + for (String attributeName : attributeNames) {
186.145 + for (int i = 0; i < level; i++) {
186.146 + sb.append(" ");
186.147 + }
186.148 + sb.append(attributeName);
186.149 + sb.append(" : "); // NOI18N
186.150 + sb.append(attributes.get(attributeName));
186.151 + sb.append("\n"); // NOI18N
186.152 + }
186.153 + }
186.154 +
186.155 + return sb.toString();
186.156 + }
186.157 +
186.158 + public ScopeInfo(String name, PythonTree node, int level, int kind,
186.159 + int func_level, ArgListCompiler ac) {
186.160 + scope_name = name;
186.161 + scope_node = node;
186.162 + this.level = level;
186.163 + this.kind = kind;
186.164 + this.func_level = func_level;
186.165 + this.ac = ac;
186.166 + }
186.167 + public int kind;
186.168 + public boolean unqual_exec;
186.169 + public boolean exec;
186.170 + public boolean from_import_star;
186.171 + public boolean contains_ns_free_vars;
186.172 + public boolean generator;
186.173 + private boolean hasReturnWithValue;
186.174 + public int yield_count;
186.175 + public int max_with_count;
186.176 + public ArgListCompiler ac;
186.177 + public Map<String, SymInfo> tbl = new LinkedHashMap<>();
186.178 +
186.179 + // define a separate dictionary for dynamic bounded variables
186.180 + public Map<String, SymInfo> attributes = new HashMap<>();
186.181 + public List<String> names = new ArrayList<>();
186.182 +
186.183 + private void addAttributeEntry(String name, PythonTree node, int flags) {
186.184 + SymInfo info = attributes.get(name);
186.185 + if (info == null) {
186.186 + SymInfo entry = new SymInfo(flags);
186.187 + if (NameStyle.isPrivateName(name)) {
186.188 + entry.flags |= PRIVATE;
186.189 + } else if (NameStyle.isProtectedName(name)) {
186.190 + entry.flags |= PROTECTED;
186.191 + }
186.192 + entry.node = node;
186.193 + attributes.put(name, entry);
186.194 + }
186.195 + }
186.196 +
186.197 + private void addToClassScope(String name, PythonTree node, boolean inConstructor) {
186.198 + int flags = CLASSSCOPE | BOUND | MEMBER;
186.199 + if (inConstructor) {
186.200 + flags |= BOUND_IN_CONSTRUCTOR;
186.201 + }
186.202 + addAttributeEntry(name, node, flags);
186.203 + }
186.204 +
186.205 + public ScopeInfo getClassScope() {
186.206 + ScopeInfo cur = this;
186.207 + while ((cur != null) &&
186.208 + (!(cur.scope_node instanceof ClassDef))) {
186.209 + cur = cur.nested;
186.210 + }
186.211 + return cur;
186.212 + }
186.213 +
186.214 + private boolean belongsToExprList(List<expr> types, expr cur) {
186.215 + return types != null && types.contains(cur);
186.216 + }
186.217 +
186.218 + boolean isAttributeAssigment(AstPath path, Attribute attr) {
186.219 + PythonTree leaf = path.leaf();
186.220 + Assign assign = null;
186.221 + expr target = attr; // default to single
186.222 + if (leaf instanceof Assign) {
186.223 + assign = (Assign)leaf;
186.224 + } else if (leaf instanceof Tuple) {
186.225 + // check for tuple assignment
186.226 + Tuple tuple = (Tuple)leaf;
186.227 + PythonTree tupleParent = path.leafParent();
186.228 + if (belongsToExprList(tuple.getInternalElts(), attr)) {
186.229 + if (tupleParent instanceof Assign) {
186.230 + assign = (Assign)tupleParent;
186.231 + target = tuple; // tuple assignment target
186.232 + }
186.233 + }
186.234 + }
186.235 + // check if we got assignment
186.236 + if (assign == null) {
186.237 + return false;
186.238 + }
186.239 + if (belongsToExprList(assign.getInternalTargets(), target)) {
186.240 + return true;
186.241 + }
186.242 + return false;
186.243 + }
186.244 +
186.245 + public void addAttribute(AstPath path, String name, PythonTree node) {
186.246 + // deeply check assignment context for attribute.
186.247 + Attribute curAttr = (Attribute)node;
186.248 +
186.249 + if (curAttr.getInternalValue() instanceof Attribute) {
186.250 + // recursice attributes( x.y.z.w ) to be handled later
186.251 + } else if (curAttr.getInternalValue() instanceof Name) {
186.252 +
186.253 + Name parentName = (Name)curAttr.getInternalValue();
186.254 +
186.255 + ScopeInfo classScope = getClassScope();
186.256 + boolean inConstructor = false;
186.257 + String parName = parentName.getInternalId();
186.258 +
186.259 + // for simplicity handle only at classScope in current source
186.260 + if (classScope != null) {
186.261 + // check for self or inherited parent name prefix
186.262 + if ((parName.equals("self")) ||
186.263 + (PythonAstUtils.getParentClassFromNode(path, classScope.scope_node, parName) != null)) {
186.264 + if (!(parName.equals("self"))) {
186.265 + // check classname not overridden by local scope variable
186.266 + if (tbl.get(parName) != null) {
186.267 + return;
186.268 + }
186.269 + }
186.270 + if (scope_name.equals("__init__") || scope_name.equals("__new__")) {
186.271 + inConstructor = true; // set in constructor
186.272 + }
186.273 + //
186.274 + // put in class scope
186.275 + if (isAttributeAssigment(path, curAttr)) {
186.276 + classScope.addToClassScope(name, node, inConstructor);
186.277 + } else {
186.278 + // store at current scope if parName is not overriding
186.279 + // classname at current scope
186.280 + int flags = CLASSSCOPE | READ;
186.281 + addAttributeEntry(name, node, flags);
186.282 + }
186.283 + }
186.284 + }
186.285 + }
186.286 + }
186.287 +
186.288 + public int addGlobal(String name, PythonTree node) {
186.289 + // global kind = func vs. class
186.290 + int global = kind == CLASSSCOPE ? CLASS_GLOBAL : NGLOBAL;
186.291 + SymInfo info = tbl.get(name);
186.292 + if (info == null) {
186.293 + SymInfo entry = new SymInfo(global | BOUND);
186.294 + if (NameStyle.isPrivateName(name)) {
186.295 + entry.flags |= PRIVATE;
186.296 + } else if (NameStyle.isProtectedName(name)) {
186.297 + entry.flags |= PROTECTED;
186.298 + }
186.299 + entry.node = node;
186.300 + tbl.put(name, entry);
186.301 + return -1;
186.302 + }
186.303 + int prev = info.flags;
186.304 + info.flags |= global | BOUND;
186.305 + return prev;
186.306 + }
186.307 + public int local = 0;
186.308 +
186.309 + public void addParam(String name, PythonTree node) {
186.310 + SymInfo entry = new SymInfo(PARAM | BOUND, local++);
186.311 + entry.node = node;
186.312 + tbl.put(name, entry);
186.313 + names.add(name);
186.314 + }
186.315 +
186.316 + // <netbeans>
186.317 + public boolean isUnused(String name) {
186.318 + SymInfo info = tbl.get(name);
186.319 + if (info != null) {
186.320 + return info.isUnused(this);
186.321 + }
186.322 + return false;
186.323 + }
186.324 +
186.325 + public boolean isParameter(String name) {
186.326 + SymInfo info = tbl.get(name);
186.327 + if (info != null) {
186.328 + return info.isParameter();
186.329 + }
186.330 + return false;
186.331 + }
186.332 + // </netbeans>
186.333 +
186.334 + public void markFromParam() {
186.335 + for (SymInfo info : tbl.values()) {
186.336 + info.flags |= FROM_PARAM;
186.337 + }
186.338 + }
186.339 +
186.340 + public SymInfo addBound(String name, PythonTree node) {
186.341 + SymInfo info = tbl.get(name);
186.342 + if (info == null) {
186.343 + info = new SymInfo(BOUND);
186.344 + if (NameStyle.isPrivateName(name)) {
186.345 + info.flags |= PRIVATE;
186.346 + } else if (NameStyle.isProtectedName(name)) {
186.347 + info.flags |= PROTECTED;
186.348 + }
186.349 + tbl.put(name, info);
186.350 + info.node = node;
186.351 + return info;
186.352 + }
186.353 + info.flags |= BOUND;
186.354 +
186.355 + return info;
186.356 + }
186.357 +
186.358 + public SymInfo addUsed(String name, PythonTree node) {
186.359 + SymInfo info = tbl.get(name);
186.360 + if (info == null) {
186.361 + // <netbeans>
186.362 + info = new SymInfo(0);
186.363 + tbl.put(name, info);
186.364 + info.node = node;
186.365 + }
186.366 + info.flags |= READ;
186.367 +
186.368 + return info;
186.369 + // </netbeans>
186.370 + }
186.371 +
186.372 +
186.373 + // <netbeans>
186.374 + void markCall(String name) {
186.375 + SymInfo entry = tbl.get(name);
186.376 + if (entry != null) {
186.377 + entry.flags |= CALLED;
186.378 + }
186.379 + }
186.380 + // </netbeans>
186.381 + private final static String PRESENT = new String("PRESENT");
186.382 + public HashMap<String, String> inner_free = new HashMap<>();
186.383 + public List<String> cellvars = new ArrayList<>();
186.384 + public List<String> jy_paramcells = new ArrayList<>();
186.385 + public int jy_npurecell;
186.386 + public int cell, distance;
186.387 + public ScopeInfo up;
186.388 + public ScopeInfo nested;
186.389 +
186.390 + //Resolve the names used in the given scope, and mark any freevars used in the up scope
186.391 + public void cook(ScopeInfo up, int distance, SymbolTable ctxt) throws Exception {
186.392 + if (up == null) {
186.393 + return; // top level => nop
186.394 + }
186.395 + this.up = up;
186.396 + this.distance = distance;
186.397 + boolean func = kind == FUNCSCOPE;
186.398 + List<String> purecells = new ArrayList<>();
186.399 + cell = 0;
186.400 + boolean some_inner_free = inner_free.size() > 0;
186.401 +
186.402 + for (String name : inner_free.keySet()) {
186.403 +
186.404 + SymInfo info = tbl.get(name);
186.405 + if (info == null) {
186.406 + tbl.put(name, new SymInfo(FREE));
186.407 + continue;
186.408 + }
186.409 + int flags = info.flags;
186.410 + if (func) {
186.411 + // not func global and bound ?
186.412 + if ((flags & NGLOBAL) == 0 && (flags & BOUND) != 0) {
186.413 + info.flags |= CELL;
186.414 + if ((info.flags & PARAM) != 0) {
186.415 + jy_paramcells.add(name);
186.416 + }
186.417 + cellvars.add(name);
186.418 + info.env_index = cell++;
186.419 + if ((flags & PARAM) == 0) {
186.420 + purecells.add(name);
186.421 + }
186.422 + continue;
186.423 + }
186.424 + } else {
186.425 + info.flags |= FREE;
186.426 + }
186.427 + }
186.428 + boolean some_free = false;
186.429 +
186.430 + boolean nested = up.kind != TOPSCOPE;
186.431 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
186.432 + String name = entry.getKey();
186.433 + SymInfo info = entry.getValue();
186.434 + int flags = info.flags;
186.435 + if (nested && (flags & FREE) != 0) {
186.436 + up.inner_free.put(name, PRESENT);
186.437 + }
186.438 + if ((flags & (GLOBAL | PARAM | CELL)) == 0) {
186.439 + if ((flags & BOUND) != 0) { // ?? only func
186.440 + // System.err.println("local: "+name);
186.441 + names.add(name);
186.442 + info.locals_index = local++;
186.443 + continue;
186.444 + }
186.445 + info.flags |= FREE;
186.446 + some_free = true;
186.447 + if (nested) {
186.448 + up.inner_free.put(name, PRESENT);
186.449 + }
186.450 + }
186.451 +
186.452 + // <netbeans>
186.453 + if ((info.flags & FREE) != 0) {
186.454 + // Mark definition symbol as read as well
186.455 + ScopeInfo curr = up;
186.456 + while (curr != null) {
186.457 + SymInfo s = curr.tbl.get(name);
186.458 + if (s != null && ((s.flags & BOUND) != 0)) {
186.459 + s.flags |= READ;
186.460 + s.flags |= (info.flags & (CALLED));
186.461 + break;
186.462 + }
186.463 + curr = curr.up;
186.464 + while (curr != null && curr.kind == CLASSSCOPE) {
186.465 + curr = curr.up;
186.466 + }
186.467 + }
186.468 + }
186.469 +
186.470 + // </netbeans>
186.471 + }
186.472 + if ((jy_npurecell = purecells.size()) > 0) {
186.473 + int sz = purecells.size();
186.474 + for (int i = 0; i < sz; i++) {
186.475 + names.add(purecells.get(i));
186.476 + }
186.477 + }
186.478 +
186.479 + if (some_free && nested) {
186.480 + up.contains_ns_free_vars = true;
186.481 + }
186.482 + // XXX - this doesn't catch all cases - may depend subtly
186.483 + // on how visiting NOW works with antlr compared to javacc
186.484 + if ((unqual_exec || from_import_star)) {
186.485 + if (some_inner_free) {
186.486 + dynastuff_trouble(true, ctxt);
186.487 + } else if (func_level > 1 && some_free) {
186.488 + dynastuff_trouble(false, ctxt);
186.489 + }
186.490 + }
186.491 +
186.492 + }
186.493 +
186.494 + private void dynastuff_trouble(boolean inner_free,
186.495 + SymbolTable ctxt) throws Exception {
186.496 + String illegal;
186.497 + if (unqual_exec && from_import_star) {
186.498 + illegal = "function '" + scope_name +
186.499 + "' uses import * and bare exec, which are illegal";
186.500 + } else if (unqual_exec) {
186.501 + illegal = "unqualified exec is not allowed in function '" +
186.502 + scope_name + "'";
186.503 + } else {
186.504 + illegal = "import * is not allowed in function '" + scope_name + "'";
186.505 + }
186.506 + String why;
186.507 + if (inner_free) {
186.508 + why = " because it contains a function with free variables";
186.509 + } else {
186.510 + why = " because it contains free variables";
186.511 + }
186.512 + ctxt.error(illegal + why, true, scope_node);
186.513 + }
186.514 + public List<String> freevars = new ArrayList<>();
186.515 +
186.516 + /**
186.517 + * setup the closure on this scope using the scope passed into cook as up as
186.518 + * the containing scope
186.519 + */
186.520 + public void setup_closure() {
186.521 + setup_closure(up);
186.522 + }
186.523 +
186.524 + /**
186.525 + * setup the closure on this scope using the passed in scope. This is used
186.526 + * by jythonc to setup its closures.
186.527 + */
186.528 + public void setup_closure(ScopeInfo up) {
186.529 + int free = cell; // env = cell...,free...
186.530 + Map<String, SymInfo> up_tbl = up.tbl;
186.531 + boolean nested = up.kind != TOPSCOPE;
186.532 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
186.533 + String name = entry.getKey();
186.534 + SymInfo info = entry.getValue();
186.535 + int flags = info.flags;
186.536 + if ((flags & FREE) != 0) {
186.537 + SymInfo up_info = up_tbl.get(name);
186.538 + // ?? differs from CPython -- what is the intended behaviour?
186.539 + if (up_info != null) {
186.540 + int up_flags = up_info.flags;
186.541 + if ((up_flags & (CELL | FREE)) != 0) {
186.542 + info.env_index = free++;
186.543 + freevars.add(name);
186.544 + continue;
186.545 + }
186.546 + // ! func global affect nested scopes
186.547 + if (nested && (up_flags & NGLOBAL) != 0) {
186.548 + info.flags = NGLOBAL | BOUND;
186.549 + continue;
186.550 + }
186.551 + }
186.552 + info.flags &= ~FREE;
186.553 + }
186.554 + }
186.555 +
186.556 + }
186.557 +
186.558 + @Override
186.559 + public String toString() {
186.560 + return "ScopeInfo[" + scope_name + " " + kind + "]@" +
186.561 + System.identityHashCode(this);
186.562 + }
186.563 +
186.564 + public void defineAsGenerator(expr node) {
186.565 + generator = true;
186.566 + if (hasReturnWithValue) {
186.567 + throw new ParseException("'return' with argument " +
186.568 + "inside generator", node);
186.569 + }
186.570 + }
186.571 +
186.572 + public void noteReturnValue(Return node) {
186.573 + if (generator) {
186.574 + throw new ParseException("'return' with argument " +
186.575 + "inside generator", node);
186.576 + }
186.577 + hasReturnWithValue = true;
186.578 + }
186.579 +}
187.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
187.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ScopesCompiler.java Mon Sep 21 13:01:16 2015 +0200
187.3 @@ -0,0 +1,641 @@
187.4 +// (C) Copyright 2001 Samuele Pedroni
187.5 +package org.netbeans.modules.python.source.scopes;
187.6 +
187.7 +import java.util.ArrayList;
187.8 +import java.util.List;
187.9 +import java.util.Map;
187.10 +import java.util.Set;
187.11 +import java.util.Stack;
187.12 +import org.netbeans.modules.python.source.AstPath;
187.13 +import org.openide.util.Exceptions;
187.14 +import org.python.antlr.PythonTree;
187.15 +import org.python.antlr.Visitor;
187.16 +import org.python.antlr.ast.Assign;
187.17 +import org.python.antlr.ast.Attribute;
187.18 +import org.python.antlr.ast.Call;
187.19 +import org.python.antlr.ast.ClassDef;
187.20 +import org.python.antlr.ast.Delete;
187.21 +import org.python.antlr.ast.Exec;
187.22 +import org.python.antlr.ast.Expression;
187.23 +import org.python.antlr.ast.FunctionDef;
187.24 +import org.python.antlr.ast.GeneratorExp;
187.25 +import org.python.antlr.ast.Global;
187.26 +import org.python.antlr.ast.Import;
187.27 +import org.python.antlr.ast.ImportFrom;
187.28 +import org.python.antlr.ast.Interactive;
187.29 +import org.python.antlr.ast.Lambda;
187.30 +import org.python.antlr.ast.ListComp;
187.31 +import org.python.antlr.ast.Name;
187.32 +import org.python.antlr.ast.Return;
187.33 +import org.python.antlr.ast.Str;
187.34 +import org.python.antlr.ast.With;
187.35 +import org.python.antlr.ast.Yield;
187.36 +import org.python.antlr.ast.alias;
187.37 +import org.python.antlr.ast.arguments;
187.38 +import org.python.antlr.base.expr;
187.39 +import org.python.antlr.ast.expr_contextType;
187.40 +import org.python.antlr.base.stmt;
187.41 +
187.42 +/**
187.43 + * Based on org.python.compiler.ScopesCompiler in Jython
187.44 + *
187.45 + * Modifications I've made:
187.46 + * - Methods for finding all the free variables
187.47 + * - Methods for identifying unused bound variables
187.48 + * - Track whether symbols are referenced as calls or not
187.49 + * (so I can determine whether to look in the index for
187.50 + * functions or data etc. when trying to resolve imports)
187.51 + * - Track variable reads/writes
187.52 + * - Track imports etc.
187.53 + * - Add nodes to each SymInfo
187.54 + * - Replace old style Java (Hashtable, Vector, implements ScopeConstants) with
187.55 + * modern Java (HashMap, ArrayList, import static)
187.56 + *
187.57 + */
187.58 +@SuppressWarnings("unchecked")
187.59 +public class ScopesCompiler extends Visitor implements ScopeConstants {
187.60 + private SymbolTable symbolTable;
187.61 + private Stack scopes;
187.62 + private ScopeInfo cur = null;
187.63 + private Map<PythonTree, ScopeInfo> nodeScopes;
187.64 + private int level = 0;
187.65 + private int func_level = 0;
187.66 + private List<Import> imports;
187.67 + private List<PythonTree> mainImports;
187.68 + private List<ImportFrom> importsFrom;
187.69 + private Set<PythonTree> topLevelImports;
187.70 + private PythonTree root;
187.71 + private PythonTree parent;
187.72 + private AstPath path = new AstPath();
187.73 + /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
187.74 + private List<Str> publicSymbols;
187.75 + /** Set to true if we encountered manipulation on __all__ that I don't understand */
187.76 + private boolean invalidPublicSymbols;
187.77 +
187.78 + public ScopesCompiler(SymbolTable symbolTable, Map<PythonTree, ScopeInfo> nodeScopes, PythonTree root,
187.79 + List<Import> imports, List<ImportFrom> importsFrom, List<PythonTree> mainImports, Set<PythonTree> topLevelImports) {
187.80 + this.symbolTable = symbolTable;
187.81 + this.nodeScopes = nodeScopes;
187.82 + scopes = new Stack();
187.83 + this.root = root;
187.84 +
187.85 + this.imports = imports;
187.86 + this.importsFrom = importsFrom;
187.87 + this.mainImports = mainImports;
187.88 + this.topLevelImports = topLevelImports;
187.89 + }
187.90 +
187.91 + @Override
187.92 + public void traverse(PythonTree node) throws Exception {
187.93 + // Jython's parser often doesn't set the parent references correctly
187.94 + // so try to fix that here
187.95 + node.setParent(parent);
187.96 +
187.97 + PythonTree oldParent = parent;
187.98 + parent = node;
187.99 +
187.100 + path.descend(node);
187.101 + super.traverse(node);
187.102 + parent = oldParent;
187.103 + path.ascend();
187.104 + }
187.105 +
187.106 + public void beginScope(String name, int kind, PythonTree node,
187.107 + ArgListCompiler ac) {
187.108 + if (cur != null) {
187.109 + scopes.push(cur);
187.110 + }
187.111 + if (kind == FUNCSCOPE) {
187.112 + func_level++;
187.113 + }
187.114 + cur = new ScopeInfo(name, node, level++, kind, func_level, ac);
187.115 + nodeScopes.put(node, cur);
187.116 + }
187.117 +
187.118 + public void endScope() throws Exception {
187.119 + if (cur.kind == FUNCSCOPE) {
187.120 + func_level--;
187.121 + }
187.122 + level--;
187.123 + ScopeInfo up = null;
187.124 + if (!scopes.empty()) {
187.125 + up = (ScopeInfo)scopes.pop();
187.126 + }
187.127 + //Go into the stack to find a non class containing scope to use making the closure
187.128 + //See PEP 227
187.129 + int dist = 1;
187.130 + ScopeInfo referenceable = up;
187.131 + for (int i = scopes.size() - 1; i >= 0 && referenceable.kind == CLASSSCOPE; i--, dist++) {
187.132 + referenceable = ((ScopeInfo)scopes.get(i));
187.133 + }
187.134 + cur.cook(referenceable, dist, symbolTable);
187.135 +// cur.dump(); // debug
187.136 + cur = up;
187.137 + }
187.138 +
187.139 + public void parse() {
187.140 + try {
187.141 + visit(root);
187.142 + } catch (Throwable t) {
187.143 + Exceptions.printStackTrace(t);
187.144 + //throw org.python.core.ParserFacade.fixParseError(null, t,
187.145 + // code_compiler.getFilename());
187.146 + }
187.147 + }
187.148 +
187.149 + @Override
187.150 + public Object visitInteractive(Interactive node) throws Exception {
187.151 + beginScope("<single-top>", TOPSCOPE, node, null);
187.152 + PythonTree oldParent = parent;
187.153 + parent = node;
187.154 + suite(node.getInternalBody());
187.155 + parent = oldParent;
187.156 + endScope();
187.157 + return null;
187.158 + }
187.159 +
187.160 + @Override
187.161 + public Object visitModule(org.python.antlr.ast.Module node)
187.162 + throws Exception {
187.163 + List<stmt> body = node.getInternalBody();
187.164 + if (body != null && body.size() > 0) {
187.165 + boolean foundFirst = false;
187.166 + for (stmt stmt : body) {
187.167 + if (stmt != null) {
187.168 + if (stmt instanceof Import || stmt instanceof ImportFrom) {
187.169 + if (!foundFirst) {
187.170 + foundFirst = true;
187.171 + }
187.172 + mainImports.add(stmt);
187.173 + } else if (foundFirst) {
187.174 + break;
187.175 + }
187.176 + }
187.177 + }
187.178 + }
187.179 +
187.180 + beginScope("<file-top>", TOPSCOPE, node, null);
187.181 +
187.182 + PythonTree oldParent = parent;
187.183 + parent = node;
187.184 + suite(node.getInternalBody());
187.185 + parent = oldParent;
187.186 +
187.187 + endScope();
187.188 + return null;
187.189 + }
187.190 +
187.191 + @Override
187.192 + public Object visitExpression(Expression node) throws Exception {
187.193 + beginScope("<eval-top>", TOPSCOPE, node, null);
187.194 + visit(new Return(node, node.getInternalBody()));
187.195 + endScope();
187.196 + return null;
187.197 + }
187.198 +
187.199 + private void def(String name, int extraFlags, PythonTree node) {
187.200 + SymInfo info = cur.addBound(name, node);
187.201 + // <netbeans>
187.202 + info.flags |= (DEF | extraFlags);
187.203 + info.node = node;
187.204 + // </netbeans>
187.205 + }
187.206 +
187.207 + @Override
187.208 + public Object visitAssign(Assign node) throws Exception {
187.209 + List<expr> targets = node.getInternalTargets();
187.210 + if (targets != null && targets.size() == 1 && targets.get(0) instanceof Name) {
187.211 + Name lhs = (Name)targets.get(0);
187.212 + if ("__all__".equals(lhs.getInternalId())) { // NOI18N
187.213 + expr nodeValue = node.getInternalValue();
187.214 + if (!invalidPublicSymbols && nodeValue instanceof org.python.antlr.ast.List) {
187.215 + org.python.antlr.ast.List allList = (org.python.antlr.ast.List)nodeValue;
187.216 + if (allList != null) {
187.217 + for (expr expr : allList.getInternalElts()) {
187.218 + if (expr instanceof Str) {
187.219 + Str str = (Str)expr;
187.220 + if (publicSymbols == null) {
187.221 + publicSymbols = new ArrayList<>();
187.222 + }
187.223 + publicSymbols.add(str);
187.224 + } else {
187.225 + invalidPublicSymbols = true;
187.226 + }
187.227 + }
187.228 + }
187.229 + } else {
187.230 + invalidPublicSymbols = true;
187.231 + }
187.232 + }
187.233 + }
187.234 +
187.235 + if (targets.size() > 0) {
187.236 + List<Name> names = new ArrayList<>(targets.size());
187.237 + boolean valid = true;
187.238 + for (expr et : targets) {
187.239 + if (et instanceof Name) {
187.240 + Name name = (Name)et;
187.241 + names.add(name);
187.242 + } else {
187.243 + valid = false;
187.244 + }
187.245 + }
187.246 + if (valid) {
187.247 + expr nodeValue = node.getInternalValue();
187.248 + if (nodeValue instanceof Name) {
187.249 + Name value = (Name)nodeValue;
187.250 +
187.251 + SymInfo rhsSym = cur.tbl.get(value.getInternalId());
187.252 + if (rhsSym != null && rhsSym.isDef()) {
187.253 + for (Name name : names) {
187.254 + visitName(name);
187.255 + SymInfo sym = cur.tbl.get(name.getInternalId());
187.256 + if (sym != null) {
187.257 + sym.flags |= ALIAS;
187.258 + sym.flags |= (rhsSym.flags & (CLASS | FUNCTION));
187.259 + sym.node = rhsSym.node;
187.260 + }
187.261 + }
187.262 + }
187.263 + }
187.264 + }
187.265 + }
187.266 +
187.267 + return super.visitAssign(node);
187.268 + }
187.269 +
187.270 + @Override
187.271 + public Object visitFunctionDef(FunctionDef node) throws Exception {
187.272 + def(node.getInternalName(), FUNCTION, node);
187.273 + ArgListCompiler ac = new ArgListCompiler(symbolTable);
187.274 + ac.visitArgs(node.getInternalArgs());
187.275 +
187.276 + List<expr> defaults = ac.getDefaults();
187.277 + for (int i = 0; i < defaults.size(); i++) {
187.278 + visit(defaults.get(i));
187.279 + }
187.280 +
187.281 + List<expr> decs = node.getInternalDecorator_list();
187.282 + for (int i = decs.size() - 1; i >= 0; i--) {
187.283 + visit(decs.get(i));
187.284 + }
187.285 +
187.286 + ScopeInfo parentScope = cur;
187.287 + beginScope(node.getInternalName(), FUNCSCOPE, node, ac);
187.288 + cur.nested = parentScope;
187.289 +
187.290 + int n = ac.names.size();
187.291 + for (int i = 0; i < n; i++) {
187.292 + cur.addParam(ac.names.get(i), ac.nodes.get(i));
187.293 + }
187.294 + for (int i = 0; i < ac.init_code.size(); i++) {
187.295 + visit(ac.init_code.get(i));
187.296 + }
187.297 + cur.markFromParam();
187.298 +
187.299 + PythonTree oldParent = parent;
187.300 + parent = node;
187.301 + suite(node.getInternalBody());
187.302 + parent = oldParent;
187.303 +
187.304 + endScope();
187.305 + return null;
187.306 + }
187.307 +
187.308 + @Override
187.309 + public Object visitLambda(Lambda node) throws Exception {
187.310 + ArgListCompiler ac = new ArgListCompiler(symbolTable);
187.311 + ac.visitArgs(node.getInternalArgs());
187.312 +
187.313 + List<expr> defaults = ac.getDefaults();
187.314 + for (expr expr : defaults) {
187.315 + visit(expr);
187.316 + }
187.317 +
187.318 + beginScope("<lambda>", FUNCSCOPE, node, ac);
187.319 + assert ac.names.size() == ac.nodes.size();
187.320 + for (int i = 0; i < ac.names.size(); i++) {
187.321 + cur.addParam(ac.names.get(i), ac.nodes.get(i));
187.322 + }
187.323 + for (Object o : ac.init_code) {
187.324 + visit((stmt)o);
187.325 + }
187.326 + cur.markFromParam();
187.327 + visit(node.getInternalBody());
187.328 + endScope();
187.329 + return null;
187.330 + }
187.331 +
187.332 + public void suite(List<stmt> stmts) throws Exception {
187.333 + if (stmts != null) {
187.334 + for (int i = 0; i < stmts.size(); i++) {
187.335 + stmt s = stmts.get(i);
187.336 + path.descend(s);
187.337 + visit(s);
187.338 + path.ascend();
187.339 + }
187.340 + }
187.341 + }
187.342 +
187.343 + @Override
187.344 + public Object visitImport(Import node) throws Exception {
187.345 + if (parent == root) {
187.346 + topLevelImports.add(node);
187.347 + }
187.348 + imports.add(node);
187.349 +
187.350 + List<alias> names = node.getInternalNames();
187.351 + if (names != null) {
187.352 + for (alias alias : names) {
187.353 + String asname = alias.getInternalAsname();
187.354 + if (asname != null) {
187.355 + SymInfo entry = cur.addBound(asname, node);
187.356 + entry.flags |= IMPORTED;
187.357 + } else {
187.358 + String name = alias.getInternalName();
187.359 + if (name.indexOf('.') > 0) {
187.360 + name = name.substring(0, name.indexOf('.'));
187.361 + }
187.362 + SymInfo entry = cur.addBound(name, node);
187.363 + entry.flags |= IMPORTED;
187.364 + }
187.365 + }
187.366 + }
187.367 + return null;
187.368 + }
187.369 +
187.370 + @Override
187.371 + public Object visitImportFrom(ImportFrom node) throws Exception {
187.372 + if (parent == root) {
187.373 + topLevelImports.add(node);
187.374 + }
187.375 + importsFrom.add(node);
187.376 +
187.377 + //Future.checkFromFuture(node); // future stmt support
187.378 + List<alias> names = node.getInternalNames();
187.379 + if (names == null || names.size() == 0) {
187.380 + cur.from_import_star = true;
187.381 + return null;
187.382 + }
187.383 + for (alias alias : names) {
187.384 + String asname = alias.getInternalAsname();
187.385 + if (asname != null) {
187.386 + SymInfo entry = cur.addBound(asname, node);
187.387 + entry.flags |= IMPORTED;
187.388 + } else {
187.389 + SymInfo entry = cur.addBound(alias.getInternalName(), node);
187.390 + entry.flags |= IMPORTED;
187.391 + }
187.392 + }
187.393 + return null;
187.394 + }
187.395 +
187.396 + @Override
187.397 + public Object visitGlobal(Global node) throws Exception {
187.398 + List<String> names = node.getInternalNames();
187.399 + for (String name : names) {
187.400 + int prev = cur.addGlobal(name, node);
187.401 + if (prev >= 0) {
187.402 + if ((prev & FROM_PARAM) != 0) {
187.403 + symbolTable.error("name '" + name + "' is local and global", true, node);
187.404 + }
187.405 + if ((prev & GLOBAL) != 0) {
187.406 + continue;
187.407 + }
187.408 + String what;
187.409 + if ((prev & BOUND) != 0) {
187.410 + what = "assignment";
187.411 + } else {
187.412 + what = "use";
187.413 + }
187.414 + symbolTable.error("name '" + name + "' declared global after " + what, false, node);
187.415 + }
187.416 + }
187.417 + return null;
187.418 + }
187.419 +
187.420 + @Override
187.421 + public Object visitExec(Exec node) throws Exception {
187.422 + cur.exec = true;
187.423 + if (node.getInternalGlobals() == null && node.getInternalLocals() == null) {
187.424 + cur.unqual_exec = true;
187.425 + }
187.426 + traverse(node);
187.427 + return null;
187.428 + }
187.429 +
187.430 + @Override
187.431 + public Object visitClassDef(ClassDef node) throws Exception {
187.432 + String name = node.getInternalName();
187.433 + def(name, CLASS, node);
187.434 + List<expr> bases = node.getInternalBases();
187.435 + if (bases != null) {
187.436 + for (expr expr : bases) {
187.437 + visit(expr);
187.438 + }
187.439 + }
187.440 + ScopeInfo parentScope = cur;
187.441 + beginScope(name, CLASSSCOPE, node, null);
187.442 + cur.nested = parentScope;
187.443 + PythonTree oldParent = parent;
187.444 + parent = node;
187.445 + suite(node.getInternalBody());
187.446 + parent = oldParent;
187.447 + endScope();
187.448 + return null;
187.449 + }
187.450 +
187.451 + @Override
187.452 + public Object visitName(Name node) throws Exception {
187.453 + // Jython's parser doesn't always initialize the parent references correctly;
187.454 + // try to correct that here.
187.455 + node.setParent(parent);
187.456 +
187.457 + String name = node.getInternalId();
187.458 + if (node.getInternalCtx() != expr_contextType.Load) {
187.459 + if (name.equals("__debug__")) {
187.460 + symbolTable.error("can not assign to __debug__", true, node);
187.461 + }
187.462 + cur.addBound(name, node);
187.463 + } else {
187.464 + cur.addUsed(name, node);
187.465 + }
187.466 + return null;
187.467 + }
187.468 +
187.469 + // <netbeans>
187.470 + @Override
187.471 + public Object visitCall(Call node) throws Exception {
187.472 + Object ret = super.visitCall(node);
187.473 +
187.474 + expr func = node.getInternalFunc();
187.475 + if (func instanceof Name) {
187.476 + Name name = (Name)func;
187.477 + cur.markCall(name.getInternalId());
187.478 + } else if (func instanceof Attribute) {
187.479 + Attribute attr = (Attribute)func;
187.480 + if (cur.attributes != null) {
187.481 + SymInfo funcSymbol = cur.attributes.get(attr.getInternalAttr());
187.482 + if (funcSymbol != null) {
187.483 + funcSymbol.flags |= FUNCTION | CALLED; // mark as func/method call
187.484 + }
187.485 + }
187.486 +
187.487 + }
187.488 +
187.489 + return ret;
187.490 + }
187.491 +
187.492 + @Override
187.493 + public Object visitDelete(Delete node) throws Exception {
187.494 + for (expr et : node.getInternalTargets()) {
187.495 + if (et instanceof Name) {
187.496 + String name = ((Name)et).getInternalId();
187.497 + cur.addUsed(name, node);
187.498 + }
187.499 + }
187.500 +
187.501 + return super.visitDelete(node);
187.502 + }
187.503 +
187.504 + @Override
187.505 + public Object visitAttribute(Attribute node) throws Exception {
187.506 + if (parent instanceof Call && node.getInternalValue() instanceof Name &&
187.507 + ("__all__".equals(((Name)node.getInternalValue()).getInternalId()))) {
187.508 + // If you for example call
187.509 + // __all__.extend("foo")
187.510 + // or
187.511 + // __all__.append("bar")
187.512 + // then I don't want to try to analyze __all__
187.513 + String nodeAttr = node.getInternalAttr();
187.514 + if ("extend".equals(nodeAttr) || "append".equals(nodeAttr)) { // NOI18N
187.515 + Call call = (Call)parent;
187.516 + List<expr> callArgs = call.getInternalArgs();
187.517 + if (callArgs != null) {
187.518 + for (expr expr : callArgs) {
187.519 + if (expr instanceof Str) {
187.520 + if (publicSymbols == null) {
187.521 + publicSymbols = new ArrayList<>();
187.522 + }
187.523 + publicSymbols.add((Str)expr);
187.524 + } else if (expr instanceof org.python.antlr.ast.List) {
187.525 + org.python.antlr.ast.List list = (org.python.antlr.ast.List)expr;
187.526 + if (list != null) {
187.527 + List<expr> elts = list.getInternalElts();
187.528 + if (elts != null) {
187.529 + for (expr ex : elts) {
187.530 + if (ex instanceof Str) {
187.531 + Str str = (Str)ex;
187.532 + if (publicSymbols == null) {
187.533 + publicSymbols = new ArrayList<>();
187.534 + }
187.535 + publicSymbols.add(str);
187.536 + } else {
187.537 + invalidPublicSymbols = true;
187.538 + }
187.539 + }
187.540 + }
187.541 + }
187.542 + } else {
187.543 + invalidPublicSymbols = true;
187.544 + break;
187.545 + }
187.546 + }
187.547 + }
187.548 + } else {
187.549 + invalidPublicSymbols = true;
187.550 + }
187.551 + } else {
187.552 + String nodeAttr = node.getInternalAttr();
187.553 + if (nodeAttr != null) {
187.554 + cur.addAttribute(path, nodeAttr, node);
187.555 + }
187.556 + }
187.557 + return super.visitAttribute(node);
187.558 + }
187.559 + // </netbeans>
187.560 +
187.561 + @Override
187.562 + public Object visitListComp(ListComp node) throws Exception {
187.563 + String tmp = "_[" + node.getLine() + "_" + node.getCharPositionInLine() + "]";
187.564 + cur.addBound(tmp, node);
187.565 + traverse(node);
187.566 + return null;
187.567 + }
187.568 +
187.569 + @Override
187.570 + public Object visitYield(Yield node) throws Exception {
187.571 + cur.defineAsGenerator(node);
187.572 + cur.yield_count++;
187.573 + traverse(node);
187.574 + return null;
187.575 + }
187.576 +
187.577 + @Override
187.578 + public Object visitReturn(Return node) throws Exception {
187.579 + if (node.getInternalValue() != null) {
187.580 + cur.noteReturnValue(node);
187.581 + }
187.582 + traverse(node);
187.583 + return null;
187.584 + }
187.585 +
187.586 + @Override
187.587 + public Object visitGeneratorExp(GeneratorExp node) throws Exception {
187.588 + // The first iterator is evaluated in the outer scope
187.589 + if (node.getInternalGenerators() != null && node.getInternalGenerators().size() > 0) {
187.590 + visit(node.getInternalGenerators().get(0).getInternalIter());
187.591 + }
187.592 + String bound_exp = "_(x)";
187.593 + String tmp = "_(" + node.getLine() + "_" + node.getCharPositionInLine() + ")";
187.594 + def(tmp, GENERATOR, node);
187.595 + ArgListCompiler ac = new ArgListCompiler(symbolTable);
187.596 + List<expr> args = new ArrayList<>();
187.597 + Name argsName = new Name(node.getToken(), bound_exp, expr_contextType.Param);
187.598 + args.add(argsName);
187.599 + ac.visitArgs(new arguments(node, args, null, null, new ArrayList<expr>()));
187.600 + beginScope(tmp, FUNCSCOPE, node, ac);
187.601 + cur.addParam(bound_exp, argsName);
187.602 + cur.markFromParam();
187.603 +
187.604 + cur.defineAsGenerator(node);
187.605 + cur.yield_count++;
187.606 + // The reset of the iterators are evaluated in the inner scope
187.607 + if (node.getInternalElt() != null) {
187.608 + visit(node.getInternalElt());
187.609 + }
187.610 + if (node.getInternalGenerators() != null) {
187.611 + for (int i = 0; i < node.getInternalGenerators().size(); i++) {
187.612 + if (node.getInternalGenerators().get(i) != null) {
187.613 + if (i == 0) {
187.614 + visit(node.getInternalGenerators().get(i).getInternalTarget());
187.615 + if (node.getInternalGenerators().get(i).getInternalIfs() != null) {
187.616 + for (expr cond : node.getInternalGenerators().get(i).getInternalIfs()) {
187.617 + if (cond != null) {
187.618 + visit(cond);
187.619 + }
187.620 + }
187.621 + }
187.622 + } else {
187.623 + visit(node.getInternalGenerators().get(i));
187.624 + }
187.625 + }
187.626 + }
187.627 + }
187.628 +
187.629 + endScope();
187.630 + return null;
187.631 + }
187.632 +
187.633 + @Override
187.634 + public Object visitWith(With node) throws Exception {
187.635 + cur.max_with_count++;
187.636 + traverse(node);
187.637 +
187.638 + return null;
187.639 + }
187.640 +
187.641 + public List<Str> getPublicSymbols() {
187.642 + return invalidPublicSymbols ? null : publicSymbols;
187.643 + }
187.644 +}
188.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
188.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/SymInfo.java Mon Sep 21 13:01:16 2015 +0200
188.3 @@ -0,0 +1,184 @@
188.4 +package org.netbeans.modules.python.source.scopes;
188.5 +
188.6 +import org.python.antlr.PythonTree;
188.7 +import static org.netbeans.modules.python.source.scopes.ScopeConstants.*;
188.8 +
188.9 +public class SymInfo extends Object {
188.10 + public SymInfo(int flags) {
188.11 + this.flags = flags;
188.12 + }
188.13 +
188.14 + public SymInfo(int flags, int locals_index) {
188.15 + this.flags = flags;
188.16 + this.locals_index = locals_index;
188.17 + }
188.18 + public int flags;
188.19 + public int locals_index;
188.20 + public int env_index;
188.21 + public PythonTree node;
188.22 +
188.23 + @Override
188.24 + public String toString() {
188.25 + return "SymInfo[" + flags + " " + locals_index + " " +
188.26 + env_index + "]" + dumpFlags(null);
188.27 + }
188.28 +
188.29 + public String dumpFlags(ScopeInfo info) {
188.30 + StringBuilder sb = new StringBuilder();
188.31 + if ((flags & BOUND) != 0) {
188.32 + sb.append("[bound]");
188.33 + }
188.34 + // func scope global (affect nested scopes)
188.35 + // vs. class scope global
188.36 + if ((flags & NGLOBAL) != 0) {
188.37 + sb.append("[func-global]");
188.38 + } else if ((flags & CLASS_GLOBAL) != 0) {
188.39 + sb.append("[class-global]");
188.40 + }
188.41 + if ((flags & PARAM) != 0) {
188.42 + sb.append("[param]");
188.43 + } else if ((flags & FROM_PARAM) != 0) {
188.44 + sb.append("[from-param]");
188.45 + }
188.46 + if ((flags & CELL) != 0) {
188.47 + sb.append("[cell]");
188.48 + }
188.49 + if ((flags & FREE) != 0) {
188.50 + sb.append("[free]");
188.51 + }
188.52 + if (isImported()) {
188.53 + sb.append("[imported]");
188.54 + }
188.55 + if (isPrivate()) {
188.56 + sb.append("[private]");
188.57 + }
188.58 + if (isClass()) {
188.59 + sb.append("[class]");
188.60 + }
188.61 + if (isFunction()) {
188.62 + sb.append("[function]");
188.63 + }
188.64 + if (isData()) {
188.65 + sb.append("[data]");
188.66 + }
188.67 + if (isMember()) {
188.68 + sb.append("[member]");
188.69 + }
188.70 + if (isDef()) {
188.71 + sb.append("[def]");
188.72 + }
188.73 + if (isRead()) {
188.74 + sb.append("[read]");
188.75 + }
188.76 + if (isAlias()) {
188.77 + sb.append("[alias]");
188.78 + }
188.79 + if (isGeneratorExp()) {
188.80 + sb.append("[generator]");
188.81 + }
188.82 + if (isCalled()) {
188.83 + sb.append("[called]");
188.84 + }
188.85 + if (isProtected()) {
188.86 + sb.append("[protected]");
188.87 + }
188.88 + if (isBoundInConstructor()) {
188.89 + sb.append("[bound-in-constructor]");
188.90 + }
188.91 + if (isUnused(info)) {
188.92 + sb.append("[unused]");
188.93 + }
188.94 + if (isUnresolved()) {
188.95 + sb.append("[UNRESOLVED]");
188.96 + }
188.97 + sb.append("[node=");
188.98 + if (node != null) {
188.99 + sb.append(node.getClass().getSimpleName());
188.100 + } else {
188.101 + sb.append("null");
188.102 + }
188.103 + sb.append("]");
188.104 +
188.105 + return sb.toString();
188.106 + }
188.107 +
188.108 + public boolean isUnused(ScopeInfo info) {
188.109 + // Cannot correctly detect usage of variables in CLASSSCOPE
188.110 + return (info == null || info.kind == FUNCSCOPE || info.kind == TOPSCOPE) &&
188.111 + (flags & (READ | BOUND | DEF)) == BOUND;
188.112 + }
188.113 +
188.114 + public boolean isParameter() {
188.115 + return (flags & (PARAM | FROM_PARAM)) != 0;
188.116 + }
188.117 +
188.118 + public boolean isUnresolved() {
188.119 + return (flags & (BOUND | FREE)) == 0;
188.120 + }
188.121 +
188.122 + public boolean isImported() {
188.123 + return (flags & IMPORTED) != 0;
188.124 + }
188.125 +
188.126 + public boolean isData() {
188.127 + return (flags & (BOUND | DEF | CLASS | FUNCTION)) == (BOUND);
188.128 + }
188.129 +
188.130 + public boolean isClass() {
188.131 + return (flags & CLASS) != 0;
188.132 + }
188.133 +
188.134 + public boolean isDef() {
188.135 + return (flags & DEF) != 0;
188.136 + }
188.137 +
188.138 + public boolean isFunction() {
188.139 + return (flags & FUNCTION) != 0;
188.140 + }
188.141 +
188.142 + public boolean isBound() {
188.143 + return (flags & BOUND) != 0;
188.144 + }
188.145 +
188.146 + public boolean isMember() {
188.147 + return (flags & MEMBER) != 0;
188.148 + }
188.149 +
188.150 + public boolean isCalled() {
188.151 + return (flags & CALLED) != 0;
188.152 + }
188.153 +
188.154 + public boolean isRead() {
188.155 + return (flags & READ) != 0;
188.156 + }
188.157 +
188.158 + public boolean isGeneratorExp() {
188.159 + return (flags & GENERATOR) != 0;
188.160 + }
188.161 +
188.162 + public boolean isFree() {
188.163 + return (flags & FREE) != 0;
188.164 + }
188.165 +
188.166 + public boolean isPrivate() {
188.167 + return (flags & PRIVATE) != 0;
188.168 + }
188.169 +
188.170 + public boolean isProtected() {
188.171 + return (flags & PROTECTED) != 0;
188.172 + }
188.173 +
188.174 + public boolean isBoundInConstructor() {
188.175 + return (flags & BOUND_IN_CONSTRUCTOR) != 0;
188.176 + }
188.177 +
188.178 + public boolean isAlias() {
188.179 + return (flags & ALIAS) != 0;
188.180 + }
188.181 +
188.182 + public boolean isVariable(boolean mustBeBound) {
188.183 + int mask = mustBeBound ? BOUND : 0;
188.184 + return (flags & (BOUND | CALLED | DEF | IMPORTED | CLASS | FUNCTION | MEMBER | GENERATOR)) == mask;
188.185 + }
188.186 +
188.187 +}
189.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
189.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/SymbolTable.java Mon Sep 21 13:01:16 2015 +0200
189.3 @@ -0,0 +1,1247 @@
189.4 +/*
189.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
189.6 + *
189.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
189.8 + *
189.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
189.10 + * Other names may be trademarks of their respective owners.
189.11 + *
189.12 + * The contents of this file are subject to the terms of either the GNU
189.13 + * General Public License Version 2 only ("GPL") or the Common
189.14 + * Development and Distribution License("CDDL") (collectively, the
189.15 + * "License"). You may not use this file except in compliance with the
189.16 + * License. You can obtain a copy of the License at
189.17 + * http://www.netbeans.org/cddl-gplv2.html
189.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
189.19 + * specific language governing permissions and limitations under the
189.20 + * License. When distributing the software, include this License Header
189.21 + * Notice in each file and include the License file at
189.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
189.23 + * particular file as subject to the "Classpath" exception as provided
189.24 + * by Oracle in the GPL Version 2 section of the License file that
189.25 + * accompanied this code. If applicable, add the following below the
189.26 + * License Header, with the fields enclosed by brackets [] replaced by
189.27 + * your own identifying information:
189.28 + * "Portions Copyrighted [year] [name of copyright owner]"
189.29 + *
189.30 + * If you wish your version of this file to be governed by only the CDDL
189.31 + * or only the GPL Version 2, indicate your decision by adding
189.32 + * "[Contributor] elects to include this software in this distribution
189.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
189.34 + * single choice of license, a recipient has the option to distribute
189.35 + * your version of this file under either the CDDL, the GPL Version 2 or
189.36 + * to extend the choice of license to its licensees as provided above.
189.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
189.38 + * Version 2 license, then the option applies only if the new code is
189.39 + * made subject to such option by the copyright holder.
189.40 + *
189.41 + * Contributor(s):
189.42 + *
189.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
189.44 + */
189.45 +package org.netbeans.modules.python.source.scopes;
189.46 +
189.47 +import java.util.ArrayList;
189.48 +import java.util.Collections;
189.49 +import java.util.HashMap;
189.50 +import java.util.HashSet;
189.51 +import java.util.List;
189.52 +import java.util.Map;
189.53 +import java.util.Set;
189.54 +import org.netbeans.modules.csl.api.ElementKind;
189.55 +import org.netbeans.modules.csl.api.OffsetRange;
189.56 +import org.netbeans.modules.csl.api.Severity;
189.57 +import org.netbeans.modules.csl.api.Error;
189.58 +import org.netbeans.modules.csl.spi.DefaultError;
189.59 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
189.60 +import org.netbeans.modules.python.source.PythonAstUtils;
189.61 +import org.netbeans.modules.python.source.PythonIndex;
189.62 +import org.netbeans.modules.python.source.PythonIndexer;
189.63 +import org.netbeans.modules.python.source.PythonParserResult;
189.64 +import org.netbeans.modules.python.source.PythonUtils;
189.65 +import org.netbeans.modules.python.source.elements.AstElement;
189.66 +import org.netbeans.modules.python.source.elements.Element;
189.67 +import org.netbeans.modules.python.source.elements.IndexedElement;
189.68 +import org.netbeans.modules.python.source.ImportEntry;
189.69 +import org.netbeans.modules.python.source.ImportManager;
189.70 +import org.openide.filesystems.FileObject;
189.71 +import org.openide.filesystems.FileUtil;
189.72 +import org.openide.util.Exceptions;
189.73 +import org.python.antlr.PythonTree;
189.74 +import org.python.antlr.Visitor;
189.75 +import org.python.antlr.ast.Attribute;
189.76 +import org.python.antlr.ast.ClassDef;
189.77 +import org.python.antlr.ast.Expression;
189.78 +import org.python.antlr.ast.FunctionDef;
189.79 +import org.python.antlr.ast.GeneratorExp;
189.80 +import org.python.antlr.ast.Import;
189.81 +import org.python.antlr.ast.ImportFrom;
189.82 +import org.python.antlr.ast.Interactive;
189.83 +import org.python.antlr.ast.Lambda;
189.84 +import org.python.antlr.ast.Name;
189.85 +import org.python.antlr.ast.Str;
189.86 +import org.python.antlr.ast.alias;
189.87 +import org.python.antlr.base.expr;
189.88 +import static org.netbeans.modules.python.source.scopes.ScopeConstants.*;
189.89 +
189.90 +/**
189.91 + * A symbol table tracks a bunch of scopes and can answer questions about defined
189.92 + * symbols.
189.93 + *
189.94 + * Based on Jython's ScopeManager.
189.95 + *
189.96 + * @author Tor Norbye
189.97 + */
189.98 +public class SymbolTable {
189.99 + private final static int YES = 1;
189.100 + private final static int NO = 0;
189.101 + private final static int CIRCULAR = -1;
189.102 + private Map<PythonTree, ScopeInfo> scopes = new HashMap<>();
189.103 + private PythonTree root;
189.104 + private FileObject fileObject;
189.105 + private List<Import> imports = new ArrayList<>();
189.106 + private List<ImportFrom> importsFrom = new ArrayList<>();
189.107 + private List<PythonTree> mainImports = new ArrayList<>();
189.108 + private Set<PythonTree> topLevelImports = new HashSet<>();
189.109 + private List<Error> errors;
189.110 + /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
189.111 + private List<Str> publicSymbols;
189.112 + private final static HashMap<String, String> classAttributes = new HashMap<String, String>() {
189.113 + {
189.114 + put("__class__", "__class__");
189.115 + put("__bases__", "__bases__");
189.116 + put("__dict__", "__dict__");
189.117 + put("__doc__", "__doc__");
189.118 + put("__name__", "__bases");
189.119 + }
189.120 + };
189.121 + private HashMap<String, ClassDef> classes = new HashMap<>();
189.122 + // TODO - use WeakHashMap?
189.123 + static Map<String, Set<IndexedElement>> importedElements = new HashMap<>();
189.124 +
189.125 + private HashMap<String, ClassDef> buildLocalClasses() {
189.126 + HashMap<String, ClassDef> localClasses = new HashMap<>();
189.127 + for (PythonTree cur : scopes.keySet()) {
189.128 + if (cur instanceof ClassDef) {
189.129 + ClassDef curClass = (ClassDef)cur;
189.130 + localClasses.put(curClass.getInternalName(), curClass);
189.131 + }
189.132 + }
189.133 + return localClasses;
189.134 + }
189.135 +
189.136 + public SymbolTable(PythonTree root, FileObject fileObject) {
189.137 + this.root = root;
189.138 + this.fileObject = fileObject;
189.139 +
189.140 + if (root != null) {
189.141 + try {
189.142 + ScopesCompiler compiler = new ScopesCompiler(this, scopes, root, imports, importsFrom, mainImports, topLevelImports);
189.143 + compiler.parse();
189.144 + publicSymbols = compiler.getPublicSymbols();
189.145 + classes = buildLocalClasses();
189.146 + if (publicSymbols != null) {
189.147 + // Mark all other symbols private!
189.148 + Set<String> names = new HashSet<>(publicSymbols.size() + 1);
189.149 + names.add("__all__"); // __all__ itself is exported!
189.150 + for (Str str : publicSymbols) {
189.151 + String name = PythonAstUtils.getStrContent(str);
189.152 + if (name != null) {
189.153 + names.add(name);
189.154 + }
189.155 + }
189.156 +
189.157 + ScopeInfo topScope = scopes.get(root);
189.158 + if (topScope != null) {
189.159 + for (Map.Entry<String, SymInfo> entry : topScope.tbl.entrySet()) {
189.160 + String name = entry.getKey();
189.161 + if (!names.contains(name)) {
189.162 + SymInfo sym = entry.getValue();
189.163 + sym.flags |= PRIVATE;
189.164 + if (sym.isDef() && sym.node != null) {
189.165 + ScopeInfo scope = scopes.get(sym.node);
189.166 + scope.hidden = true;
189.167 + }
189.168 + }
189.169 + }
189.170 + }
189.171 +
189.172 + for (Map.Entry<PythonTree, ScopeInfo> entry : scopes.entrySet()) {
189.173 + ScopeInfo scope = entry.getValue();
189.174 + boolean isHidden = false;
189.175 + ScopeInfo curr = scope;
189.176 + while (curr != null) {
189.177 + if (curr.hidden) {
189.178 + isHidden = true;
189.179 + break;
189.180 + }
189.181 + if (curr.nested != null) {
189.182 + curr = curr.nested;
189.183 + } else {
189.184 + curr = curr.up;
189.185 + }
189.186 +
189.187 + }
189.188 + if (isHidden) {
189.189 + scope.hidden = true;
189.190 + }
189.191 + }
189.192 +
189.193 + // Mark all symbols private, unless the scope is a direct descendant
189.194 + // of a public symbol
189.195 + for (ScopeInfo scope : scopes.values()) {
189.196 + if (scope.hidden) {
189.197 + for (SymInfo sym : scope.tbl.values()) {
189.198 + sym.flags |= PRIVATE;
189.199 + }
189.200 + }
189.201 + }
189.202 + }
189.203 + } catch (Exception ex) {
189.204 + Exceptions.printStackTrace(ex);
189.205 + }
189.206 + }
189.207 + }
189.208 +
189.209 + public boolean isPrivate(PythonTree node, String name) {
189.210 + ScopeInfo scope = scopes.get(node);
189.211 + if (scope == null) {
189.212 + scope = scopes.get(root);
189.213 + }
189.214 + if (scope != null) {
189.215 + if (scope.up != null) {
189.216 + if (scope.hidden) {
189.217 + return true;
189.218 + }
189.219 + // Look in parent's scope table
189.220 + if (scope.nested != null) {
189.221 + scope = scope.nested;
189.222 + } else {
189.223 + scope = scope.up;
189.224 + }
189.225 + if (scope != null) {
189.226 + SymInfo sym = scope.tbl.get(name);
189.227 + if (sym != null) {
189.228 + return sym.isPrivate();
189.229 + }
189.230 + }
189.231 + } else {
189.232 + SymInfo sym = scope.tbl.get(name);
189.233 + if (sym != null) {
189.234 + return sym.isPrivate();
189.235 + }
189.236 + }
189.237 + }
189.238 +
189.239 + return false;
189.240 + }
189.241 +
189.242 + public SymInfo findDeclaration(PythonTree scope, String name, boolean allowFree) {
189.243 + ScopeInfo scopeInfo = getScopeInfo(scope);
189.244 + if (scopeInfo != null) {
189.245 + SymInfo sym = scopeInfo.tbl.get(name);
189.246 + SymInfo orig = sym;
189.247 + while (sym != null && sym.isFree()) {
189.248 + scopeInfo = scopeInfo.up;
189.249 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
189.250 + scopeInfo = scopeInfo.up;
189.251 + }
189.252 + sym = scopeInfo.tbl.get(name);
189.253 + }
189.254 +
189.255 + if (allowFree && sym == null && orig != null) {
189.256 + // Free variable -- might have to resolve it
189.257 + return orig;
189.258 + }
189.259 +
189.260 + // Look for attributes too
189.261 + if (sym == null) {
189.262 + sym = scopeInfo.attributes.get(name);
189.263 + orig = sym;
189.264 + while (sym != null && sym.isFree()) {
189.265 + scopeInfo = scopeInfo.up;
189.266 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
189.267 + scopeInfo = scopeInfo.up;
189.268 + }
189.269 + sym = scopeInfo.tbl.get(name);
189.270 + }
189.271 +
189.272 + if (allowFree && sym == null && orig != null) {
189.273 + // Free variable -- might have to resolve it
189.274 + return orig;
189.275 + }
189.276 + }
189.277 +
189.278 + return sym;
189.279 + }
189.280 +
189.281 + return null;
189.282 + }
189.283 +
189.284 + public ScopeInfo getScopeInfo(PythonTree node) {
189.285 + return scopes.get(node);
189.286 + }
189.287 +
189.288 + public List<Error> getErrors() {
189.289 + return errors != null ? errors : Collections.<Error>emptyList();
189.290 + }
189.291 +
189.292 + public SymInfo findBySignature(ElementKind kind, String signature) {
189.293 + PythonTree scope = root;
189.294 + String name = signature;
189.295 + int dot = signature.lastIndexOf('.');
189.296 + if (dot != -1) {
189.297 + String clz = signature.substring(0, dot);
189.298 + name = signature.substring(dot + 1);
189.299 + SymInfo sym = findDeclaration(root, clz, true);
189.300 + if (sym != null && sym.node != null) {
189.301 + scope = sym.node;
189.302 + }
189.303 + }
189.304 + SymInfo sym = findDeclaration(scope, name, true);
189.305 +
189.306 + return sym;
189.307 + }
189.308 +
189.309 + private List<String> getModulesToStarImport() {
189.310 + List<String> modules = new ArrayList<>();
189.311 +
189.312 + for (ImportFrom from : importsFrom) {
189.313 + List<alias> names = from.getInternalNames();
189.314 + if (names != null) {
189.315 + for (alias at : names) {
189.316 + if ("*".equals(at.getInternalName())) { // NOI18N
189.317 + modules.add(from.getInternalModule());
189.318 + }
189.319 + }
189.320 + }
189.321 + }
189.322 +
189.323 + modules.addAll(PythonIndex.BUILTIN_MODULES);
189.324 +
189.325 + return modules;
189.326 + }
189.327 +
189.328 + private void addSymbolsFromModule(PythonParserResult info, String module, String prefix, QuerySupport.Kind kind, Set<? super IndexedElement> result) {
189.329 + if (PythonIndex.isBuiltinModule(module)) {
189.330 + Set<IndexedElement> all = getAllSymbolsFromModule(info, module);
189.331 + for (IndexedElement e : all) {
189.332 + if (kind == QuerySupport.Kind.PREFIX) {
189.333 + if (e.getName().startsWith(prefix)) {
189.334 + result.add(e);
189.335 + }
189.336 + } else if (kind == QuerySupport.Kind.EXACT) {
189.337 + if (prefix.equals(e.getName())) {
189.338 + result.add(e);
189.339 + }
189.340 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
189.341 + if (e.getName().regionMatches(true, 0, prefix, 0, prefix.length())) {
189.342 + result.add(e);
189.343 + }
189.344 + }
189.345 + }
189.346 + } else {
189.347 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
189.348 + Set<IndexedElement> elements = index.getImportedElements(prefix, kind, Collections.singleton(module), null);
189.349 + for (IndexedElement e : elements) {
189.350 + result.add(e);
189.351 + }
189.352 + }
189.353 + }
189.354 +
189.355 + private Set<IndexedElement> getAllSymbolsFromModule(PythonParserResult info, String module) {
189.356 + Set<IndexedElement> elements = importedElements.get(module);
189.357 + if (elements == null) {
189.358 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
189.359 + Set<String> systemHolder = new HashSet<>(3);
189.360 + elements = index.getImportedElements("", QuerySupport.Kind.PREFIX, Collections.singleton(module), systemHolder);
189.361 + // Cache system modules - don't cache local modules
189.362 + if (!systemHolder.isEmpty()) {
189.363 + importedElements.put(module, elements);
189.364 + }
189.365 + }
189.366 +
189.367 + return elements;
189.368 + }
189.369 +
189.370 + public Set<Element> getDefinedElements(PythonParserResult info, PythonTree scope, String prefix, QuerySupport.Kind kind) {
189.371 + Set<Element> elements = new HashSet<>(300);
189.372 + ScopeInfo scopeInfo = scopes.get(scope);
189.373 + String module = PythonUtils.getModuleName(fileObject);
189.374 + String url = fileObject.toURL().toExternalForm();
189.375 +
189.376 + // Get builtin symbols
189.377 + for (String mod : getModulesToStarImport()) {
189.378 + addSymbolsFromModule(info, mod, prefix, kind, elements);
189.379 + }
189.380 +
189.381 + // I can't just search the scope table for all variables in scope because this
189.382 + // will only include the local -bound- variables and the -used- free variables.
189.383 + // I need to find potential free variables as well. This means I should walk up
189.384 + // the scope chain and compute all eligible names. By keep track of the ones I've
189.385 + // already added I avoid adding references to variables I have re-bound in closer
189.386 + // scopes.
189.387 +
189.388 + Set<String> added = new HashSet<>();
189.389 +
189.390 + while (scopeInfo != null) {
189.391 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
189.392 + String name = entry.getKey();
189.393 + if (added.contains(name)) {
189.394 + // Something in narrower scope already processed this one
189.395 + continue;
189.396 + }
189.397 + if (kind == QuerySupport.Kind.EXACT) {
189.398 + if (!(name.equals(prefix))) {
189.399 + continue;
189.400 + }
189.401 + } else if (kind == QuerySupport.Kind.PREFIX) {
189.402 + if (!name.startsWith(prefix)) {
189.403 + continue;
189.404 + }
189.405 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
189.406 + if (!name.regionMatches(true, 0, prefix, 0, prefix.length())) {
189.407 + continue;
189.408 + }
189.409 + }
189.410 + SymInfo sym = entry.getValue();
189.411 +
189.412 + ScopeInfo curr = scopeInfo;
189.413 + while (sym != null && sym.isFree()) {
189.414 + curr = curr.up;
189.415 + while (curr != null && curr.kind == CLASSSCOPE) {
189.416 + curr = curr.up;
189.417 + }
189.418 + if (curr == null) {
189.419 + sym = null;
189.420 + break;
189.421 + }
189.422 + sym = scopeInfo.tbl.get(name);
189.423 + }
189.424 + if (sym == null) {
189.425 + continue;
189.426 + }
189.427 + if (sym.isUnresolved()) {
189.428 + // Don't add completion items for stuff we're not sure about
189.429 + continue;
189.430 + }
189.431 +
189.432 + PythonTree node = sym.node;
189.433 + if (node == null) {
189.434 + continue;
189.435 + }
189.436 +
189.437 +
189.438 + if (sym.isImported()) {
189.439 + Element element = new AstElement(this, node, name, Character.isUpperCase(name.charAt(0)) ? ElementKind.CLASS : ElementKind.MODULE);
189.440 + elements.add(element);
189.441 + } else if (sym.isDef()) {
189.442 + String signature;
189.443 + if (sym.isClass() && node instanceof ClassDef) {
189.444 + signature = PythonIndexer.computeClassSig((ClassDef)node, sym);
189.445 + } else if (sym.isFunction() && node instanceof FunctionDef) {
189.446 + assert sym.isFunction() && node instanceof FunctionDef : name + ";" + sym + " in " + module;
189.447 + signature = PythonIndexer.computeFunctionSig(name, (FunctionDef)node, sym);
189.448 + } else {
189.449 + // Probably a generator expression
189.450 + continue;
189.451 + }
189.452 + //Element element = AstElement.create(null, node);
189.453 + IndexedElement element = IndexedElement.create(signature, module, url, null);
189.454 + element.setSmart(true);
189.455 + elements.add(element);
189.456 + } else {
189.457 + // TODO - class attributes?
189.458 + Element element = new AstElement(this, node, name, ElementKind.VARIABLE);
189.459 + elements.add(element);
189.460 + }
189.461 +
189.462 + added.add(name);
189.463 + }
189.464 +
189.465 + scopeInfo = scopeInfo.up;
189.466 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
189.467 + scopeInfo = scopeInfo.up;
189.468 + }
189.469 + }
189.470 +
189.471 + return elements;
189.472 + }
189.473 +
189.474 + // Return all node references to the given name
189.475 + // This will include imports, calls, definitions, etc.
189.476 + public List<PythonTree> getOccurrences(PythonTree scope, String name, boolean abortOnFree) {
189.477 + ScopeInfo scopeInfo = scopes.get(scope);
189.478 + if (scopeInfo != null) {
189.479 + SymInfo sym = scopeInfo.tbl.get(name);
189.480 + while (sym != null && sym.isFree()) {
189.481 + if (abortOnFree) {
189.482 + return null;
189.483 + }
189.484 + scopeInfo = scopeInfo.up;
189.485 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
189.486 + scopeInfo = scopeInfo.up;
189.487 + }
189.488 + sym = scopeInfo.tbl.get(name);
189.489 + }
189.490 +
189.491 + if (sym != null) {
189.492 + NameNodeFinder finder = new NameNodeFinder(name, scopeInfo.scope_node);
189.493 + finder.run();
189.494 + return finder.getNodes();
189.495 + }
189.496 + }
189.497 +
189.498 + return Collections.emptyList();
189.499 + }
189.500 +
189.501 + /** Return a list of the variables visible from a given scope */
189.502 + public Set<String> getVarNames(PythonTree scope, boolean mustBeBound) {
189.503 + ScopeInfo scopeInfo = scopes.get(scope);
189.504 + Set<String> names = new HashSet<>();
189.505 + while (scopeInfo != null) {
189.506 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
189.507 + String name = entry.getKey();
189.508 + SymInfo sym = entry.getValue();
189.509 + if (sym.isVariable(mustBeBound)) {
189.510 + names.add(name);
189.511 + }
189.512 + }
189.513 + scopeInfo = scopeInfo.up;
189.514 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
189.515 + scopeInfo = scopeInfo.up;
189.516 + }
189.517 + }
189.518 +
189.519 + return names;
189.520 + }
189.521 +
189.522 + public List<ImportEntry> getUnusedImports() {
189.523 + List<ImportEntry> unused = new ArrayList<>();
189.524 + ScopeInfo scopeInfo = scopes.get(root);
189.525 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
189.526 + SymInfo sym = entry.getValue();
189.527 + if (sym.isImported() && !sym.isRead()) {
189.528 + String name = entry.getKey();
189.529 + if (name.equals("*")) { // NOI18N
189.530 + // Not detecting usages of wildcard imports yet...
189.531 + continue;
189.532 + }
189.533 + PythonTree node = sym.node;
189.534 + if (node instanceof Import) {
189.535 + Import imp = (Import)node;
189.536 + int ordinal = 0;
189.537 + String module = null;
189.538 + String asName = null;
189.539 + List<alias> names = imp.getInternalNames();
189.540 + if (names != null) {
189.541 + for (alias at : names) {
189.542 + if (name.equals(at.getInternalAsname())) {
189.543 + module = at.getInternalName();
189.544 + asName = at.getInternalAsname();
189.545 + break;
189.546 + } else if (name.equals(at.getInternalName())) {
189.547 + module = at.getInternalName();
189.548 + break;
189.549 + }
189.550 + }
189.551 + if (module == null) {
189.552 + // For imports with dotted names, like wsgiref.handlers,
189.553 + // the symbol table entry is just "wsgiref", yet I have to match
189.554 + // the symbols, so try again more carefully
189.555 + for (alias at : names) {
189.556 + if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
189.557 + at.getInternalAsname().charAt(name.length()) == '.') {
189.558 + module = at.getInternalName();
189.559 + asName = at.getInternalAsname();
189.560 + break;
189.561 + } else if (at.getInternalName().startsWith(name) &&
189.562 + at.getInternalName().charAt(name.length()) == '.') {
189.563 + module = at.getInternalName();
189.564 + break;
189.565 + }
189.566 + }
189.567 + }
189.568 + }
189.569 + unused.add(new ImportEntry(module, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
189.570 + } else if (node instanceof ImportFrom) {
189.571 + ImportFrom imp = (ImportFrom)node;
189.572 + if (ImportManager.isFutureImport(imp)) {
189.573 + continue;
189.574 + }
189.575 + String module = imp.getInternalModule();
189.576 + String origName = null;
189.577 + String asName = null;
189.578 + int ordinal = 0;
189.579 + List<alias> names = imp.getInternalNames();
189.580 + if (names != null) {
189.581 + for (alias at : names) {
189.582 + if (name.equals(at.getInternalAsname())) {
189.583 + origName = at.getInternalName();
189.584 + asName = at.getInternalAsname();
189.585 + break;
189.586 + } else if (name.equals(at.getInternalName())) {
189.587 + origName = at.getInternalName();
189.588 + break;
189.589 + }
189.590 + }
189.591 + if (origName == null) {
189.592 + // For imports with dotted names, like wsgiref.handlers,
189.593 + // the symbol table entry is just "wsgiref", yet I have to match
189.594 + // the symbols, so try again more carefully
189.595 + for (alias at : names) {
189.596 + if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
189.597 + at.getInternalAsname().charAt(name.length()) == '.') {
189.598 + origName = at.getInternalName();
189.599 + asName = at.getInternalAsname();
189.600 + break;
189.601 + } else if (at.getInternalName().startsWith(name) &&
189.602 + at.getInternalName().charAt(name.length()) == '.') {
189.603 + origName = at.getInternalName();
189.604 + break;
189.605 + }
189.606 + }
189.607 + }
189.608 + }
189.609 + unused.add(new ImportEntry(module, origName, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
189.610 + }
189.611 + }
189.612 + }
189.613 +
189.614 + return unused;
189.615 + }
189.616 +
189.617 + private class NameNodeFinder extends Visitor {
189.618 + private List<PythonTree> nodes = new ArrayList<>();
189.619 + private PythonTree startScope;
189.620 + private String name;
189.621 +
189.622 + public NameNodeFinder(String name, PythonTree startScope) {
189.623 + this.name = name;
189.624 + this.startScope = startScope;
189.625 + }
189.626 +
189.627 + public void run() {
189.628 + try {
189.629 + visit(startScope);
189.630 + } catch (Exception ex) {
189.631 + Exceptions.printStackTrace(ex);
189.632 + }
189.633 + }
189.634 +
189.635 + @Override
189.636 + public Object visitImport(Import imp) throws Exception {
189.637 + List<alias> names = imp.getInternalNames();
189.638 + if (names != null && names.size() > 0) {
189.639 + boolean found = false;
189.640 + for (alias at : names) {
189.641 + String asName = at.getInternalAsname();
189.642 + if (asName != null) {
189.643 + if (name.equals(asName)) {
189.644 + found = true;
189.645 + break;
189.646 + }
189.647 + } else if (name.equals(at.getInternalName())) {
189.648 + found = true;
189.649 + break;
189.650 + }
189.651 + }
189.652 + if (found) {
189.653 + nodes.add(imp);
189.654 + }
189.655 + }
189.656 + return super.visitImport(imp);
189.657 + }
189.658 +
189.659 + @Override
189.660 + public Object visitImportFrom(ImportFrom imp) throws Exception {
189.661 + List<alias> names = imp.getInternalNames();
189.662 + if (names != null && names.size() > 0) {
189.663 + boolean found = false;
189.664 + for (alias at : names) {
189.665 + String asName = at.getInternalAsname();
189.666 + if (asName != null) {
189.667 + if (name.equals(asName)) {
189.668 + found = true;
189.669 + break;
189.670 + }
189.671 + } else if (name.equals(at.getInternalName())) {
189.672 + found = true;
189.673 + break;
189.674 + }
189.675 + }
189.676 + if (found) {
189.677 + nodes.add(imp);
189.678 + }
189.679 + }
189.680 +
189.681 + return super.visitImportFrom(imp);
189.682 + }
189.683 +
189.684 + @Override
189.685 + public Object visitName(Name node) throws Exception {
189.686 + if (node.getInternalId().equals(name)) {
189.687 + nodes.add(node);
189.688 + }
189.689 + return super.visitName(node);
189.690 + }
189.691 +
189.692 + @Override
189.693 + public Object visitFunctionDef(FunctionDef node) throws Exception {
189.694 + if (name.equals(node.getInternalName())) {
189.695 + nodes.add(node);
189.696 + }
189.697 +
189.698 + if (isIncludedScope(node)) {
189.699 + return super.visitFunctionDef(node);
189.700 + } else {
189.701 + return null;
189.702 + }
189.703 + }
189.704 +
189.705 + @Override
189.706 + public Object visitClassDef(ClassDef node) throws Exception {
189.707 + if (name.equals(node.getInternalName())) {
189.708 + nodes.add(node);
189.709 + }
189.710 +
189.711 + if (isIncludedScope(node)) {
189.712 + return super.visitClassDef(node);
189.713 + } else {
189.714 + return null;
189.715 + }
189.716 + }
189.717 +
189.718 + @Override
189.719 + public Object visitExpression(Expression node) throws Exception {
189.720 + if (isIncludedScope(node)) {
189.721 + return super.visitExpression(node);
189.722 + } else {
189.723 + return null;
189.724 + }
189.725 + }
189.726 +
189.727 + @Override
189.728 + public Object visitInteractive(Interactive node) throws Exception {
189.729 + if (isIncludedScope(node)) {
189.730 + return super.visitInteractive(node);
189.731 + } else {
189.732 + return null;
189.733 + }
189.734 + }
189.735 +
189.736 + @Override
189.737 + public Object visitLambda(Lambda node) throws Exception {
189.738 + if (isIncludedScope(node)) {
189.739 + return super.visitLambda(node);
189.740 + } else {
189.741 + return null;
189.742 + }
189.743 + }
189.744 +
189.745 + @Override
189.746 + public Object visitGeneratorExp(GeneratorExp node) throws Exception {
189.747 + if (isIncludedScope(node)) {
189.748 + return super.visitGeneratorExp(node);
189.749 + } else {
189.750 + return null;
189.751 + }
189.752 + }
189.753 +
189.754 + private boolean isIncludedScope(PythonTree node) {
189.755 + if (node == startScope) {
189.756 + return true;
189.757 + }
189.758 +
189.759 + ScopeInfo info = scopes.get(node);
189.760 + if (info == null) {
189.761 + return false;
189.762 + }
189.763 +
189.764 + SymInfo sym = info.tbl.get(name);
189.765 + // Skip scopes that redefine the variable
189.766 + if (sym != null && sym.isBound()) {
189.767 + return false;
189.768 + }
189.769 +
189.770 + return true;
189.771 + }
189.772 +
189.773 + public List<PythonTree> getNodes() {
189.774 + return nodes;
189.775 + }
189.776 + }
189.777 +
189.778 + public Map<String, SymInfo> getUnresolvedNames(PythonParserResult info) {
189.779 + Map<String, SymInfo> unresolved = new HashMap<>();
189.780 + Set<String> builtin = getBuiltin(info);
189.781 +
189.782 + for (ScopeInfo scopeInfo : scopes.values()) {
189.783 + Map<String, SymInfo> tbl = scopeInfo.tbl;
189.784 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
189.785 + SymInfo symInfo = entry.getValue();
189.786 + boolean isUnresolved = symInfo.isUnresolved();
189.787 + if (!isUnresolved && symInfo.isFree()) {
189.788 + // Peek up scope stack
189.789 + String name = entry.getKey();
189.790 + SymInfo sym = symInfo;
189.791 + ScopeInfo scope = scopeInfo;
189.792 + while (sym != null && sym.isFree()) {
189.793 + scope = scope.up;
189.794 + while (scope != null && scope.kind == CLASSSCOPE) {
189.795 + scope = scope.up;
189.796 + }
189.797 + sym = scope.tbl.get(name);
189.798 + }
189.799 + if (sym == null) {
189.800 + isUnresolved = true;
189.801 + } else {
189.802 + isUnresolved = sym.isUnresolved();
189.803 + }
189.804 + }
189.805 + if (isUnresolved) {
189.806 + String key = entry.getKey();
189.807 + if (!builtin.contains(key)) {
189.808 + unresolved.put(key, symInfo);
189.809 + }
189.810 + }
189.811 + }
189.812 + }
189.813 +
189.814 + return unresolved;
189.815 + }
189.816 +
189.817 + public List<Attribute> getNotInInitAttributes(PythonParserResult info) {
189.818 + List<Attribute> notInInitAttribs = new ArrayList<>();
189.819 + for (ScopeInfo scopeInfo : scopes.values()) {
189.820 + if (scopeInfo.scope_node instanceof ClassDef) {
189.821 + if (scopeInfo.attributes != null) {
189.822 + for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
189.823 + SymInfo symInfo = entry.getValue();
189.824 + if (!symInfo.isBoundInConstructor()) {
189.825 + notInInitAttribs.add((Attribute)symInfo.node);
189.826 + }
189.827 + }
189.828 + }
189.829 + }
189.830 + }
189.831 + return notInInitAttribs;
189.832 + }
189.833 +
189.834 + private ScopeInfo getClassScope(String className) {
189.835 + for (ScopeInfo scopeInfo : scopes.values()) {
189.836 + if (scopeInfo.scope_node instanceof ClassDef) {
189.837 + ClassDef curClass = (ClassDef)scopeInfo.scope_node;
189.838 + if (curClass.getInternalName().equals(className)) {
189.839 + return scopeInfo;
189.840 + }
189.841 + }
189.842 + }
189.843 + return null;
189.844 + }
189.845 +
189.846 + private int belongsToParents(ClassDef cls, String name, HashMap<String, String> cycling) {
189.847 + List<expr> bases = cls.getInternalBases();
189.848 + if (bases == null || bases.size() == 0) {
189.849 + return NO; // no parents
189.850 + }
189.851 + for (expr base : bases) {
189.852 + String className = null;
189.853 + if (base instanceof Name) {
189.854 + className = ((Name)base).getInternalId();
189.855 + } else {
189.856 + // should be Attribute here( module.className form )
189.857 + // which imply imported from external scope
189.858 + // So we give up on scope returning optimistaically True
189.859 + return YES;
189.860 + }
189.861 + assert (className != null);
189.862 + if (cycling.get(className) != null) {
189.863 + cycling.clear();
189.864 + // put parent child conficting back in cycling
189.865 + cycling.put(className, cls.getInternalName());
189.866 + return CIRCULAR;
189.867 + }
189.868 + cycling.put(className, className);
189.869 + ScopeInfo localClassScope = getClassScope(className);
189.870 + if (localClassScope == null) {
189.871 + // return true (success) when at least one parent is outside module scope
189.872 + // just to notify caller to be optimistic and assume that
189.873 + // name is resolved by imported classes inheritance
189.874 + // scanning imported classed from here is discouraged for
189.875 + // performances reasons
189.876 + return YES;
189.877 + } else {
189.878 + if ((name != null) &&
189.879 + (localClassScope.attributes.get(name) != null)) {
189.880 + return YES;
189.881 + }
189.882 + // try recurse parentage to resolve attribute
189.883 + ClassDef parentClass = (ClassDef)localClassScope.scope_node;
189.884 + int recResult = belongsToParents(parentClass, name, cycling);
189.885 + if (recResult != NO) // stop on FOUND(YES) or CIRCULAR error
189.886 + {
189.887 + return recResult;
189.888 + }
189.889 + }
189.890 + }
189.891 + return NO;
189.892 + }
189.893 +
189.894 + private boolean isImported(String moduleName) {
189.895 + for (Import imported : imports) {
189.896 + List<alias> names = imported.getInternalNames();
189.897 + if (names != null) {
189.898 + for (alias cur : names) {
189.899 + String name = cur.getInternalName();
189.900 + String asName = cur.getInternalAsname();
189.901 + if (((name != null) && (name.equals(moduleName))) ||
189.902 + ((asName != null) && (asName.equals(moduleName)))) {
189.903 + return true;
189.904 + }
189.905 + }
189.906 + }
189.907 + }
189.908 + return false;
189.909 + }
189.910 +
189.911 + private boolean isImportedFrom(String className) {
189.912 + for (ImportFrom importedFrom : importsFrom) {
189.913 + List<alias> names = importedFrom.getInternalNames();
189.914 + if (names != null) {
189.915 + for (alias cur : names) {
189.916 + String name = cur.getInternalName();
189.917 + String asName = cur.getInternalAsname();
189.918 + if (((name != null) && (name.equals(className))) ||
189.919 + ((asName != null) && (asName.equals(className)))) {
189.920 + return true;
189.921 + }
189.922 + }
189.923 + }
189.924 + }
189.925 + return false;
189.926 + }
189.927 +
189.928 + public List<PythonTree> getUnresolvedParents(PythonParserResult info) {
189.929 + // deal with unresolved parents in inherit trees
189.930 + List<PythonTree> unresolvedParents = new ArrayList<>();
189.931 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
189.932 +
189.933 + for (String cur : classes.keySet()) {
189.934 + ClassDef cls = classes.get(cur);
189.935 + List<expr> bases = cls.getInternalBases();
189.936 + if (bases == null || bases.size() > 0) {
189.937 + // has parents
189.938 + for (expr base : bases) {
189.939 + if (base instanceof Name) {
189.940 + String className = ((Name)base).getInternalId();
189.941 + Set<String> builtin = getBuiltin(info);
189.942 + if ((!classes.containsKey(className)) &&
189.943 + (!builtin.contains(className))) {
189.944 + // check in from imports
189.945 + if (!isImportedFrom(className)) {
189.946 + unresolvedParents.add(base);
189.947 + }
189.948 + }
189.949 + } else {
189.950 + // should be Attribute here( module.className form )
189.951 + // which imply imported from external scope
189.952 + Attribute attr = (Attribute)base;
189.953 + String clsName = attr.getInternalAttr();
189.954 + if (attr.getInternalValue() instanceof Name) {
189.955 + String moduleName = ((Name)(attr.getInternalValue())).getInternalId();
189.956 + // check that import is resolved first
189.957 + if (!isImported(moduleName)) {
189.958 + unresolvedParents.add(base);
189.959 + } else {
189.960 + Set<IndexedElement> found = index.getImportedElements(clsName, QuerySupport.Kind.EXACT, Collections.<String>singleton(moduleName), null);
189.961 + if (found.size() == 0) {
189.962 + unresolvedParents.add(base);
189.963 + }
189.964 + }
189.965 + } else {
189.966 + unresolvedParents.add(base);
189.967 + }
189.968 + }
189.969 + }
189.970 + }
189.971 + }
189.972 + return unresolvedParents;
189.973 + }
189.974 +
189.975 + public HashMap<ClassDef, String> getClassesCyclingRedundancies(PythonParserResult info) {
189.976 + HashMap<ClassDef, String> cyclingRedundancies = new HashMap<>();
189.977 + for (String cur : classes.keySet()) {
189.978 + HashMap<String, String> returned = new HashMap<>();
189.979 + ClassDef curClass = classes.get(cur);
189.980 + if (!cyclingRedundancies.containsKey(curClass)) {
189.981 + if (belongsToParents(curClass, null, returned) == CIRCULAR) {
189.982 + // store hashMap returned
189.983 + Map.Entry<String, String> cycling = returned.entrySet().iterator().next();
189.984 + cyclingRedundancies.put(curClass, cycling.getKey());
189.985 + }
189.986 + }
189.987 + }
189.988 + return cyclingRedundancies;
189.989 + }
189.990 +
189.991 + public List<PythonTree> getUnresolvedAttributes(PythonParserResult info) {
189.992 + List<PythonTree> unresolvedNodes = new ArrayList<>();
189.993 + for (ScopeInfo scopeInfo : scopes.values()) {
189.994 + Set<String> unresolved = new HashSet<>();
189.995 + Map<String, SymInfo> tbl = scopeInfo.tbl;
189.996 + // unresolved attributes in local classes
189.997 + Map<String, SymInfo> attribs = scopeInfo.attributes;
189.998 + for (Map.Entry<String, SymInfo> curAttr : attribs.entrySet()) {
189.999 + SymInfo symInfo = curAttr.getValue();
189.1000 + if (symInfo.isRead()) {
189.1001 + // check for builtin attribs first
189.1002 + if (classAttributes.get(curAttr.getKey()) == null) {
189.1003 + // not a builtin attribute
189.1004 + ScopeInfo parentScope = scopeInfo.getClassScope();
189.1005 + if (parentScope != null) {
189.1006 + // limit scope to Classes for self and inherited
189.1007 + Map<String, SymInfo> parentattribs = parentScope.attributes;
189.1008 + SymInfo classAttr = parentattribs.get(curAttr.getKey());
189.1009 + tbl = parentScope.tbl;
189.1010 + if (classAttr == null) {
189.1011 + // may be also a reference to a method
189.1012 + classAttr = tbl.get(curAttr.getKey());
189.1013 + }
189.1014 + if (classAttr == null) {
189.1015 + // do not bother with method since they are
189.1016 + // managed by completion
189.1017 + ClassDef curClass = (ClassDef)parentScope.scope_node;
189.1018 + if (belongsToParents(curClass, curAttr.getKey(), new HashMap()) == NO) {
189.1019 + if (!symInfo.isCalled()) {
189.1020 + // no corresponding attributes
189.1021 + //PythonTree tree = symInfo.node ;
189.1022 + Attribute attr = (Attribute)symInfo.node;
189.1023 + // Name name = new Name(tree.getToken(),attr.getInternalAttr(),attr.ctx) ;
189.1024 + unresolvedNodes.add(attr);
189.1025 + }
189.1026 + }
189.1027 + }
189.1028 + }
189.1029 + }
189.1030 + }
189.1031 + }
189.1032 + if (unresolved.size() > 0) {
189.1033 + NameFinder finder = new NameFinder(unresolved);
189.1034 + List<Name> nodes = finder.run(scopeInfo.scope_node);
189.1035 + unresolvedNodes.addAll(nodes);
189.1036 + }
189.1037 +
189.1038 + }
189.1039 +
189.1040 + if (unresolvedNodes.size() > 1) {
189.1041 + Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
189.1042 + //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
189.1043 + }
189.1044 +
189.1045 + return unresolvedNodes;
189.1046 + }
189.1047 +
189.1048 + public List<PythonTree> getUnresolved(PythonParserResult info) {
189.1049 + List<PythonTree> unresolvedNodes = new ArrayList<>();
189.1050 + Set<String> builtin = getBuiltin(info);
189.1051 +
189.1052 + for (ScopeInfo scopeInfo : scopes.values()) {
189.1053 + Set<String> unresolved = new HashSet<>();
189.1054 + Map<String, SymInfo> tbl = scopeInfo.tbl;
189.1055 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
189.1056 + SymInfo symInfo = entry.getValue();
189.1057 + boolean isUnresolved = symInfo.isUnresolved();
189.1058 + if (!isUnresolved && symInfo.isFree()) {
189.1059 + // Peek up scope stack
189.1060 + String name = entry.getKey();
189.1061 + SymInfo sym = symInfo;
189.1062 + ScopeInfo scope = scopeInfo;
189.1063 + while (sym != null && sym.isFree()) {
189.1064 + scope = scope.up;
189.1065 + while (scope != null && scope.kind == CLASSSCOPE) {
189.1066 + scope = scope.up;
189.1067 + }
189.1068 + sym = scope.tbl.get(name);
189.1069 + }
189.1070 + if (sym == null) {
189.1071 + isUnresolved = true;
189.1072 + } else {
189.1073 + isUnresolved = sym.isUnresolved();
189.1074 + }
189.1075 + }
189.1076 + if (isUnresolved) {
189.1077 + String key = entry.getKey();
189.1078 + if (!builtin.contains(key)) {
189.1079 + unresolved.add(key);
189.1080 + }
189.1081 + }
189.1082 + }
189.1083 +
189.1084 +
189.1085 + if (unresolved.size() > 0) {
189.1086 + // Check imports and see if it's resolved by existing imports
189.1087 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
189.1088 + // TODO - cache system libraries!
189.1089 + // TODO - make method which doesn't create elements for these guys!
189.1090 +// Set<IndexedElement> elements = index.getImportedElements("", NameKind.PREFIX, PythonIndex.ALL_SCOPE, imports, importsFrom);
189.1091 +// for (IndexedElement e : elements) {
189.1092 +// unresolved.remove(e.getName());
189.1093 +// }
189.1094 + Set<String> wildcarded = index.getImportedFromWildcards(importsFrom);
189.1095 + unresolved.removeAll(wildcarded);
189.1096 +
189.1097 + if (unresolved.size() > 0) {
189.1098 + NameFinder finder = new NameFinder(unresolved);
189.1099 + List<Name> nodes = finder.run(scopeInfo.scope_node);
189.1100 + unresolvedNodes.addAll(nodes);
189.1101 + }
189.1102 + }
189.1103 + }
189.1104 +
189.1105 + if (unresolvedNodes.size() > 1) {
189.1106 + Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
189.1107 + //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
189.1108 + }
189.1109 +
189.1110 + return unresolvedNodes;
189.1111 + }
189.1112 +
189.1113 + public List<PythonTree> getUnused(boolean skipSelf, boolean skipParams) { // not used for unused imports, see separate method
189.1114 + List<PythonTree> unusedNodes = new ArrayList<>();
189.1115 +
189.1116 + for (ScopeInfo scopeInfo : scopes.values()) {
189.1117 + if (scopeInfo.kind != FUNCSCOPE && scopeInfo.kind != TOPSCOPE && scopeInfo.kind != CLASSSCOPE) {
189.1118 + continue;
189.1119 + }
189.1120 + Set<String> unused = new HashSet<>();
189.1121 + Map<String, SymInfo> tbl = scopeInfo.tbl;
189.1122 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
189.1123 + SymInfo symInfo = entry.getValue();
189.1124 + if (symInfo.isUnused(scopeInfo) && (!skipParams || !symInfo.isParameter())) {
189.1125 + String key = entry.getKey();
189.1126 + if (skipSelf && "self".equals(key)) { // NOI18N
189.1127 + continue;
189.1128 + }
189.1129 + unused.add(key);
189.1130 + }
189.1131 + }
189.1132 +
189.1133 + if (unused.size() > 0) {
189.1134 + NameFinder finder = new NameFinder(unused);
189.1135 + List<Name> nodes = finder.run(scopeInfo.scope_node);
189.1136 + unusedNodes.addAll(nodes);
189.1137 + }
189.1138 + }
189.1139 +
189.1140 + if (unusedNodes.size() > 1) {
189.1141 + Collections.sort(unusedNodes, PythonUtils.NAME_NODE_COMPARATOR);
189.1142 + //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
189.1143 + }
189.1144 +
189.1145 + return unusedNodes;
189.1146 + }
189.1147 +
189.1148 + private static class NameFinder extends Visitor {
189.1149 + private Set<String> names;
189.1150 + private List<Name> nodes = new ArrayList<>();
189.1151 + private PythonTree acceptDef;
189.1152 +
189.1153 + private NameFinder(Set<String> names) {
189.1154 + this.names = names;
189.1155 + }
189.1156 +
189.1157 + @Override
189.1158 + public Object visitClassDef(ClassDef node) throws Exception {
189.1159 + // Don't look in nested scopes
189.1160 + if (node != acceptDef) {
189.1161 + return null;
189.1162 + }
189.1163 + return super.visitClassDef(node);
189.1164 + }
189.1165 +
189.1166 + @Override
189.1167 + public Object visitFunctionDef(FunctionDef node) throws Exception {
189.1168 + // Don't look in nested scopes
189.1169 + if (node != acceptDef) {
189.1170 + return null;
189.1171 + }
189.1172 + return super.visitFunctionDef(node);
189.1173 + }
189.1174 +
189.1175 + @Override
189.1176 + public Object visitName(Name node) throws Exception {
189.1177 + String name = node.getInternalId();
189.1178 + if (names.contains(name)) {
189.1179 + nodes.add(node);
189.1180 + }
189.1181 +
189.1182 + return super.visitName(node);
189.1183 + }
189.1184 +
189.1185 + public List<Name> run(PythonTree node) {
189.1186 + this.acceptDef = node;
189.1187 + try {
189.1188 + visit(node);
189.1189 + } catch (Exception ex) {
189.1190 + Exceptions.printStackTrace(ex);
189.1191 + }
189.1192 +
189.1193 + return nodes;
189.1194 + }
189.1195 + }
189.1196 + private static Set<String> builtinSymbols;
189.1197 +
189.1198 + private Set<String> getBuiltin(PythonParserResult info) {
189.1199 + if (builtinSymbols == null) {
189.1200 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
189.1201 + builtinSymbols = index.getBuiltinSymbols();
189.1202 + }
189.1203 +
189.1204 + return builtinSymbols;
189.1205 + }
189.1206 +
189.1207 + public void error(String msg, boolean err, PythonTree node) throws Exception {
189.1208 + assert node != null;
189.1209 + // TODO - record and register with the hints manager?
189.1210 + OffsetRange range = PythonAstUtils.getRange(node);
189.1211 +
189.1212 + if (errors == null) {
189.1213 + errors = new ArrayList<>();
189.1214 + }
189.1215 + Error error = new DefaultError(null, msg, null, fileObject, range.getStart(), range.getEnd(), err ? Severity.ERROR : Severity.WARNING);
189.1216 + errors.add(error);
189.1217 + }
189.1218 +
189.1219 + public String getFilename() {
189.1220 + return FileUtil.getFileDisplayName(fileObject);
189.1221 + }
189.1222 +
189.1223 + public Map<PythonTree, ScopeInfo> getScopes() {
189.1224 + return scopes;
189.1225 + }
189.1226 +
189.1227 + public List<Import> getImports() {
189.1228 + return imports;
189.1229 + }
189.1230 +
189.1231 + public List<ImportFrom> getImportsFrom() {
189.1232 + return importsFrom;
189.1233 + }
189.1234 +
189.1235 + public boolean isTopLevel(PythonTree node) {
189.1236 + return topLevelImports.contains(node);
189.1237 + }
189.1238 +
189.1239 + public List<PythonTree> getMainImports() {
189.1240 + return mainImports;
189.1241 + }
189.1242 +
189.1243 + public Set<PythonTree> getTopLevelImports() {
189.1244 + return topLevelImports;
189.1245 + }
189.1246 +
189.1247 + public List<Str> getPublicSymbols() {
189.1248 + return publicSymbols;
189.1249 + }
189.1250 +}
190.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
190.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/Bundle.properties Mon Sep 21 13:01:16 2015 +0200
190.3 @@ -0,0 +1,284 @@
190.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
190.5 +#
190.6 +# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
190.7 +#
190.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
190.9 +# Other names may be trademarks of their respective owners.
190.10 +#
190.11 +# The contents of this file are subject to the terms of either the GNU
190.12 +# General Public License Version 2 only ("GPL") or the Common
190.13 +# Development and Distribution License("CDDL") (collectively, the
190.14 +# "License"). You may not use this file except in compliance with the
190.15 +# License. You can obtain a copy of the License at
190.16 +# http://www.netbeans.org/cddl-gplv2.html
190.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
190.18 +# specific language governing permissions and limitations under the
190.19 +# License. When distributing the software, include this License Header
190.20 +# Notice in each file and include the License file at
190.21 +# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
190.22 +# particular file as subject to the "Classpath" exception as provided
190.23 +# by Oracle in the GPL Version 2 section of the License file that
190.24 +# accompanied this code. If applicable, add the following below the
190.25 +# License Header, with the fields enclosed by brackets [] replaced by
190.26 +# your own identifying information:
190.27 +# "Portions Copyrighted [year] [name of copyright owner]"
190.28 +#
190.29 +# Contributor(s):
190.30 +#
190.31 +# The Original Software is NetBeans. The Initial Developer of the Original
190.32 +# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
190.33 +# Microsystems, Inc. All Rights Reserved.
190.34 +#
190.35 +# If you wish your version of this file to be governed by only the CDDL
190.36 +# or only the GPL Version 2, indicate your decision by adding
190.37 +# "[Contributor] elects to include this software in this distribution
190.38 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
190.39 +# single choice of license, a recipient has the option to distribute
190.40 +# your version of this file under either the CDDL, the GPL Version 2 or
190.41 +# to extend the choice of license to its licensees as provided above.
190.42 +# However, if you add GPL Version 2 code and therefore, elected the GPL
190.43 +# Version 2 license, then the option applies only if the new code is
190.44 +# made subject to such option by the copyright holder.
190.45 +
190.46 +# Formating options
190.47 +
190.48 +LBL_TabsAndIndents=Tabs and Indents
190.49 +LBL_CodeGeneration=Code Generation
190.50 +LBL_Alignment=Alignment
190.51 +LBL_Wrapping=Wrapping
190.52 +LBL_BlankLines=Blank Lines
190.53 +LBL_Spaces=Spaces
190.54 +LBL_Imports=Imports
190.55 +
190.56 +LBL_bp_SAME_LINE=Same Line
190.57 +LBL_bp_NEW_LINE=New Line
190.58 +LBL_bp_NEW_LINE_HALF_INDENTED=New Line Half Indented
190.59 +LBL_bp_NEW_LINE_INDENTED= New Line Indented
190.60 +
190.61 +LBL_bg_GENERATE=Generate
190.62 +LBL_bg_LEAVE_ALONE=Leave Alone
190.63 +LBL_bg_ELIMINATE=Eliminate
190.64 +
190.65 +LBL_wrp_WRAP_ALWAYS=Always
190.66 +LBL_wrp_WRAP_IF_LONG=If Long
190.67 +LBL_wrp_WRAP_NEVER=Never
190.68 +
190.69 +LBL_imp_COMMENT_OUT=Comment Out
190.70 +LBL_imp_LEAVE_ALONE=Leave Alone
190.71 +LBL_imp_DELETE=Delete
190.72 +
190.73 +LBL_ExpandTabToSpaces=&Expand Tab to Spaces
190.74 +LBL_TabSize=&Tab Size:
190.75 +LBL_IndentSize=&Indentation Size:
190.76 +LBL_ContinuationIndentSize=&Continuation Indentation Size:
190.77 +LBL_LabelIndent=&Label Indentation\:
190.78 +LBL_AbsoluteLabelIndent=&Absolute Label Indentation
190.79 +LBL_IndentTopLevelClassMemberts=Indent Top Level Class &Members
190.80 +LBL_AddLeadingStarInComment=Add Leading Star In Comment
190.81 +LBL_RightMargin=&Right Margin:
190.82 +
190.83 +LBL_Naming=Naming\:
190.84 +LBL_PreferLongerNames=Prefer Longer Names
190.85 +LBL_Prefix=Prefix
190.86 +LBL_Suffix=Suffix
190.87 +LBL_Field=Field\:
190.88 +LBL_StaticField=Static Field\:
190.89 +LBL_Parameter=Parameter\:
190.90 +LBL_LocalVariable=Local Variable\:
190.91 +LBL_Misc=Misc\:
190.92 +LBL_QualifyFieldAccess=Qualify Field Access
190.93 +LBL_UseIsForBooleanGetters=Use Is For Boolean Getters
190.94 +LBL_AddOverrideAnnotation=Add Override Annotation
190.95 +LBL_FinalMofier=Final Modifier\:
190.96 +LBL_ParametersFinal=Make Generated Parameters Final
190.97 +LBL_LocalVariablesFinal=Make Generated Local variables Final
190.98 +LBL_ImportOredering=Import Ordering\:
190.99 +LBL_ImportUp=Move Up
190.100 +LBL_ImportDown=Move Down
190.101 +LBL_blBeforePackage=Before &Package\:
190.102 +LBL_blAfterPackage=After P&ackage\:
190.103 +LBL_blBeforeImports=Before &Imports\:
190.104 +LBL_blAfterImports=After I&mports\:
190.105 +LBL_blBeforeClass=Before &Class\:
190.106 +LBL_blAfterClass=After C&lass\:
190.107 +LBL_blAfterClassHeader=After Class &Header\:
190.108 +LBL_blBeforeFields=Before &Field\:
190.109 +LBL_blAfterFields=After Fi&eld\:
190.110 +LBL_blBeforeMethods=Before &Method\:
190.111 +LBL_blAfterMethods=After Me&thod\:
190.112 +
190.113 +LBL_BeforeKeywords=Before Keywords
190.114 +LBL_spaceBeforeWhile="while"
190.115 +LBL_spaceBeforeElse="else"
190.116 +LBL_spaceBeforeCatch="catch"
190.117 +LBL_spaceBeforeFinally="finally"
190.118 +
190.119 +LBL_BeforeParentheses=Before Parentheses
190.120 +LBL_spaceBeforeMethodDeclParen=Method Declaration
190.121 +LBL_spaceBeforeMethodCallParen=Method Call
190.122 +LBL_spaceBeforeIfParen="if"
190.123 +LBL_spaceBeforeForParen="for"
190.124 +LBL_spaceBeforeWhileParen="while"
190.125 +LBL_spaceBeforeCatchParen="catch"
190.126 +LBL_spaceBeforeSwitchParen="switch"
190.127 +LBL_spaceBeforeSynchronizedParen="synchronized"
190.128 +LBL_spaceBeforeAnnotationParen=Annotation Parameters
190.129 +
190.130 +LBL_AroundOperators=Around Operators
190.131 +LBL_spaceAroundUnaryOps=Unary Operators
190.132 +LBL_spaceAroundBinaryOps=Binary Operators
190.133 +LBL_spaceAroundTernaryOps=Ternary Operators
190.134 +LBL_spaceAroundAssignOps=Assignment Operators
190.135 +
190.136 +LBL_BeforeLeftBraces=Before Left Braces
190.137 +LBL_spaceBeforeClassDeclLeftBrace=Class Declaration
190.138 +LBL_spaceBeforeMethodDeclLeftBrace=Method Declaration
190.139 +LBL_spaceBeforeIfLeftBrace="if"
190.140 +LBL_spaceBeforeElseLeftBrace="else"
190.141 +LBL_spaceBeforeWhileLeftBrace="while"
190.142 +LBL_spaceBeforeForLeftBrace="for"
190.143 +LBL_spaceBeforeDoLeftBrace="do"
190.144 +LBL_spaceBeforeSwitchLeftBrace="switch"
190.145 +LBL_spaceBeforeTryLeftBrace="try"
190.146 +LBL_spaceBeforeCatchLeftBrace="catch"
190.147 +LBL_spaceBeforeFinallyLeftBrace="finally"
190.148 +LBL_spaceBeforeSynchronizedLeftBrace="synchronized"
190.149 +LBL_spaceBeforeStaticInitLeftBrace=Static Initializer
190.150 +LBL_spaceBeforeArrayInitLeftBrace=Array Initializer
190.151 +
190.152 +LBL_WithinParentheses=Within Parentheses
190.153 +LBL_spaceWithinParens=Parentheses
190.154 +LBL_spaceWithinMethodDeclParens=Method Declaration
190.155 +LBL_spaceWithinMethodCallParens=Method Call
190.156 +LBL_spaceWithinIfParens="if"
190.157 +LBL_spaceWithinForParens="for"
190.158 +LBL_spaceWithinWhileParens="while"
190.159 +LBL_spaceWithinSwitchParens="switch"
190.160 +LBL_spaceWithinCatchParens="catch"
190.161 +LBL_spaceWithinSynchronizedParens="synchronized"
190.162 +LBL_spaceWithinTypeCastParens=Type Cast
190.163 +LBL_spaceWithinAnnotationParens=Annotation
190.164 +LBL_spaceWithinBraces=Braces
190.165 +LBL_spaceWithinArrayInitBrackets=Array Initializer Brackets
190.166 +
190.167 +LBL_Other=Other
190.168 +LBL_spaceBeforeComma=Before Comma
190.169 +LBL_spaceAfterComma=After Comma
190.170 +LBL_spaceBeforeSemi=Before Semicolon
190.171 +LBL_spaceAfterSemi=After Semicolon
190.172 +LBL_spaceBeforeColon=Before Colon
190.173 +LBL_spaceAfterColon=After Colon
190.174 +LBL_spaceAfterTypeCast=After Type Cast
190.175 +LBL_wrp_extendsImplementsKeyword=&Extends/Implements Keyword\:
190.176 +LBL_wrp_extendsImplementsList=E&xtends/Implements List\:
190.177 +LBL_wrp_methodParameters=Method &Parameters\:
190.178 +LBL_wrp_throwsKeyword=&Throws Keyword\:
190.179 +LBL_wrp_throwsList=Th&rows List\:
190.180 +LBL_wrp_methodCallArgs=Method Call &Arguments\:
190.181 +LBL_wrp_annotationArgs=Annotation Arg&uments\:
190.182 +LBL_wrp_chainedMethodCalls=C&hained Method Calls\:
190.183 +LBL_wrp_arrayInit=Array Initiali&zer\:
190.184 +LBL_wrp_for=&For\:
190.185 +LBL_wrp_forStatement=F&or Statement\:
190.186 +LBL_wrp_ifStatement=&If Statement\:
190.187 +LBL_wrp_whileStatement=&While Statement\:
190.188 +LBL_wrp_doWhileStatement=&Do ... While Statement
190.189 +LBL_wrp_assert=&Assert\:
190.190 +LBL_wrp_enumConstants=Enum &Constants\:
190.191 +LBL_wrp_annotations=A&nnotations\:
190.192 +LBL_wrp_binaryOps=&Binary Operators\:
190.193 +LBL_wrp_ternaryOps=Ternar&y Operators\:
190.194 +LBL_wrp_assignOps=Assi&gnment Operators\:
190.195 +
190.196 +LBL_br_bracesPlacement=Braces Placement
190.197 +LBL_br_bracesGeneration=Braces Generation
190.198 +LBL_al_newLines=New Lines
190.199 +LBL_al_multilineAlignment=Multiline Alignment
190.200 +LBL_nl_Else="&else"
190.201 +LBL_nl_While="w&hile"
190.202 +LBL_nl_Catch="c&atch"
190.203 +LBL_nl_Finally="finall&y"
190.204 +LBL_nl_Modifiers=after modifie&rs
190.205 +LBL_am_MethodParams=Method &Parameters
190.206 +LBL_am_CallArgs=Method Call Arg&uments
190.207 +LBL_am_AnnotationArgs=&Annotation Arguments
190.208 +LBL_an_Implements=I&mplements List
190.209 +LBL_am_Throws=&Throws List
190.210 +LBL_am_Paren=Parenthesize&d
190.211 +LBL_am_BinaryOp=&Binary Operators
190.212 +LBL_am_TernaryOp=Ter&nary Operators
190.213 +LBL_am_Assign=Assi&gnment
190.214 +LBL_am_For=&For
190.215 +LBL_am_ArrayInit=Array Initiali&zer
190.216 +
190.217 +LBL_IndentCasesFromSwitch=Indent Case Statements In &Switch
190.218 +
190.219 +# Following entries (marked) as samples are used as examples in the formating
190.220 +# options. It is highly discourage to localize them unless absolutely necessary.
190.221 +
190.222 +SAMPLE_Default=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC
190.223 +SAMPLE_TabsIndents=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC {
190.224 +SAMPLE_AlignBraces=@Anno(paramA="a Value", paramB="bValue")\n
190.225 +SAMPLE_Wrapping=@Anno(paramA="a Value", paramB="bValue")
190.226 +SAMPLE_BlankLines=package org.netbeans.samples;
190.227 +
190.228 +SAMPLE_Imports=\
190.229 +# Copyright 2008\n\
190.230 +"""My Module"""\n\
190.231 +\n\
190.232 +import sys\n\
190.233 +import wsgiref.handlers\n\
190.234 +from google.appengine.ext.webapp.util import run_wsgi_app\n\
190.235 +from google.appengine.ext import webapp\n\
190.236 +from google.appengine.ext import db\n\
190.237 +import os\n\
190.238 +\n\
190.239 +\n\
190.240 +from google.appengine.api import users\n\
190.241 +import google.appengine.api.test\n\
190.242 +from google.appengine.api import users\n\
190.243 +\n\
190.244 +from google.appengine.api import users\n\
190.245 +from google.appengine.api import users\n\
190.246 +import string\n\
190.247 +from google.appengine.ext.webapp import template as FooBar\n\
190.248 +from google.appengine.ext.webapp.util import login_required\n\
190.249 +import random\n\
190.250 +import datetime\n
190.251 +
190.252 +#\n\
190.253 +#new_str = swapcase("foo")
190.254 +
190.255 +
190.256 +# Newlines on the following line since space prefixes are ignored by the .properties loader
190.257 +SAMPLE_Spaces=\
190.258 +def func( arg1 ,arg2 ,\
190.259 +\n arg3 = 3, arg = 4):\
190.260 +\n\
190.261 +\n if pos!=-1 and optval[ pos-1 ].isspace():\
190.262 +\n x=5+2\
190.263 +\n\
190.264 +\nmodeDict = { 'r':'rb','w':'wb', \\\
190.265 +\n 'a' : 'r+b' }\
190.266 +\nx = 2; y=3 ; z = 5\n
190.267 +
190.268 +
190.269 +nlFinallyCheckBox1.text="finall&y"
190.270 +
190.271 +
190.272 +AN_Preview=Preview
190.273 +AD_Preview=Preview
190.274 +FmtImports.formatImportsCb.text=Organize Imports during formatting
190.275 +FmtImports.removeDuplicateCb.text=Remove Duplicate Imports
190.276 +FmtImports.systemLibsCb.text=Separate out system libraries
190.277 +FmtImports.onePerLineCb.text=Prefer one import per line
190.278 +FmtImports.cleanupLabel.text=Unused imports:
190.279 +FmtImports.preferSymbols.text=Prefer symbol imports
190.280 +FmtImports.sortImportsCb.text=Sort Alphabetically
190.281 +FmtSpaces.addAroundOp.text=Add spaces around operators
190.282 +FmtSpaces.removeInParam.text=But remove in parameter assignments
190.283 +FmtSpaces.removeInParen.text=Remove spaces inside ( ), { }, and [ ]
190.284 +FmtSpaces.addAfterComma.text=Add spaces after commas
190.285 +FmtSpaces.removeBeforeSep.text=Remove spaces before separators ( : , ; )
190.286 +FmtSpaces.collapseSpacesCb.text=Collapse multiple spaces
190.287 +FmtImports.sepFromImpCb.text=Separate "from" and "import" statements
191.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
191.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtAlignment.form Mon Sep 21 13:01:16 2015 +0200
191.3 @@ -0,0 +1,350 @@
191.4 +<?xml version="1.0" encoding="UTF-8" ?>
191.5 +
191.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
191.7 + <Properties>
191.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Alignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.10 + </Property>
191.11 + <Property name="opaque" type="boolean" value="false"/>
191.12 + </Properties>
191.13 + <AuxValues>
191.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
191.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
191.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
191.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
191.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
191.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
191.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
191.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
191.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
191.23 + </AuxValues>
191.24 +
191.25 + <Layout>
191.26 + <DimensionLayout dim="0">
191.27 + <Group type="103" groupAlignment="0" attributes="0">
191.28 + <Group type="102" attributes="0">
191.29 + <Group type="103" groupAlignment="0" attributes="0">
191.30 + <Group type="102" alignment="0" attributes="0">
191.31 + <EmptySpace min="-2" max="-2" attributes="0"/>
191.32 + <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
191.33 + </Group>
191.34 + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
191.35 + <Group type="102" alignment="0" attributes="1">
191.36 + <Component id="newLinesLabel" min="-2" max="-2" attributes="0"/>
191.37 + <EmptySpace max="-2" attributes="0"/>
191.38 + <Component id="jSeparator1" max="32767" attributes="0"/>
191.39 + </Group>
191.40 + <Group type="102" alignment="0" attributes="1">
191.41 + <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
191.42 + <EmptySpace max="-2" attributes="0"/>
191.43 + <Component id="jSeparator2" max="32767" attributes="1"/>
191.44 + </Group>
191.45 + <Group type="102" alignment="0" attributes="0">
191.46 + <EmptySpace max="-2" attributes="0"/>
191.47 + <Group type="103" groupAlignment="0" attributes="0">
191.48 + <Component id="amThrowsCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
191.49 + <Component id="amBinaryOpCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
191.50 + <Component id="amAssignCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
191.51 + <Component id="amAnnotationArgsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
191.52 + <Component id="nlElseCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
191.53 + <Component id="nlWhileCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
191.54 + <Component id="nlCatchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
191.55 + <Component id="amMethodParamsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
191.56 + </Group>
191.57 + <EmptySpace min="-2" max="-2" attributes="0"/>
191.58 + <Group type="103" groupAlignment="0" attributes="0">
191.59 + <Component id="amCallArgsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
191.60 + <Component id="nlModifiersCheckBox" min="-2" max="-2" attributes="0"/>
191.61 + <Component id="nlFinallyCheckBox" min="-2" max="-2" attributes="0"/>
191.62 + <Component id="amImplementsCheckBox1" min="-2" max="-2" attributes="0"/>
191.63 + <Component id="amArrayInitCheckBox1" min="-2" max="-2" attributes="0"/>
191.64 + <Component id="amTernaryOpCheckBox1" min="-2" max="-2" attributes="0"/>
191.65 + <Component id="amForCheckBox1" min="-2" max="-2" attributes="0"/>
191.66 + </Group>
191.67 + </Group>
191.68 + </Group>
191.69 + </Group>
191.70 + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
191.71 + </Group>
191.72 + </Group>
191.73 + </DimensionLayout>
191.74 + <DimensionLayout dim="1">
191.75 + <Group type="103" groupAlignment="0" attributes="0">
191.76 + <Group type="102" alignment="0" attributes="0">
191.77 + <Group type="103" groupAlignment="0" attributes="0">
191.78 + <Group type="102" attributes="0">
191.79 + <EmptySpace max="-2" attributes="0"/>
191.80 + <Component id="newLinesLabel" min="-2" max="-2" attributes="1"/>
191.81 + </Group>
191.82 + <Group type="102" attributes="0">
191.83 + <EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
191.84 + <Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
191.85 + </Group>
191.86 + </Group>
191.87 + <EmptySpace max="-2" attributes="0"/>
191.88 + <Group type="103" groupAlignment="3" attributes="0">
191.89 + <Component id="nlElseCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.90 + <Component id="nlFinallyCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.91 + </Group>
191.92 + <EmptySpace max="-2" attributes="0"/>
191.93 + <Group type="103" groupAlignment="3" attributes="0">
191.94 + <Component id="nlWhileCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.95 + <Component id="nlModifiersCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.96 + </Group>
191.97 + <Group type="103" groupAlignment="0" attributes="0">
191.98 + <Group type="102" attributes="0">
191.99 + <EmptySpace max="-2" attributes="0"/>
191.100 + <Component id="nlCatchCheckBox" min="-2" max="-2" attributes="0"/>
191.101 + <EmptySpace type="separate" max="-2" attributes="0"/>
191.102 + <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
191.103 + </Group>
191.104 + <Group type="102" attributes="0">
191.105 + <EmptySpace min="-2" pref="44" max="-2" attributes="0"/>
191.106 + <Component id="jSeparator2" min="-2" pref="10" max="-2" attributes="0"/>
191.107 + </Group>
191.108 + </Group>
191.109 + <EmptySpace min="-2" max="-2" attributes="0"/>
191.110 + <Group type="103" groupAlignment="3" attributes="0">
191.111 + <Component id="amMethodParamsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.112 + <Component id="amCallArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.113 + </Group>
191.114 + <EmptySpace min="-2" max="-2" attributes="0"/>
191.115 + <Group type="103" groupAlignment="3" attributes="0">
191.116 + <Component id="amAnnotationArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
191.117 + <Component id="amImplementsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.118 + </Group>
191.119 + <EmptySpace max="-2" attributes="0"/>
191.120 + <Group type="103" groupAlignment="3" attributes="0">
191.121 + <Component id="amThrowsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.122 + <Component id="amArrayInitCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.123 + </Group>
191.124 + <EmptySpace max="-2" attributes="0"/>
191.125 + <Group type="103" groupAlignment="3" attributes="0">
191.126 + <Component id="amBinaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.127 + <Component id="amTernaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.128 + </Group>
191.129 + <EmptySpace max="-2" attributes="0"/>
191.130 + <Group type="103" groupAlignment="3" attributes="0">
191.131 + <Component id="amAssignCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.132 + <Component id="amForCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
191.133 + </Group>
191.134 + <EmptySpace min="-2" max="-2" attributes="0"/>
191.135 + <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
191.136 + <EmptySpace max="32767" attributes="0"/>
191.137 + </Group>
191.138 + </Group>
191.139 + </DimensionLayout>
191.140 + </Layout>
191.141 + <SubComponents>
191.142 + <Component class="javax.swing.JLabel" name="newLinesLabel">
191.143 + <Properties>
191.144 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.145 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_newLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.146 + </Property>
191.147 + </Properties>
191.148 + </Component>
191.149 + <Component class="javax.swing.JCheckBox" name="nlElseCheckBox">
191.150 + <Properties>
191.151 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.152 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Else" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.153 + </Property>
191.154 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.155 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.156 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.157 + </Border>
191.158 + </Property>
191.159 + </Properties>
191.160 + </Component>
191.161 + <Component class="javax.swing.JCheckBox" name="nlWhileCheckBox">
191.162 + <Properties>
191.163 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.164 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_While" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.165 + </Property>
191.166 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.167 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.168 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.169 + </Border>
191.170 + </Property>
191.171 + </Properties>
191.172 + </Component>
191.173 + <Component class="javax.swing.JCheckBox" name="nlCatchCheckBox">
191.174 + <Properties>
191.175 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.176 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Catch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.177 + </Property>
191.178 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.179 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.180 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.181 + </Border>
191.182 + </Property>
191.183 + </Properties>
191.184 + </Component>
191.185 + <Component class="javax.swing.JCheckBox" name="nlFinallyCheckBox">
191.186 + <Properties>
191.187 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.188 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Finally" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.189 + </Property>
191.190 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.191 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.192 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.193 + </Border>
191.194 + </Property>
191.195 + </Properties>
191.196 + </Component>
191.197 + <Component class="javax.swing.JCheckBox" name="nlModifiersCheckBox">
191.198 + <Properties>
191.199 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.200 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Modifiers" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.201 + </Property>
191.202 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.203 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.204 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.205 + </Border>
191.206 + </Property>
191.207 + </Properties>
191.208 + </Component>
191.209 + <Component class="javax.swing.JLabel" name="multilineAlignmentLabel">
191.210 + <Properties>
191.211 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.212 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_multilineAlignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.213 + </Property>
191.214 + </Properties>
191.215 + </Component>
191.216 + <Component class="javax.swing.JCheckBox" name="amMethodParamsCheckBox">
191.217 + <Properties>
191.218 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.219 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_MethodParams" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.220 + </Property>
191.221 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.222 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.223 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.224 + </Border>
191.225 + </Property>
191.226 + </Properties>
191.227 + </Component>
191.228 + <Component class="javax.swing.JCheckBox" name="amCallArgsCheckBox">
191.229 + <Properties>
191.230 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.231 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_CallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.232 + </Property>
191.233 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.234 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.235 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.236 + </Border>
191.237 + </Property>
191.238 + </Properties>
191.239 + </Component>
191.240 + <Component class="javax.swing.JCheckBox" name="amAnnotationArgsCheckBox">
191.241 + <Properties>
191.242 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.243 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_AnnotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.244 + </Property>
191.245 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.246 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.247 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.248 + </Border>
191.249 + </Property>
191.250 + </Properties>
191.251 + </Component>
191.252 + <Component class="javax.swing.JCheckBox" name="amImplementsCheckBox1">
191.253 + <Properties>
191.254 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.255 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_an_Implements" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.256 + </Property>
191.257 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.258 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.259 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.260 + </Border>
191.261 + </Property>
191.262 + </Properties>
191.263 + </Component>
191.264 + <Component class="javax.swing.JCheckBox" name="amThrowsCheckBox1">
191.265 + <Properties>
191.266 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.267 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Throws" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.268 + </Property>
191.269 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.270 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.271 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.272 + </Border>
191.273 + </Property>
191.274 + </Properties>
191.275 + </Component>
191.276 + <Component class="javax.swing.JCheckBox" name="amArrayInitCheckBox1">
191.277 + <Properties>
191.278 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.279 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_ArrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.280 + </Property>
191.281 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.282 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.283 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.284 + </Border>
191.285 + </Property>
191.286 + </Properties>
191.287 + </Component>
191.288 + <Component class="javax.swing.JCheckBox" name="amBinaryOpCheckBox1">
191.289 + <Properties>
191.290 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.291 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_BinaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.292 + </Property>
191.293 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.294 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.295 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.296 + </Border>
191.297 + </Property>
191.298 + </Properties>
191.299 + </Component>
191.300 + <Component class="javax.swing.JCheckBox" name="amTernaryOpCheckBox1">
191.301 + <Properties>
191.302 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.303 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_TernaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.304 + </Property>
191.305 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.306 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.307 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.308 + </Border>
191.309 + </Property>
191.310 + </Properties>
191.311 + </Component>
191.312 + <Component class="javax.swing.JCheckBox" name="amAssignCheckBox1">
191.313 + <Properties>
191.314 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.315 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Assign" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.316 + </Property>
191.317 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.318 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.319 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.320 + </Border>
191.321 + </Property>
191.322 + </Properties>
191.323 + </Component>
191.324 + <Component class="javax.swing.JCheckBox" name="amForCheckBox1">
191.325 + <Properties>
191.326 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.327 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_For" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.328 + </Property>
191.329 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.330 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.331 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.332 + </Border>
191.333 + </Property>
191.334 + </Properties>
191.335 + </Component>
191.336 + <Component class="javax.swing.JCheckBox" name="amParenthesizedCheckBox1">
191.337 + <Properties>
191.338 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.339 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Paren" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.340 + </Property>
191.341 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
191.342 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
191.343 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
191.344 + </Border>
191.345 + </Property>
191.346 + </Properties>
191.347 + </Component>
191.348 + <Component class="javax.swing.JSeparator" name="jSeparator1">
191.349 + </Component>
191.350 + <Component class="javax.swing.JSeparator" name="jSeparator2">
191.351 + </Component>
191.352 + </SubComponents>
191.353 +</Form>
192.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
192.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtAlignment.java Mon Sep 21 13:01:16 2015 +0200
192.3 @@ -0,0 +1,309 @@
192.4 +/*
192.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
192.6 + *
192.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
192.8 + *
192.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
192.10 + * Other names may be trademarks of their respective owners.
192.11 + *
192.12 + * The contents of this file are subject to the terms of either the GNU
192.13 + * General Public License Version 2 only ("GPL") or the Common
192.14 + * Development and Distribution License("CDDL") (collectively, the
192.15 + * "License"). You may not use this file except in compliance with the
192.16 + * License. You can obtain a copy of the License at
192.17 + * http://www.netbeans.org/cddl-gplv2.html
192.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
192.19 + * specific language governing permissions and limitations under the
192.20 + * License. When distributing the software, include this License Header
192.21 + * Notice in each file and include the License file at
192.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
192.23 + * particular file as subject to the "Classpath" exception as provided
192.24 + * by Oracle in the GPL Version 2 section of the License file that
192.25 + * accompanied this code. If applicable, add the following below the
192.26 + * License Header, with the fields enclosed by brackets [] replaced by
192.27 + * your own identifying information:
192.28 + * "Portions Copyrighted [year] [name of copyright owner]"
192.29 + *
192.30 + * Contributor(s):
192.31 + *
192.32 + * The Original Software is NetBeans. The Initial Developer of the Original
192.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
192.34 + * Microsystems, Inc. All Rights Reserved.
192.35 + *
192.36 + * If you wish your version of this file to be governed by only the CDDL
192.37 + * or only the GPL Version 2, indicate your decision by adding
192.38 + * "[Contributor] elects to include this software in this distribution
192.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
192.40 + * single choice of license, a recipient has the option to distribute
192.41 + * your version of this file under either the CDDL, the GPL Version 2 or
192.42 + * to extend the choice of license to its licensees as provided above.
192.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
192.44 + * Version 2 license, then the option applies only if the new code is
192.45 + * made subject to such option by the copyright holder.
192.46 + */
192.47 +
192.48 +package org.netbeans.modules.python.source.ui;
192.49 +
192.50 +//import org.netbeans.modules.python.editor.options.CodeStyle.WrapStyle;
192.51 +//import static org.netbeans.modules.python.editor.options.FmtOptions.*;
192.52 +//import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
192.53 +//import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
192.54 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
192.55 +
192.56 +
192.57 +/**
192.58 + *
192.59 + * @author phrebejk
192.60 + */
192.61 +public class FmtAlignment extends javax.swing.JPanel {
192.62 +
192.63 + /** Creates new form FmtAlignment */
192.64 + public FmtAlignment() {
192.65 + initComponents();
192.66 +/*
192.67 + nlElseCheckBox.putClientProperty(OPTION_ID, placeElseOnNewLine);
192.68 + nlWhileCheckBox.putClientProperty(OPTION_ID, placeWhileOnNewLine);
192.69 + nlCatchCheckBox.putClientProperty(OPTION_ID, placeCatchOnNewLine);
192.70 + nlFinallyCheckBox.putClientProperty(OPTION_ID, placeFinallyOnNewLine);
192.71 + nlModifiersCheckBox.putClientProperty(OPTION_ID, placeNewLineAfterModifiers);
192.72 + amMethodParamsCheckBox.putClientProperty(OPTION_ID, alignMultilineMethodParams);
192.73 + amCallArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineCallArgs);
192.74 + amAnnotationArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineAnnotationArgs);
192.75 + amArrayInitCheckBox1.putClientProperty(OPTION_ID, alignMultilineArrayInit);
192.76 + amAssignCheckBox1.putClientProperty(OPTION_ID, alignMultilineAssignment);
192.77 + amBinaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineBinaryOp);
192.78 + amForCheckBox1.putClientProperty(OPTION_ID, alignMultilineFor);
192.79 + amImplementsCheckBox1.putClientProperty(OPTION_ID, alignMultilineImplements);
192.80 + amParenthesizedCheckBox1.putClientProperty(OPTION_ID, alignMultilineParenthesized);
192.81 + amTernaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineTernaryOp);
192.82 + amThrowsCheckBox1.putClientProperty(OPTION_ID, alignMultilineThrows);
192.83 + }
192.84 +
192.85 + public static PreferencesCustomizer.Factory getController() {
192.86 + return new CategorySupport.Factory("alignment", FmtAlignment.class, //NOI18N
192.87 + org.openide.util.NbBundle.getMessage(FmtAlignment.class, "SAMPLE_AlignBraces"), // NOI18N
192.88 + new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
192.89 + new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
192.90 + new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
192.91 + new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
192.92 + new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
192.93 + new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
192.94 + new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
192.95 + new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
192.96 + new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
192.97 + new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
192.98 + new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
192.99 + new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
192.100 + new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
192.101 + new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
192.102 + new String[] { FmtOptions.wrapAnnotationArgs, WrapStyle.WRAP_ALWAYS.name() },
192.103 + new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
192.104 + new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
192.105 + new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
192.106 + new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
192.107 + new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() } );
192.108 + */
192.109 + }
192.110 +
192.111 + /** This method is called from within the constructor to
192.112 + * initialize the form.
192.113 + * WARNING: Do NOT modify this code. The content of this method is
192.114 + * always regenerated by the Form Editor.
192.115 + */
192.116 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
192.117 + private void initComponents() {
192.118 +
192.119 + newLinesLabel = new javax.swing.JLabel();
192.120 + nlElseCheckBox = new javax.swing.JCheckBox();
192.121 + nlWhileCheckBox = new javax.swing.JCheckBox();
192.122 + nlCatchCheckBox = new javax.swing.JCheckBox();
192.123 + nlFinallyCheckBox = new javax.swing.JCheckBox();
192.124 + nlModifiersCheckBox = new javax.swing.JCheckBox();
192.125 + multilineAlignmentLabel = new javax.swing.JLabel();
192.126 + amMethodParamsCheckBox = new javax.swing.JCheckBox();
192.127 + amCallArgsCheckBox = new javax.swing.JCheckBox();
192.128 + amAnnotationArgsCheckBox = new javax.swing.JCheckBox();
192.129 + amImplementsCheckBox1 = new javax.swing.JCheckBox();
192.130 + amThrowsCheckBox1 = new javax.swing.JCheckBox();
192.131 + amArrayInitCheckBox1 = new javax.swing.JCheckBox();
192.132 + amBinaryOpCheckBox1 = new javax.swing.JCheckBox();
192.133 + amTernaryOpCheckBox1 = new javax.swing.JCheckBox();
192.134 + amAssignCheckBox1 = new javax.swing.JCheckBox();
192.135 + amForCheckBox1 = new javax.swing.JCheckBox();
192.136 + amParenthesizedCheckBox1 = new javax.swing.JCheckBox();
192.137 + jSeparator1 = new javax.swing.JSeparator();
192.138 + jSeparator2 = new javax.swing.JSeparator();
192.139 +
192.140 + setName(org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_Alignment")); // NOI18N
192.141 + setOpaque(false);
192.142 +
192.143 + org.openide.awt.Mnemonics.setLocalizedText(newLinesLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_newLines")); // NOI18N
192.144 +
192.145 + org.openide.awt.Mnemonics.setLocalizedText(nlElseCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Else")); // NOI18N
192.146 + nlElseCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.147 +
192.148 + org.openide.awt.Mnemonics.setLocalizedText(nlWhileCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_While")); // NOI18N
192.149 + nlWhileCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.150 +
192.151 + org.openide.awt.Mnemonics.setLocalizedText(nlCatchCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Catch")); // NOI18N
192.152 + nlCatchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.153 +
192.154 + org.openide.awt.Mnemonics.setLocalizedText(nlFinallyCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Finally")); // NOI18N
192.155 + nlFinallyCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.156 +
192.157 + org.openide.awt.Mnemonics.setLocalizedText(nlModifiersCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Modifiers")); // NOI18N
192.158 + nlModifiersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.159 +
192.160 + org.openide.awt.Mnemonics.setLocalizedText(multilineAlignmentLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_multilineAlignment")); // NOI18N
192.161 +
192.162 + org.openide.awt.Mnemonics.setLocalizedText(amMethodParamsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_MethodParams")); // NOI18N
192.163 + amMethodParamsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.164 +
192.165 + org.openide.awt.Mnemonics.setLocalizedText(amCallArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_CallArgs")); // NOI18N
192.166 + amCallArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.167 +
192.168 + org.openide.awt.Mnemonics.setLocalizedText(amAnnotationArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_AnnotationArgs")); // NOI18N
192.169 + amAnnotationArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.170 +
192.171 + org.openide.awt.Mnemonics.setLocalizedText(amImplementsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_an_Implements")); // NOI18N
192.172 + amImplementsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.173 +
192.174 + org.openide.awt.Mnemonics.setLocalizedText(amThrowsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Throws")); // NOI18N
192.175 + amThrowsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.176 +
192.177 + org.openide.awt.Mnemonics.setLocalizedText(amArrayInitCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_ArrayInit")); // NOI18N
192.178 + amArrayInitCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.179 +
192.180 + org.openide.awt.Mnemonics.setLocalizedText(amBinaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_BinaryOp")); // NOI18N
192.181 + amBinaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.182 +
192.183 + org.openide.awt.Mnemonics.setLocalizedText(amTernaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_TernaryOp")); // NOI18N
192.184 + amTernaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.185 +
192.186 + org.openide.awt.Mnemonics.setLocalizedText(amAssignCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Assign")); // NOI18N
192.187 + amAssignCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.188 +
192.189 + org.openide.awt.Mnemonics.setLocalizedText(amForCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_For")); // NOI18N
192.190 + amForCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.191 +
192.192 + org.openide.awt.Mnemonics.setLocalizedText(amParenthesizedCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Paren")); // NOI18N
192.193 + amParenthesizedCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
192.194 +
192.195 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
192.196 + this.setLayout(layout);
192.197 + layout.setHorizontalGroup(
192.198 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.199 + .addGroup(layout.createSequentialGroup()
192.200 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.201 + .addGroup(layout.createSequentialGroup()
192.202 + .addContainerGap()
192.203 + .addComponent(amParenthesizedCheckBox1))
192.204 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
192.205 + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
192.206 + .addComponent(newLinesLabel)
192.207 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.208 + .addComponent(jSeparator1))
192.209 + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
192.210 + .addComponent(multilineAlignmentLabel)
192.211 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.212 + .addComponent(jSeparator2))
192.213 + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
192.214 + .addContainerGap()
192.215 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.216 + .addComponent(amThrowsCheckBox1)
192.217 + .addComponent(amBinaryOpCheckBox1)
192.218 + .addComponent(amAssignCheckBox1)
192.219 + .addComponent(amAnnotationArgsCheckBox)
192.220 + .addComponent(nlElseCheckBox)
192.221 + .addComponent(nlWhileCheckBox)
192.222 + .addComponent(nlCatchCheckBox)
192.223 + .addComponent(amMethodParamsCheckBox))
192.224 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.225 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.226 + .addComponent(amCallArgsCheckBox)
192.227 + .addComponent(nlModifiersCheckBox)
192.228 + .addComponent(nlFinallyCheckBox)
192.229 + .addComponent(amImplementsCheckBox1)
192.230 + .addComponent(amArrayInitCheckBox1)
192.231 + .addComponent(amTernaryOpCheckBox1)
192.232 + .addComponent(amForCheckBox1)))))
192.233 + .addGap(0, 0, 0))
192.234 + );
192.235 + layout.setVerticalGroup(
192.236 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.237 + .addGroup(layout.createSequentialGroup()
192.238 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.239 + .addGroup(layout.createSequentialGroup()
192.240 + .addContainerGap()
192.241 + .addComponent(newLinesLabel))
192.242 + .addGroup(layout.createSequentialGroup()
192.243 + .addGap(17, 17, 17)
192.244 + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
192.245 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.246 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.247 + .addComponent(nlElseCheckBox)
192.248 + .addComponent(nlFinallyCheckBox))
192.249 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.250 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.251 + .addComponent(nlWhileCheckBox)
192.252 + .addComponent(nlModifiersCheckBox))
192.253 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.254 + .addGroup(layout.createSequentialGroup()
192.255 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.256 + .addComponent(nlCatchCheckBox)
192.257 + .addGap(18, 18, 18)
192.258 + .addComponent(multilineAlignmentLabel))
192.259 + .addGroup(layout.createSequentialGroup()
192.260 + .addGap(44, 44, 44)
192.261 + .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
192.262 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.263 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.264 + .addComponent(amMethodParamsCheckBox)
192.265 + .addComponent(amCallArgsCheckBox))
192.266 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.267 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.268 + .addComponent(amAnnotationArgsCheckBox)
192.269 + .addComponent(amImplementsCheckBox1))
192.270 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.271 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.272 + .addComponent(amThrowsCheckBox1)
192.273 + .addComponent(amArrayInitCheckBox1))
192.274 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.275 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.276 + .addComponent(amBinaryOpCheckBox1)
192.277 + .addComponent(amTernaryOpCheckBox1))
192.278 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.279 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.280 + .addComponent(amAssignCheckBox1)
192.281 + .addComponent(amForCheckBox1))
192.282 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.283 + .addComponent(amParenthesizedCheckBox1)
192.284 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
192.285 + );
192.286 + }// </editor-fold>//GEN-END:initComponents
192.287 +
192.288 +
192.289 + // Variables declaration - do not modify//GEN-BEGIN:variables
192.290 + private javax.swing.JCheckBox amAnnotationArgsCheckBox;
192.291 + private javax.swing.JCheckBox amArrayInitCheckBox1;
192.292 + private javax.swing.JCheckBox amAssignCheckBox1;
192.293 + private javax.swing.JCheckBox amBinaryOpCheckBox1;
192.294 + private javax.swing.JCheckBox amCallArgsCheckBox;
192.295 + private javax.swing.JCheckBox amForCheckBox1;
192.296 + private javax.swing.JCheckBox amImplementsCheckBox1;
192.297 + private javax.swing.JCheckBox amMethodParamsCheckBox;
192.298 + private javax.swing.JCheckBox amParenthesizedCheckBox1;
192.299 + private javax.swing.JCheckBox amTernaryOpCheckBox1;
192.300 + private javax.swing.JCheckBox amThrowsCheckBox1;
192.301 + private javax.swing.JSeparator jSeparator1;
192.302 + private javax.swing.JSeparator jSeparator2;
192.303 + private javax.swing.JLabel multilineAlignmentLabel;
192.304 + private javax.swing.JLabel newLinesLabel;
192.305 + private javax.swing.JCheckBox nlCatchCheckBox;
192.306 + private javax.swing.JCheckBox nlElseCheckBox;
192.307 + private javax.swing.JCheckBox nlFinallyCheckBox;
192.308 + private javax.swing.JCheckBox nlModifiersCheckBox;
192.309 + private javax.swing.JCheckBox nlWhileCheckBox;
192.310 + // End of variables declaration//GEN-END:variables
192.311 +
192.312 +}
193.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
193.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtBlankLines.form Mon Sep 21 13:01:16 2015 +0200
193.3 @@ -0,0 +1,284 @@
193.4 +<?xml version="1.0" encoding="UTF-8" ?>
193.5 +
193.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
193.7 + <Properties>
193.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_BlankLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.10 + </Property>
193.11 + <Property name="opaque" type="boolean" value="false"/>
193.12 + </Properties>
193.13 + <AuxValues>
193.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
193.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
193.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
193.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
193.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
193.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
193.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
193.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
193.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
193.23 + </AuxValues>
193.24 +
193.25 + <Layout>
193.26 + <DimensionLayout dim="0">
193.27 + <Group type="103" groupAlignment="0" attributes="0">
193.28 + <Group type="102" attributes="0">
193.29 + <Group type="103" groupAlignment="0" attributes="0">
193.30 + <Component id="bPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.31 + <Component id="aPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.32 + <Component id="bImportsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.33 + <Component id="aImports" alignment="0" min="-2" max="-2" attributes="0"/>
193.34 + <Component id="bClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.35 + <Component id="aClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.36 + <Component id="aClassHeaderLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.37 + <Component id="bFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.38 + <Component id="aFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.39 + <Component id="bMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.40 + <Component id="aMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
193.41 + </Group>
193.42 + <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
193.43 + <Group type="103" groupAlignment="0" attributes="0">
193.44 + <Component id="aMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.45 + <Component id="bMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.46 + <Component id="aFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.47 + <Component id="bFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.48 + <Component id="aClassHeaderField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.49 + <Component id="aClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.50 + <Component id="bClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.51 + <Component id="aImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.52 + <Component id="bImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.53 + <Component id="aPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.54 + <Component id="bPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
193.55 + </Group>
193.56 + </Group>
193.57 + </Group>
193.58 + </DimensionLayout>
193.59 + <DimensionLayout dim="1">
193.60 + <Group type="103" groupAlignment="0" attributes="0">
193.61 + <Group type="102" attributes="0">
193.62 + <Group type="103" groupAlignment="3" attributes="0">
193.63 + <Component id="bPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.64 + <Component id="bPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.65 + </Group>
193.66 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.67 + <Group type="103" groupAlignment="3" attributes="0">
193.68 + <Component id="aPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.69 + <Component id="aPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.70 + </Group>
193.71 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.72 + <Group type="103" groupAlignment="3" attributes="0">
193.73 + <Component id="bImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.74 + <Component id="bImportsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.75 + </Group>
193.76 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.77 + <Group type="103" groupAlignment="3" attributes="0">
193.78 + <Component id="aImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.79 + <Component id="aImports" alignment="3" min="-2" max="-2" attributes="0"/>
193.80 + </Group>
193.81 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.82 + <Group type="103" groupAlignment="3" attributes="0">
193.83 + <Component id="bClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.84 + <Component id="bClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.85 + </Group>
193.86 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.87 + <Group type="103" groupAlignment="3" attributes="0">
193.88 + <Component id="aClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.89 + <Component id="aClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.90 + </Group>
193.91 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.92 + <Group type="103" groupAlignment="3" attributes="0">
193.93 + <Component id="aClassHeaderField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.94 + <Component id="aClassHeaderLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.95 + </Group>
193.96 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.97 + <Group type="103" groupAlignment="3" attributes="0">
193.98 + <Component id="bFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.99 + <Component id="bFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.100 + </Group>
193.101 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.102 + <Group type="103" groupAlignment="3" attributes="0">
193.103 + <Component id="aFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.104 + <Component id="aFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.105 + </Group>
193.106 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.107 + <Group type="103" groupAlignment="3" attributes="0">
193.108 + <Component id="bMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.109 + <Component id="bMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.110 + </Group>
193.111 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
193.112 + <Group type="103" groupAlignment="3" attributes="0">
193.113 + <Component id="aMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
193.114 + <Component id="aMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
193.115 + </Group>
193.116 + </Group>
193.117 + </Group>
193.118 + </DimensionLayout>
193.119 + </Layout>
193.120 + <SubComponents>
193.121 + <Component class="javax.swing.JLabel" name="bPackageLabel">
193.122 + <Properties>
193.123 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.124 + <ComponentRef name="bPackageField"/>
193.125 + </Property>
193.126 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.127 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforePackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.128 + </Property>
193.129 + </Properties>
193.130 + </Component>
193.131 + <Component class="javax.swing.JTextField" name="bPackageField">
193.132 + <Properties>
193.133 + <Property name="columns" type="int" value="5"/>
193.134 + </Properties>
193.135 + </Component>
193.136 + <Component class="javax.swing.JLabel" name="aPackageLabel">
193.137 + <Properties>
193.138 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.139 + <ComponentRef name="aPackageField"/>
193.140 + </Property>
193.141 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.142 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterPackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.143 + </Property>
193.144 + </Properties>
193.145 + </Component>
193.146 + <Component class="javax.swing.JTextField" name="aPackageField">
193.147 + <Properties>
193.148 + <Property name="columns" type="int" value="5"/>
193.149 + </Properties>
193.150 + </Component>
193.151 + <Component class="javax.swing.JLabel" name="bImportsLabel">
193.152 + <Properties>
193.153 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.154 + <ComponentRef name="bImportsField"/>
193.155 + </Property>
193.156 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.157 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.158 + </Property>
193.159 + </Properties>
193.160 + </Component>
193.161 + <Component class="javax.swing.JTextField" name="bImportsField">
193.162 + <Properties>
193.163 + <Property name="columns" type="int" value="5"/>
193.164 + </Properties>
193.165 + </Component>
193.166 + <Component class="javax.swing.JLabel" name="aImports">
193.167 + <Properties>
193.168 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.169 + <ComponentRef name="aImportsField"/>
193.170 + </Property>
193.171 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.172 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.173 + </Property>
193.174 + </Properties>
193.175 + </Component>
193.176 + <Component class="javax.swing.JTextField" name="aImportsField">
193.177 + <Properties>
193.178 + <Property name="columns" type="int" value="5"/>
193.179 + </Properties>
193.180 + </Component>
193.181 + <Component class="javax.swing.JLabel" name="bClassLabel">
193.182 + <Properties>
193.183 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.184 + <ComponentRef name="bClassField"/>
193.185 + </Property>
193.186 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.187 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.188 + </Property>
193.189 + </Properties>
193.190 + </Component>
193.191 + <Component class="javax.swing.JTextField" name="bClassField">
193.192 + <Properties>
193.193 + <Property name="columns" type="int" value="5"/>
193.194 + </Properties>
193.195 + </Component>
193.196 + <Component class="javax.swing.JLabel" name="aClassLabel">
193.197 + <Properties>
193.198 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.199 + <ComponentRef name="aClassField"/>
193.200 + </Property>
193.201 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.202 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.203 + </Property>
193.204 + </Properties>
193.205 + </Component>
193.206 + <Component class="javax.swing.JTextField" name="aClassField">
193.207 + <Properties>
193.208 + <Property name="columns" type="int" value="5"/>
193.209 + </Properties>
193.210 + </Component>
193.211 + <Component class="javax.swing.JLabel" name="aClassHeaderLabel">
193.212 + <Properties>
193.213 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.214 + <ComponentRef name="aClassHeaderField"/>
193.215 + </Property>
193.216 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.217 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClassHeader" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.218 + </Property>
193.219 + </Properties>
193.220 + </Component>
193.221 + <Component class="javax.swing.JTextField" name="aClassHeaderField">
193.222 + <Properties>
193.223 + <Property name="columns" type="int" value="5"/>
193.224 + </Properties>
193.225 + </Component>
193.226 + <Component class="javax.swing.JLabel" name="bFieldsLabel">
193.227 + <Properties>
193.228 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.229 + <ComponentRef name="bFieldsField"/>
193.230 + </Property>
193.231 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.232 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.233 + </Property>
193.234 + </Properties>
193.235 + </Component>
193.236 + <Component class="javax.swing.JTextField" name="bFieldsField">
193.237 + <Properties>
193.238 + <Property name="columns" type="int" value="5"/>
193.239 + </Properties>
193.240 + </Component>
193.241 + <Component class="javax.swing.JLabel" name="aFieldsLabel">
193.242 + <Properties>
193.243 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.244 + <ComponentRef name="aFieldsField"/>
193.245 + </Property>
193.246 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.247 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.248 + </Property>
193.249 + </Properties>
193.250 + </Component>
193.251 + <Component class="javax.swing.JTextField" name="aFieldsField">
193.252 + <Properties>
193.253 + <Property name="columns" type="int" value="5"/>
193.254 + </Properties>
193.255 + </Component>
193.256 + <Component class="javax.swing.JLabel" name="bMethodsLabel">
193.257 + <Properties>
193.258 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.259 + <ComponentRef name="bMethodsField"/>
193.260 + </Property>
193.261 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.262 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.263 + </Property>
193.264 + </Properties>
193.265 + </Component>
193.266 + <Component class="javax.swing.JTextField" name="bMethodsField">
193.267 + <Properties>
193.268 + <Property name="columns" type="int" value="5"/>
193.269 + </Properties>
193.270 + </Component>
193.271 + <Component class="javax.swing.JLabel" name="aMethodsLabel">
193.272 + <Properties>
193.273 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
193.274 + <ComponentRef name="aMethodsField"/>
193.275 + </Property>
193.276 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
193.277 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
193.278 + </Property>
193.279 + </Properties>
193.280 + </Component>
193.281 + <Component class="javax.swing.JTextField" name="aMethodsField">
193.282 + <Properties>
193.283 + <Property name="columns" type="int" value="5"/>
193.284 + </Properties>
193.285 + </Component>
193.286 + </SubComponents>
193.287 +</Form>
194.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
194.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtBlankLines.java Mon Sep 21 13:01:16 2015 +0200
194.3 @@ -0,0 +1,295 @@
194.4 +/*
194.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
194.6 + *
194.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
194.8 + *
194.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
194.10 + * Other names may be trademarks of their respective owners.
194.11 + *
194.12 + * The contents of this file are subject to the terms of either the GNU
194.13 + * General Public License Version 2 only ("GPL") or the Common
194.14 + * Development and Distribution License("CDDL") (collectively, the
194.15 + * "License"). You may not use this file except in compliance with the
194.16 + * License. You can obtain a copy of the License at
194.17 + * http://www.netbeans.org/cddl-gplv2.html
194.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
194.19 + * specific language governing permissions and limitations under the
194.20 + * License. When distributing the software, include this License Header
194.21 + * Notice in each file and include the License file at
194.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
194.23 + * particular file as subject to the "Classpath" exception as provided
194.24 + * by Oracle in the GPL Version 2 section of the License file that
194.25 + * accompanied this code. If applicable, add the following below the
194.26 + * License Header, with the fields enclosed by brackets [] replaced by
194.27 + * your own identifying information:
194.28 + * "Portions Copyrighted [year] [name of copyright owner]"
194.29 + *
194.30 + * Contributor(s):
194.31 + *
194.32 + * The Original Software is NetBeans. The Initial Developer of the Original
194.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
194.34 + * Microsystems, Inc. All Rights Reserved.
194.35 + *
194.36 + * If you wish your version of this file to be governed by only the CDDL
194.37 + * or only the GPL Version 2, indicate your decision by adding
194.38 + * "[Contributor] elects to include this software in this distribution
194.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
194.40 + * single choice of license, a recipient has the option to distribute
194.41 + * your version of this file under either the CDDL, the GPL Version 2 or
194.42 + * to extend the choice of license to its licensees as provided above.
194.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
194.44 + * Version 2 license, then the option applies only if the new code is
194.45 + * made subject to such option by the copyright holder.
194.46 + */
194.47 +
194.48 +package org.netbeans.modules.python.source.ui;
194.49 +
194.50 +//import static org.netbeans.modules.python.editor.options.FmtOptions.*;
194.51 +//import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
194.52 +//import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
194.53 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
194.54 +
194.55 +/**
194.56 + *
194.57 + * @author phrebejk
194.58 + */
194.59 +public class FmtBlankLines extends javax.swing.JPanel {
194.60 +
194.61 + /** Creates new form FmtBlankLines */
194.62 + public FmtBlankLines() {
194.63 + initComponents();
194.64 +/*
194.65 + bPackageField.putClientProperty(OPTION_ID, blankLinesBeforePackage );
194.66 + aPackageField.putClientProperty(OPTION_ID, blankLinesAfterPackage);
194.67 + bImportsField.putClientProperty(OPTION_ID, blankLinesBeforeImports);
194.68 + aImportsField.putClientProperty(OPTION_ID, blankLinesAfterImports);
194.69 + bClassField.putClientProperty(OPTION_ID, blankLinesBeforeClass);
194.70 + aClassField.putClientProperty(OPTION_ID, blankLinesAfterClass);
194.71 + aClassHeaderField.putClientProperty(OPTION_ID, blankLinesAfterClassHeader);
194.72 + bFieldsField.putClientProperty(OPTION_ID, blankLinesBeforeFields);
194.73 + aFieldsField.putClientProperty(OPTION_ID, blankLinesAfterFields);
194.74 + bMethodsField.putClientProperty(OPTION_ID, blankLinesBeforeMethods );
194.75 + aMethodsField.putClientProperty(OPTION_ID, blankLinesAfterMethods);
194.76 +
194.77 + bPackageField.addKeyListener(new NumericKeyListener());
194.78 + aPackageField.addKeyListener(new NumericKeyListener());
194.79 + bImportsField.addKeyListener(new NumericKeyListener());
194.80 + aImportsField.addKeyListener(new NumericKeyListener());
194.81 + bClassField.addKeyListener(new NumericKeyListener());
194.82 + aClassField.addKeyListener(new NumericKeyListener());
194.83 + aClassHeaderField.addKeyListener(new NumericKeyListener());
194.84 + bFieldsField.addKeyListener(new NumericKeyListener());
194.85 + aFieldsField.addKeyListener(new NumericKeyListener());
194.86 + bMethodsField.addKeyListener(new NumericKeyListener());
194.87 + aMethodsField.addKeyListener(new NumericKeyListener());
194.88 +
194.89 + }
194.90 +
194.91 + public static PreferencesCustomizer.Factory getController() {
194.92 + return new CategorySupport.Factory("blank-lines", FmtBlankLines.class, //NOI18N
194.93 + org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "SAMPLE_BlankLines")); // NOI18N
194.94 + */
194.95 + }
194.96 +
194.97 + /** This method is called from within the constructor to
194.98 + * initialize the form.
194.99 + * WARNING: Do NOT modify this code. The content of this method is
194.100 + * always regenerated by the Form Editor.
194.101 + */
194.102 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
194.103 + private void initComponents() {
194.104 +
194.105 + bPackageLabel = new javax.swing.JLabel();
194.106 + bPackageField = new javax.swing.JTextField();
194.107 + aPackageLabel = new javax.swing.JLabel();
194.108 + aPackageField = new javax.swing.JTextField();
194.109 + bImportsLabel = new javax.swing.JLabel();
194.110 + bImportsField = new javax.swing.JTextField();
194.111 + aImports = new javax.swing.JLabel();
194.112 + aImportsField = new javax.swing.JTextField();
194.113 + bClassLabel = new javax.swing.JLabel();
194.114 + bClassField = new javax.swing.JTextField();
194.115 + aClassLabel = new javax.swing.JLabel();
194.116 + aClassField = new javax.swing.JTextField();
194.117 + aClassHeaderLabel = new javax.swing.JLabel();
194.118 + aClassHeaderField = new javax.swing.JTextField();
194.119 + bFieldsLabel = new javax.swing.JLabel();
194.120 + bFieldsField = new javax.swing.JTextField();
194.121 + aFieldsLabel = new javax.swing.JLabel();
194.122 + aFieldsField = new javax.swing.JTextField();
194.123 + bMethodsLabel = new javax.swing.JLabel();
194.124 + bMethodsField = new javax.swing.JTextField();
194.125 + aMethodsLabel = new javax.swing.JLabel();
194.126 + aMethodsField = new javax.swing.JTextField();
194.127 +
194.128 + setName(org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_BlankLines")); // NOI18N
194.129 + setOpaque(false);
194.130 +
194.131 + bPackageLabel.setLabelFor(bPackageField);
194.132 + org.openide.awt.Mnemonics.setLocalizedText(bPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforePackage")); // NOI18N
194.133 +
194.134 + bPackageField.setColumns(5);
194.135 +
194.136 + aPackageLabel.setLabelFor(aPackageField);
194.137 + org.openide.awt.Mnemonics.setLocalizedText(aPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterPackage")); // NOI18N
194.138 +
194.139 + aPackageField.setColumns(5);
194.140 +
194.141 + bImportsLabel.setLabelFor(bImportsField);
194.142 + org.openide.awt.Mnemonics.setLocalizedText(bImportsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeImports")); // NOI18N
194.143 +
194.144 + bImportsField.setColumns(5);
194.145 +
194.146 + aImports.setLabelFor(aImportsField);
194.147 + org.openide.awt.Mnemonics.setLocalizedText(aImports, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterImports")); // NOI18N
194.148 +
194.149 + aImportsField.setColumns(5);
194.150 +
194.151 + bClassLabel.setLabelFor(bClassField);
194.152 + org.openide.awt.Mnemonics.setLocalizedText(bClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeClass")); // NOI18N
194.153 +
194.154 + bClassField.setColumns(5);
194.155 +
194.156 + aClassLabel.setLabelFor(aClassField);
194.157 + org.openide.awt.Mnemonics.setLocalizedText(aClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClass")); // NOI18N
194.158 +
194.159 + aClassField.setColumns(5);
194.160 +
194.161 + aClassHeaderLabel.setLabelFor(aClassHeaderField);
194.162 + org.openide.awt.Mnemonics.setLocalizedText(aClassHeaderLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClassHeader")); // NOI18N
194.163 +
194.164 + aClassHeaderField.setColumns(5);
194.165 +
194.166 + bFieldsLabel.setLabelFor(bFieldsField);
194.167 + org.openide.awt.Mnemonics.setLocalizedText(bFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeFields")); // NOI18N
194.168 +
194.169 + bFieldsField.setColumns(5);
194.170 +
194.171 + aFieldsLabel.setLabelFor(aFieldsField);
194.172 + org.openide.awt.Mnemonics.setLocalizedText(aFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterFields")); // NOI18N
194.173 +
194.174 + aFieldsField.setColumns(5);
194.175 +
194.176 + bMethodsLabel.setLabelFor(bMethodsField);
194.177 + org.openide.awt.Mnemonics.setLocalizedText(bMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeMethods")); // NOI18N
194.178 +
194.179 + bMethodsField.setColumns(5);
194.180 +
194.181 + aMethodsLabel.setLabelFor(aMethodsField);
194.182 + org.openide.awt.Mnemonics.setLocalizedText(aMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterMethods")); // NOI18N
194.183 +
194.184 + aMethodsField.setColumns(5);
194.185 +
194.186 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
194.187 + this.setLayout(layout);
194.188 + layout.setHorizontalGroup(
194.189 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
194.190 + .addGroup(layout.createSequentialGroup()
194.191 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
194.192 + .addComponent(bPackageLabel)
194.193 + .addComponent(aPackageLabel)
194.194 + .addComponent(bImportsLabel)
194.195 + .addComponent(aImports)
194.196 + .addComponent(bClassLabel)
194.197 + .addComponent(aClassLabel)
194.198 + .addComponent(aClassHeaderLabel)
194.199 + .addComponent(bFieldsLabel)
194.200 + .addComponent(aFieldsLabel)
194.201 + .addComponent(bMethodsLabel)
194.202 + .addComponent(aMethodsLabel))
194.203 + .addGap(6, 6, 6)
194.204 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
194.205 + .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.206 + .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.207 + .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.208 + .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.209 + .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.210 + .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.211 + .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.212 + .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.213 + .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.214 + .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.215 + .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
194.216 + );
194.217 +
194.218 + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
194.219 +
194.220 + layout.setVerticalGroup(
194.221 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
194.222 + .addGroup(layout.createSequentialGroup()
194.223 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.224 + .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.225 + .addComponent(bPackageLabel))
194.226 + .addGap(4, 4, 4)
194.227 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.228 + .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.229 + .addComponent(aPackageLabel))
194.230 + .addGap(4, 4, 4)
194.231 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.232 + .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.233 + .addComponent(bImportsLabel))
194.234 + .addGap(4, 4, 4)
194.235 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.236 + .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.237 + .addComponent(aImports))
194.238 + .addGap(4, 4, 4)
194.239 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.240 + .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.241 + .addComponent(bClassLabel))
194.242 + .addGap(4, 4, 4)
194.243 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.244 + .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.245 + .addComponent(aClassLabel))
194.246 + .addGap(4, 4, 4)
194.247 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.248 + .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.249 + .addComponent(aClassHeaderLabel))
194.250 + .addGap(4, 4, 4)
194.251 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.252 + .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.253 + .addComponent(bFieldsLabel))
194.254 + .addGap(4, 4, 4)
194.255 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.256 + .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.257 + .addComponent(aFieldsLabel))
194.258 + .addGap(4, 4, 4)
194.259 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.260 + .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.261 + .addComponent(bMethodsLabel))
194.262 + .addGap(4, 4, 4)
194.263 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
194.264 + .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
194.265 + .addComponent(aMethodsLabel)))
194.266 + );
194.267 +
194.268 + layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
194.269 +
194.270 + }// </editor-fold>//GEN-END:initComponents
194.271 +
194.272 +
194.273 + // Variables declaration - do not modify//GEN-BEGIN:variables
194.274 + private javax.swing.JTextField aClassField;
194.275 + private javax.swing.JTextField aClassHeaderField;
194.276 + private javax.swing.JLabel aClassHeaderLabel;
194.277 + private javax.swing.JLabel aClassLabel;
194.278 + private javax.swing.JTextField aFieldsField;
194.279 + private javax.swing.JLabel aFieldsLabel;
194.280 + private javax.swing.JLabel aImports;
194.281 + private javax.swing.JTextField aImportsField;
194.282 + private javax.swing.JTextField aMethodsField;
194.283 + private javax.swing.JLabel aMethodsLabel;
194.284 + private javax.swing.JTextField aPackageField;
194.285 + private javax.swing.JLabel aPackageLabel;
194.286 + private javax.swing.JTextField bClassField;
194.287 + private javax.swing.JLabel bClassLabel;
194.288 + private javax.swing.JTextField bFieldsField;
194.289 + private javax.swing.JLabel bFieldsLabel;
194.290 + private javax.swing.JTextField bImportsField;
194.291 + private javax.swing.JLabel bImportsLabel;
194.292 + private javax.swing.JTextField bMethodsField;
194.293 + private javax.swing.JLabel bMethodsLabel;
194.294 + private javax.swing.JTextField bPackageField;
194.295 + private javax.swing.JLabel bPackageLabel;
194.296 + // End of variables declaration//GEN-END:variables
194.297 +
194.298 +}
195.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
195.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtImports.form Mon Sep 21 13:01:16 2015 +0200
195.3 @@ -0,0 +1,129 @@
195.4 +<?xml version="1.0" encoding="UTF-8" ?>
195.5 +
195.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
195.7 + <Properties>
195.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Imports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.10 + </Property>
195.11 + </Properties>
195.12 + <AuxValues>
195.13 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
195.14 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
195.15 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
195.16 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
195.17 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
195.18 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
195.19 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
195.20 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
195.21 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
195.22 + </AuxValues>
195.23 +
195.24 + <Layout>
195.25 + <DimensionLayout dim="0">
195.26 + <Group type="103" groupAlignment="0" attributes="0">
195.27 + <Group type="102" attributes="0">
195.28 + <Group type="103" groupAlignment="0" attributes="0">
195.29 + <Component id="formatImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
195.30 + <Component id="onePerLineCb" alignment="0" min="-2" max="-2" attributes="0"/>
195.31 + <Component id="systemLibsCb" alignment="0" min="-2" max="-2" attributes="0"/>
195.32 + <Component id="sortImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
195.33 + <Component id="sepFromImpCb" alignment="0" min="-2" max="-2" attributes="0"/>
195.34 + <Component id="removeDuplicateCb" alignment="0" min="-2" max="-2" attributes="0"/>
195.35 + <Component id="preferSymbols" alignment="0" min="-2" max="-2" attributes="0"/>
195.36 + <Group type="102" alignment="0" attributes="0">
195.37 + <Component id="cleanupLabel" min="-2" max="-2" attributes="0"/>
195.38 + <EmptySpace max="-2" attributes="0"/>
195.39 + <Component id="cleanupCombo" min="-2" max="-2" attributes="0"/>
195.40 + </Group>
195.41 + </Group>
195.42 + <EmptySpace max="32767" attributes="0"/>
195.43 + </Group>
195.44 + </Group>
195.45 + </DimensionLayout>
195.46 + <DimensionLayout dim="1">
195.47 + <Group type="103" groupAlignment="0" attributes="0">
195.48 + <Group type="102" alignment="0" attributes="0">
195.49 + <Component id="formatImportsCb" min="-2" max="-2" attributes="0"/>
195.50 + <EmptySpace type="separate" max="-2" attributes="0"/>
195.51 + <Component id="onePerLineCb" min="-2" max="-2" attributes="0"/>
195.52 + <EmptySpace max="-2" attributes="0"/>
195.53 + <Component id="systemLibsCb" min="-2" max="-2" attributes="0"/>
195.54 + <EmptySpace max="-2" attributes="0"/>
195.55 + <Component id="sortImportsCb" min="-2" max="-2" attributes="0"/>
195.56 + <EmptySpace max="-2" attributes="0"/>
195.57 + <Component id="sepFromImpCb" min="-2" max="-2" attributes="0"/>
195.58 + <EmptySpace max="-2" attributes="0"/>
195.59 + <Component id="removeDuplicateCb" min="-2" max="-2" attributes="0"/>
195.60 + <EmptySpace max="-2" attributes="0"/>
195.61 + <Component id="preferSymbols" min="-2" max="-2" attributes="0"/>
195.62 + <EmptySpace type="separate" max="-2" attributes="0"/>
195.63 + <Group type="103" groupAlignment="3" attributes="0">
195.64 + <Component id="cleanupLabel" alignment="3" min="-2" max="-2" attributes="0"/>
195.65 + <Component id="cleanupCombo" alignment="3" min="-2" max="-2" attributes="0"/>
195.66 + </Group>
195.67 + <EmptySpace max="32767" attributes="0"/>
195.68 + </Group>
195.69 + </Group>
195.70 + </DimensionLayout>
195.71 + </Layout>
195.72 + <SubComponents>
195.73 + <Component class="javax.swing.JCheckBox" name="formatImportsCb">
195.74 + <Properties>
195.75 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.76 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.formatImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.77 + </Property>
195.78 + </Properties>
195.79 + </Component>
195.80 + <Component class="javax.swing.JCheckBox" name="onePerLineCb">
195.81 + <Properties>
195.82 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.83 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.onePerLineCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.84 + </Property>
195.85 + </Properties>
195.86 + </Component>
195.87 + <Component class="javax.swing.JCheckBox" name="systemLibsCb">
195.88 + <Properties>
195.89 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.90 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.systemLibsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.91 + </Property>
195.92 + </Properties>
195.93 + </Component>
195.94 + <Component class="javax.swing.JCheckBox" name="removeDuplicateCb">
195.95 + <Properties>
195.96 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.97 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.removeDuplicateCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.98 + </Property>
195.99 + </Properties>
195.100 + </Component>
195.101 + <Component class="javax.swing.JLabel" name="cleanupLabel">
195.102 + <Properties>
195.103 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.104 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.cleanupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.105 + </Property>
195.106 + </Properties>
195.107 + </Component>
195.108 + <Component class="javax.swing.JComboBox" name="cleanupCombo">
195.109 + </Component>
195.110 + <Component class="javax.swing.JCheckBox" name="preferSymbols">
195.111 + <Properties>
195.112 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.113 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.preferSymbols.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.114 + </Property>
195.115 + </Properties>
195.116 + </Component>
195.117 + <Component class="javax.swing.JCheckBox" name="sortImportsCb">
195.118 + <Properties>
195.119 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.120 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sortImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.121 + </Property>
195.122 + </Properties>
195.123 + </Component>
195.124 + <Component class="javax.swing.JCheckBox" name="sepFromImpCb">
195.125 + <Properties>
195.126 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
195.127 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sepFromImpCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
195.128 + </Property>
195.129 + </Properties>
195.130 + </Component>
195.131 + </SubComponents>
195.132 +</Form>
196.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
196.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtImports.java Mon Sep 21 13:01:16 2015 +0200
196.3 @@ -0,0 +1,169 @@
196.4 +/*
196.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
196.6 + *
196.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
196.8 + *
196.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
196.10 + * Other names may be trademarks of their respective owners.
196.11 + *
196.12 + * The contents of this file are subject to the terms of either the GNU
196.13 + * General Public License Version 2 only ("GPL") or the Common
196.14 + * Development and Distribution License("CDDL") (collectively, the
196.15 + * "License"). You may not use this file except in compliance with the
196.16 + * License. You can obtain a copy of the License at
196.17 + * http://www.netbeans.org/cddl-gplv2.html
196.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
196.19 + * specific language governing permissions and limitations under the
196.20 + * License. When distributing the software, include this License Header
196.21 + * Notice in each file and include the License file at
196.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
196.23 + * particular file as subject to the "Classpath" exception as provided
196.24 + * by Oracle in the GPL Version 2 section of the License file that
196.25 + * accompanied this code. If applicable, add the following below the
196.26 + * License Header, with the fields enclosed by brackets [] replaced by
196.27 + * your own identifying information:
196.28 + * "Portions Copyrighted [year] [name of copyright owner]"
196.29 + *
196.30 + * Contributor(s):
196.31 + *
196.32 + * The Original Software is NetBeans. The Initial Developer of the Original
196.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
196.34 + * Microsystems, Inc. All Rights Reserved.
196.35 + *
196.36 + * If you wish your version of this file to be governed by only the CDDL
196.37 + * or only the GPL Version 2, indicate your decision by adding
196.38 + * "[Contributor] elects to include this software in this distribution
196.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
196.40 + * single choice of license, a recipient has the option to distribute
196.41 + * your version of this file under either the CDDL, the GPL Version 2 or
196.42 + * to extend the choice of license to its licensees as provided above.
196.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
196.44 + * Version 2 license, then the option applies only if the new code is
196.45 + * made subject to such option by the copyright holder.
196.46 + */
196.47 +
196.48 +package org.netbeans.modules.python.source.ui;
196.49 +
196.50 +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
196.51 +import static org.netbeans.modules.python.source.ui.FmtOptions.*;
196.52 +import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
196.53 +
196.54 +/**
196.55 + * Options related to imports
196.56 + *
196.57 + * @author Tor Norbye
196.58 + */
196.59 +public class FmtImports extends javax.swing.JPanel {
196.60 +
196.61 + /** Creates new form FmtImports */
196.62 + public FmtImports() {
196.63 + initComponents();
196.64 +
196.65 + formatImportsCb.putClientProperty(OPTION_ID, formatImports);
196.66 + onePerLineCb.putClientProperty(OPTION_ID, oneImportPerLine);
196.67 + removeDuplicateCb.putClientProperty(OPTION_ID, removeDuplicates);
196.68 + systemLibsCb.putClientProperty(OPTION_ID, systemLibsFirst);
196.69 + cleanupCombo.putClientProperty(OPTION_ID, cleanupUnusedImports);
196.70 + preferSymbols.putClientProperty(OPTION_ID, preferSymbolImports);
196.71 + sortImportsCb.putClientProperty(OPTION_ID, sortImports);
196.72 + sepFromImpCb.putClientProperty(OPTION_ID, separateFromImps);
196.73 + }
196.74 +
196.75 + public static PreferencesCustomizer.Factory getController() {
196.76 + return new CategorySupport.Factory("imports", FmtImports.class,
196.77 + org.openide.util.NbBundle.getMessage(FmtImports.class, "SAMPLE_Imports"));
196.78 + }
196.79 +
196.80 + /** This method is called from within the constructor to
196.81 + * initialize the form.
196.82 + * WARNING: Do NOT modify this code. The content of this method is
196.83 + * always regenerated by the Form Editor.
196.84 + */
196.85 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
196.86 + private void initComponents() {
196.87 +
196.88 + formatImportsCb = new javax.swing.JCheckBox();
196.89 + onePerLineCb = new javax.swing.JCheckBox();
196.90 + systemLibsCb = new javax.swing.JCheckBox();
196.91 + removeDuplicateCb = new javax.swing.JCheckBox();
196.92 + cleanupLabel = new javax.swing.JLabel();
196.93 + cleanupCombo = new javax.swing.JComboBox();
196.94 + preferSymbols = new javax.swing.JCheckBox();
196.95 + sortImportsCb = new javax.swing.JCheckBox();
196.96 + sepFromImpCb = new javax.swing.JCheckBox();
196.97 +
196.98 + setName(org.openide.util.NbBundle.getMessage(FmtImports.class, "LBL_Imports")); // NOI18N
196.99 +
196.100 + org.openide.awt.Mnemonics.setLocalizedText(formatImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.formatImportsCb.text")); // NOI18N
196.101 +
196.102 + org.openide.awt.Mnemonics.setLocalizedText(onePerLineCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.onePerLineCb.text")); // NOI18N
196.103 +
196.104 + org.openide.awt.Mnemonics.setLocalizedText(systemLibsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.systemLibsCb.text")); // NOI18N
196.105 +
196.106 + org.openide.awt.Mnemonics.setLocalizedText(removeDuplicateCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.removeDuplicateCb.text")); // NOI18N
196.107 +
196.108 + org.openide.awt.Mnemonics.setLocalizedText(cleanupLabel, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.cleanupLabel.text")); // NOI18N
196.109 +
196.110 + org.openide.awt.Mnemonics.setLocalizedText(preferSymbols, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.preferSymbols.text")); // NOI18N
196.111 +
196.112 + org.openide.awt.Mnemonics.setLocalizedText(sortImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sortImportsCb.text")); // NOI18N
196.113 +
196.114 + org.openide.awt.Mnemonics.setLocalizedText(sepFromImpCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sepFromImpCb.text")); // NOI18N
196.115 +
196.116 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
196.117 + this.setLayout(layout);
196.118 + layout.setHorizontalGroup(
196.119 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
196.120 + .addGroup(layout.createSequentialGroup()
196.121 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
196.122 + .addComponent(formatImportsCb)
196.123 + .addComponent(onePerLineCb)
196.124 + .addComponent(systemLibsCb)
196.125 + .addComponent(sortImportsCb)
196.126 + .addComponent(sepFromImpCb)
196.127 + .addComponent(removeDuplicateCb)
196.128 + .addComponent(preferSymbols)
196.129 + .addGroup(layout.createSequentialGroup()
196.130 + .addComponent(cleanupLabel)
196.131 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196.132 + .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
196.133 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
196.134 + );
196.135 + layout.setVerticalGroup(
196.136 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
196.137 + .addGroup(layout.createSequentialGroup()
196.138 + .addComponent(formatImportsCb)
196.139 + .addGap(18, 18, 18)
196.140 + .addComponent(onePerLineCb)
196.141 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196.142 + .addComponent(systemLibsCb)
196.143 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196.144 + .addComponent(sortImportsCb)
196.145 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196.146 + .addComponent(sepFromImpCb)
196.147 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196.148 + .addComponent(removeDuplicateCb)
196.149 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196.150 + .addComponent(preferSymbols)
196.151 + .addGap(18, 18, 18)
196.152 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
196.153 + .addComponent(cleanupLabel)
196.154 + .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
196.155 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
196.156 + );
196.157 + }// </editor-fold>//GEN-END:initComponents
196.158 +
196.159 +
196.160 + // Variables declaration - do not modify//GEN-BEGIN:variables
196.161 + private javax.swing.JComboBox cleanupCombo;
196.162 + private javax.swing.JLabel cleanupLabel;
196.163 + private javax.swing.JCheckBox formatImportsCb;
196.164 + private javax.swing.JCheckBox onePerLineCb;
196.165 + private javax.swing.JCheckBox preferSymbols;
196.166 + private javax.swing.JCheckBox removeDuplicateCb;
196.167 + private javax.swing.JCheckBox sepFromImpCb;
196.168 + private javax.swing.JCheckBox sortImportsCb;
196.169 + private javax.swing.JCheckBox systemLibsCb;
196.170 + // End of variables declaration//GEN-END:variables
196.171 +
196.172 +}
197.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
197.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtOptions.java Mon Sep 21 13:01:16 2015 +0200
197.3 @@ -0,0 +1,1036 @@
197.4 +/*
197.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
197.6 + *
197.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
197.8 + *
197.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
197.10 + * Other names may be trademarks of their respective owners.
197.11 + *
197.12 + * The contents of this file are subject to the terms of either the GNU
197.13 + * General Public License Version 2 only ("GPL") or the Common
197.14 + * Development and Distribution License("CDDL") (collectively, the
197.15 + * "License"). You may not use this file except in compliance with the
197.16 + * License. You can obtain a copy of the License at
197.17 + * http://www.netbeans.org/cddl-gplv2.html
197.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
197.19 + * specific language governing permissions and limitations under the
197.20 + * License. When distributing the software, include this License Header
197.21 + * Notice in each file and include the License file at
197.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
197.23 + * particular file as subject to the "Classpath" exception as provided
197.24 + * by Oracle in the GPL Version 2 section of the License file that
197.25 + * accompanied this code. If applicable, add the following below the
197.26 + * License Header, with the fields enclosed by brackets [] replaced by
197.27 + * your own identifying information:
197.28 + * "Portions Copyrighted [year] [name of copyright owner]"
197.29 + *
197.30 + * Contributor(s):
197.31 + *
197.32 + * The Original Software is NetBeans. The Initial Developer of the Original
197.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
197.34 + * Microsystems, Inc. All Rights Reserved.
197.35 + *
197.36 + * If you wish your version of this file to be governed by only the CDDL
197.37 + * or only the GPL Version 2, indicate your decision by adding
197.38 + * "[Contributor] elects to include this software in this distribution
197.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
197.40 + * single choice of license, a recipient has the option to distribute
197.41 + * your version of this file under either the CDDL, the GPL Version 2 or
197.42 + * to extend the choice of license to its licensees as provided above.
197.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
197.44 + * Version 2 license, then the option applies only if the new code is
197.45 + * made subject to such option by the copyright holder.
197.46 + */
197.47 +package org.netbeans.modules.python.source.ui;
197.48 +
197.49 +import org.netbeans.modules.python.source.CodeStyle;
197.50 +import java.awt.Component;
197.51 +import java.awt.Container;
197.52 +import java.awt.Rectangle;
197.53 +import java.awt.event.ActionEvent;
197.54 +import java.awt.event.ActionListener;
197.55 +import java.io.BufferedWriter;
197.56 +import java.io.File;
197.57 +import java.io.FileWriter;
197.58 +import java.io.IOException;
197.59 +import java.util.Arrays;
197.60 +import java.util.HashMap;
197.61 +import java.util.HashSet;
197.62 +import java.util.LinkedList;
197.63 +import java.util.List;
197.64 +import java.util.Map;
197.65 +import java.util.Set;
197.66 +import java.util.prefs.AbstractPreferences;
197.67 +import java.util.prefs.BackingStoreException;
197.68 +import java.util.prefs.Preferences;
197.69 +import javax.swing.ComboBoxModel;
197.70 +import javax.swing.DefaultComboBoxModel;
197.71 +import javax.swing.JCheckBox;
197.72 +import javax.swing.JComboBox;
197.73 +import javax.swing.JComponent;
197.74 +import javax.swing.JEditorPane;
197.75 +import javax.swing.JPanel;
197.76 +import javax.swing.JTextField;
197.77 +import javax.swing.event.DocumentEvent;
197.78 +import javax.swing.event.DocumentListener;
197.79 +import javax.swing.text.BadLocationException;
197.80 +import javax.swing.text.Document;
197.81 +import org.netbeans.api.editor.settings.SimpleValueNames;
197.82 +import static org.netbeans.modules.python.source.CodeStyle.*;
197.83 +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
197.84 +import org.netbeans.modules.options.editor.spi.PreviewProvider;
197.85 +import org.netbeans.modules.python.api.PythonMIMEResolver;
197.86 +import org.netbeans.modules.python.source.PythonFormatter;
197.87 +import org.netbeans.modules.python.source.PythonParserResult;
197.88 +import org.openide.cookies.SaveCookie;
197.89 +import org.openide.filesystems.FileObject;
197.90 +import org.openide.filesystems.FileUtil;
197.91 +import org.openide.loaders.DataObject;
197.92 +import org.openide.loaders.DataObjectNotFoundException;
197.93 +import org.openide.text.CloneableEditorSupport;
197.94 +import org.openide.util.Exceptions;
197.95 +import org.openide.util.HelpCtx;
197.96 +import org.openide.util.NbBundle;
197.97 +
197.98 +/**
197.99 + *
197.100 + * @author phrebejk
197.101 + */
197.102 +public class FmtOptions {
197.103 + public static final String expandTabToSpaces = SimpleValueNames.EXPAND_TABS;
197.104 + public static final String tabSize = SimpleValueNames.TAB_SIZE;
197.105 + public static final String spacesPerTab = SimpleValueNames.SPACES_PER_TAB;
197.106 + public static final String indentSize = SimpleValueNames.INDENT_SHIFT_WIDTH;
197.107 + public static final String continuationIndentSize = "continuationIndentSize"; //NOI18N
197.108 + public static final String labelIndent = "labelIndent"; //NOI18N
197.109 + public static final String absoluteLabelIndent = "absoluteLabelIndent"; //NOI18N
197.110 + public static final String indentTopLevelClassMembers = "indentTopLevelClassMembers"; //NOI18N
197.111 + public static final String indentCasesFromSwitch = "indentCasesFromSwitch"; //NOI18N
197.112 + public static final String rightMargin = SimpleValueNames.TEXT_LIMIT_WIDTH;
197.113 +
197.114 + /*
197.115 + public static final String addLeadingStarInComment = "addLeadingStarInComment"; //NOI18N
197.116 +
197.117 + public static final String preferLongerNames = "preferLongerNames"; //NOI18N
197.118 + public static final String fieldNamePrefix = "fieldNamePrefix"; //NOI18N
197.119 + public static final String fieldNameSuffix = "fieldNameSuffix"; //NOI18N
197.120 + public static final String staticFieldNamePrefix = "staticFieldNamePrefix"; //NOI18N
197.121 + public static final String staticFieldNameSuffix = "staticFieldNameSuffix"; //NOI18N
197.122 + public static final String parameterNamePrefix = "parameterNamePrefix"; //NOI18N
197.123 + public static final String parameterNameSuffix = "parameterNameSuffix"; //NOI18N
197.124 + public static final String localVarNamePrefix = "localVarNamePrefix"; //NOI18N
197.125 + public static final String localVarNameSuffix = "localVarNameSuffix"; //NOI18N
197.126 + public static final String qualifyFieldAccess = "qualifyFieldAccess"; //NOI18N
197.127 + public static final String useIsForBooleanGetters = "useIsForBooleanGetters"; //NOI18N
197.128 + public static final String addOverrideAnnotation = "addOverrideAnnotation"; //NOI18N
197.129 + public static final String makeLocalVarsFinal = "makeLocalVarsFinal"; //NOI18N
197.130 + public static final String makeParametersFinal = "makeParametersFinal"; //NOI18N
197.131 + public static final String classMembersOrder = "classMembersOrder"; //NOI18N
197.132 +
197.133 + public static final String alignMultilineMethodParams = "alignMultilineMethodParams"; //NOI18N
197.134 + public static final String alignMultilineCallArgs = "alignMultilineCallArgs"; //NOI18N
197.135 + public static final String alignMultilineAnnotationArgs = "alignMultilineAnnotationArgs"; //NOI18N
197.136 + public static final String alignMultilineImplements = "alignMultilineImplements"; //NOI18N
197.137 + public static final String alignMultilineThrows = "alignMultilineThrows"; //NOI18N
197.138 + public static final String alignMultilineParenthesized = "alignMultilineParenthesized"; //NOI18N
197.139 + public static final String alignMultilineBinaryOp = "alignMultilineBinaryOp"; //NOI18N
197.140 + public static final String alignMultilineTernaryOp = "alignMultilineTernaryOp"; //NOI18N
197.141 + public static final String alignMultilineAssignment = "alignMultilineAssignment"; //NOI18N
197.142 + public static final String alignMultilineFor = "alignMultilineFor"; //NOI18N
197.143 + public static final String alignMultilineArrayInit = "alignMultilineArrayInit"; //NOI18N
197.144 + public static final String placeElseOnNewLine = "placeElseOnNewLine"; //NOI18N
197.145 + public static final String placeWhileOnNewLine = "placeWhileOnNewLine"; //NOI18N
197.146 + public static final String placeCatchOnNewLine = "placeCatchOnNewLine"; //NOI18N
197.147 + public static final String placeFinallyOnNewLine = "placeFinallyOnNewLine"; //NOI18N
197.148 + public static final String placeNewLineAfterModifiers = "placeNewLineAfterModifiers"; //NOI18N
197.149 +
197.150 + public static final String wrapExtendsImplementsKeyword = "wrapExtendsImplementsKeyword"; //NOI18N
197.151 + public static final String wrapExtendsImplementsList = "wrapExtendsImplementsList"; //NOI18N
197.152 + public static final String wrapMethodParams = "wrapMethodParams"; //NOI18N
197.153 + public static final String wrapThrowsKeyword = "wrapThrowsKeyword"; //NOI18N
197.154 + public static final String wrapThrowsList = "wrapThrowsList"; //NOI18N
197.155 + public static final String wrapMethodCallArgs = "wrapMethodCallArgs"; //NOI18N
197.156 + public static final String wrapAnnotationArgs = "wrapAnnotationArgs"; //NOI18N
197.157 + public static final String wrapChainedMethodCalls = "wrapChainedMethodCalls"; //NOI18N
197.158 + public static final String wrapArrayInit = "wrapArrayInit"; //NOI18N
197.159 + public static final String wrapFor = "wrapFor"; //NOI18N
197.160 + public static final String wrapForStatement = "wrapForStatement"; //NOI18N
197.161 + public static final String wrapIfStatement = "wrapIfStatement"; //NOI18N
197.162 + public static final String wrapWhileStatement = "wrapWhileStatement"; //NOI18N
197.163 + public static final String wrapDoWhileStatement = "wrapDoWhileStatement"; //NOI18N
197.164 + public static final String wrapAssert = "wrapAssert"; //NOI18N
197.165 + public static final String wrapEnumConstants = "wrapEnumConstants"; //NOI18N
197.166 + public static final String wrapAnnotations = "wrapAnnotations"; //NOI18N
197.167 + public static final String wrapBinaryOps = "wrapBinaryOps"; //NOI18N
197.168 + public static final String wrapTernaryOps = "wrapTernaryOps"; //NOI18N
197.169 + public static final String wrapAssignOps = "wrapAssignOps"; //NOI18N
197.170 +
197.171 + public static final String blankLinesBeforePackage = "blankLinesBeforePackage"; //NOI18N
197.172 + public static final String blankLinesAfterPackage = "blankLinesAfterPackage"; //NOI18N
197.173 + public static final String blankLinesBeforeImports = "blankLinesBeforeImports"; //NOI18N
197.174 + public static final String blankLinesAfterImports = "blankLinesAfterImports"; //NOI18N
197.175 + public static final String blankLinesBeforeClass = "blankLinesBeforeClass"; //NOI18N
197.176 + public static final String blankLinesAfterClass = "blankLinesAfterClass"; //NOI18N
197.177 + public static final String blankLinesAfterClassHeader = "blankLinesAfterClassHeader"; //NOI18N
197.178 + public static final String blankLinesBeforeFields = "blankLinesBeforeFields"; //NOI18N
197.179 + public static final String blankLinesAfterFields = "blankLinesAfterFields"; //NOI18N
197.180 + public static final String blankLinesBeforeMethods = "blankLinesBeforeMethods"; //NOI18N
197.181 + public static final String blankLinesAfterMethods = "blankLinesAfterMethods"; //NOI18N
197.182 +
197.183 + public static final String spaceBeforeWhile = "spaceBeforeWhile"; //NOI18N
197.184 + public static final String spaceBeforeElse = "spaceBeforeElse"; //NOI18N
197.185 + public static final String spaceBeforeCatch = "spaceBeforeCatch"; //NOI18N
197.186 + public static final String spaceBeforeFinally = "spaceBeforeFinally"; //NOI18N
197.187 + public static final String spaceBeforeMethodDeclParen = "spaceBeforeMethodDeclParen"; //NOI18N
197.188 + public static final String spaceBeforeMethodCallParen = "spaceBeforeMethodCallParen"; //NOI18N
197.189 + public static final String spaceBeforeIfParen = "spaceBeforeIfParen"; //NOI18N
197.190 + public static final String spaceBeforeForParen = "spaceBeforeForParen"; //NOI18N
197.191 + public static final String spaceBeforeWhileParen = "spaceBeforeWhileParen"; //NOI18N
197.192 + public static final String spaceBeforeCatchParen = "spaceBeforeCatchParen"; //NOI18N
197.193 + public static final String spaceBeforeSwitchParen = "spaceBeforeSwitchParen"; //NOI18N
197.194 + public static final String spaceBeforeSynchronizedParen = "spaceBeforeSynchronizedParen"; //NOI18N
197.195 + public static final String spaceBeforeAnnotationParen = "spaceBeforeAnnotationParen"; //NOI18N
197.196 + public static final String spaceAroundUnaryOps = "spaceAroundUnaryOps"; //NOI18N
197.197 + public static final String spaceAroundBinaryOps = "spaceAroundBinaryOps"; //NOI18N
197.198 + public static final String spaceAroundTernaryOps = "spaceAroundTernaryOps"; //NOI18N
197.199 + public static final String spaceAroundAssignOps = "spaceAroundAssignOps"; //NOI18N
197.200 + public static final String spaceBeforeClassDeclLeftBrace = "spaceBeforeClassDeclLeftBrace"; //NOI18N
197.201 + public static final String spaceBeforeMethodDeclLeftBrace = "spaceBeforeMethodDeclLeftBrace"; //NOI18N
197.202 + public static final String spaceBeforeIfLeftBrace = "spaceBeforeIfLeftBrace"; //NOI18N
197.203 + public static final String spaceBeforeElseLeftBrace = "spaceBeforeElseLeftBrace"; //NOI18N
197.204 + public static final String spaceBeforeWhileLeftBrace = "spaceBeforeWhileLeftBrace"; //NOI18N
197.205 + public static final String spaceBeforeForLeftBrace = "spaceBeforeForLeftBrace"; //NOI18N
197.206 + public static final String spaceBeforeDoLeftBrace = "spaceBeforeDoLeftBrace"; //NOI18N
197.207 + public static final String spaceBeforeSwitchLeftBrace = "spaceBeforeSwitchLeftBrace"; //NOI18N
197.208 + public static final String spaceBeforeTryLeftBrace = "spaceBeforeTryLeftBrace"; //NOI18N
197.209 + public static final String spaceBeforeCatchLeftBrace = "spaceBeforeCatchLeftBrace"; //NOI18N
197.210 + public static final String spaceBeforeFinallyLeftBrace = "spaceBeforeFinallyLeftBrace"; //NOI18N
197.211 + public static final String spaceBeforeSynchronizedLeftBrace = "spaceBeforeSynchronizedLeftBrace"; //NOI18N
197.212 + public static final String spaceBeforeStaticInitLeftBrace = "spaceBeforeStaticInitLeftBrace"; //NOI18N
197.213 + public static final String spaceBeforeArrayInitLeftBrace = "spaceBeforeArrayInitLeftBrace"; //NOI18N
197.214 + public static final String spaceWithinParens = "spaceWithinParens"; //NOI18N
197.215 + public static final String spaceWithinMethodDeclParens = "spaceWithinMethodDeclParens"; //NOI18N
197.216 + public static final String spaceWithinMethodCallParens = "spaceWithinMethodCallParens"; //NOI18N
197.217 + public static final String spaceWithinIfParens = "spaceWithinIfParens"; //NOI18N
197.218 + public static final String spaceWithinForParens = "spaceWithinForParens"; //NOI18N
197.219 + public static final String spaceWithinWhileParens = "spaceWithinWhileParens"; //NOI18N
197.220 + public static final String spaceWithinSwitchParens = "spaceWithinSwitchParens"; //NOI18N
197.221 + public static final String spaceWithinCatchParens = "spaceWithinCatchParens"; //NOI18N
197.222 + public static final String spaceWithinSynchronizedParens = "spaceWithinSynchronizedParens"; //NOI18N
197.223 + public static final String spaceWithinTypeCastParens = "spaceWithinTypeCastParens"; //NOI18N
197.224 + public static final String spaceWithinAnnotationParens = "spaceWithinAnnotationParens"; //NOI18N
197.225 + public static final String spaceWithinBraces = "spaceWithinBraces"; //NOI18N
197.226 + public static final String spaceWithinArrayInitBrackets = "spaceWithinArrayInitBrackets"; //NOI18N
197.227 + public static final String spaceBeforeComma = "spaceBeforeComma"; //NOI18N
197.228 + public static final String spaceAfterComma = "spaceAfterComma"; //NOI18N
197.229 + public static final String spaceBeforeSemi = "spaceBeforeSemi"; //NOI18N
197.230 + public static final String spaceAfterSemi = "spaceAfterSemi"; //NOI18N
197.231 + public static final String spaceBeforeColon = "spaceBeforeColon"; //NOI18N
197.232 + public static final String spaceAfterColon = "spaceAfterColon"; //NOI18N
197.233 + public static final String spaceAfterTypeCast = "spaceAfterTypeCast"; //NOI18N
197.234 + */
197.235 +
197.236 + // Spaces
197.237 + public static final String addSpaceAroundOperators = "spaceAroundOperators"; //NOI18N
197.238 + public static final String removeSpaceInParens = "spaceInsideParens"; //NOI18N
197.239 + public static final String addSpaceAfterComma = "spaceAfterComma"; //NOI18N
197.240 + public static final String removeSpaceBeforeSep = "spaceBeforeSeparator"; //NOI18N
197.241 + public static final String removeSpaceInParamAssign = "spaceInKeywordAssign"; //NOI18N
197.242 + public static final String collapseSpaces = "collapseSpaces"; //NOI18N
197.243 + // Imports
197.244 + public static final String formatImports = "formatImports"; //NOI18N
197.245 + public static final String oneImportPerLine = "oneImportPerLine"; //NOI18N
197.246 + public static final String removeDuplicates = "removeDuplicates"; //NOI18N
197.247 + public static final String systemLibsFirst = "systemLibsFirst"; //NOI18N
197.248 + public static final String cleanupUnusedImports = "cleanupUnusedImports"; //NOI18N
197.249 + public static final String preferSymbolImports = "preferSymbolImports"; //NOI18N
197.250 + public static final String sortImports = "sortImports"; //NOI18N
197.251 + public static final String separateFromImps = "separateFromImps"; //NOI18N
197.252 + public static CodeStyleProducer codeStyleProducer;
197.253 + static final String CODE_STYLE_PROFILE = "CodeStyle"; // NOI18N
197.254 + static final String DEFAULT_PROFILE = "default"; // NOI18N
197.255 + static final String PROJECT_PROFILE = "project"; // NOI18N
197.256 + static final String usedProfile = "usedProfile"; // NOI18N
197.257 +
197.258 + private FmtOptions() {
197.259 + }
197.260 +
197.261 + public static int getDefaultAsInt(String key) {
197.262 + return Integer.parseInt(defaults.get(key));
197.263 + }
197.264 +
197.265 + public static boolean getDefaultAsBoolean(String key) {
197.266 + return Boolean.parseBoolean(defaults.get(key));
197.267 + }
197.268 +
197.269 + public static String getDefaultAsString(String key) {
197.270 + return defaults.get(key);
197.271 + }
197.272 +
197.273 + public static boolean isInteger(String optionID) {
197.274 + String value = defaults.get(optionID);
197.275 +
197.276 + try {
197.277 + Integer.parseInt(value);
197.278 + return true;
197.279 + } catch (NumberFormatException numberFormatException) {
197.280 + return false;
197.281 + }
197.282 + }
197.283 + // Private section ---------------------------------------------------------
197.284 + private static final String TRUE = "true"; // NOI18N
197.285 + private static final String FALSE = "false"; // NOI18N
197.286 + private static final String WRAP_ALWAYS = WrapStyle.WRAP_ALWAYS.name();
197.287 + //private static final String WRAP_IF_LONG = WrapStyle.WRAP_IF_LONG.name();
197.288 + private static final String WRAP_NEVER = WrapStyle.WRAP_NEVER.name();
197.289 +
197.290 + //private static final String CLEANUP_COMMENT = ImportCleanupStyle.COMMENT_OUT.name();
197.291 + private static final String IMP_LEAVE_ALONE = ImportCleanupStyle.LEAVE_ALONE.name();
197.292 + private static Map<String, String> defaults;
197.293 +
197.294 +
197.295 + static {
197.296 + createDefaults();
197.297 + }
197.298 +
197.299 + private static void createDefaults() {
197.300 + String defaultValues[][] = {
197.301 + {expandTabToSpaces, TRUE}, //NOI18N
197.302 + {tabSize, "4"}, //NOI18N
197.303 + {spacesPerTab, "4"}, //NOI18N
197.304 + {indentSize, "4"}, //NOI18N
197.305 + {continuationIndentSize, "8"}, //NOI18N
197.306 + {labelIndent, "0"}, //NOI18N
197.307 + {absoluteLabelIndent, FALSE}, //NOI18N
197.308 + {indentTopLevelClassMembers, TRUE}, //NOI18N
197.309 + {indentCasesFromSwitch, TRUE}, //NOI18N
197.310 + {rightMargin, "80"}, //NOI18N
197.311 +
197.312 + /*
197.313 + { addLeadingStarInComment, TRUE}, //NOI18N
197.314 +
197.315 + { preferLongerNames, TRUE}, //NOI18N
197.316 + { fieldNamePrefix, ""}, //NOI18N // XXX null
197.317 + { fieldNameSuffix, ""}, //NOI18N // XXX null
197.318 + { staticFieldNamePrefix, ""}, //NOI18N // XXX null
197.319 + { staticFieldNameSuffix, ""}, //NOI18N // XXX null
197.320 + { parameterNamePrefix, ""}, //NOI18N // XXX null
197.321 + { parameterNameSuffix, ""}, //NOI18N // XXX null
197.322 + { localVarNamePrefix, ""}, //NOI18N // XXX null
197.323 + { localVarNameSuffix, ""}, //NOI18N // XXX null
197.324 + { qualifyFieldAccess, FALSE}, //NOI18N // XXX
197.325 + { useIsForBooleanGetters, TRUE}, //NOI18N
197.326 + { addOverrideAnnotation, TRUE}, //NOI18N
197.327 + { makeLocalVarsFinal, FALSE}, //NOI18N
197.328 + { makeParametersFinal, FALSE}, //NOI18N
197.329 + { classMembersOrder, ""}, //NOI18N // XXX
197.330 +
197.331 + { alignMultilineMethodParams, FALSE}, //NOI18N
197.332 + { alignMultilineCallArgs, FALSE}, //NOI18N
197.333 + { alignMultilineAnnotationArgs, FALSE}, //NOI18N
197.334 + { alignMultilineImplements, FALSE}, //NOI18N
197.335 + { alignMultilineThrows, FALSE}, //NOI18N
197.336 + { alignMultilineParenthesized, FALSE}, //NOI18N
197.337 + { alignMultilineBinaryOp, FALSE}, //NOI18N
197.338 + { alignMultilineTernaryOp, FALSE}, //NOI18N
197.339 + { alignMultilineAssignment, FALSE}, //NOI18N
197.340 + { alignMultilineFor, FALSE}, //NOI18N
197.341 + { alignMultilineArrayInit, FALSE}, //NOI18N
197.342 + { placeElseOnNewLine, FALSE}, //NOI18N
197.343 + { placeWhileOnNewLine, FALSE}, //NOI18N
197.344 + { placeCatchOnNewLine, FALSE}, //NOI18N
197.345 + { placeFinallyOnNewLine, FALSE}, //NOI18N
197.346 + { placeNewLineAfterModifiers, FALSE}, //NOI18N
197.347 +
197.348 + { wrapExtendsImplementsKeyword, WRAP_NEVER}, //NOI18N
197.349 + { wrapExtendsImplementsList, WRAP_NEVER}, //NOI18N
197.350 + { wrapMethodParams, WRAP_NEVER}, //NOI18N
197.351 + { wrapThrowsKeyword, WRAP_NEVER}, //NOI18N
197.352 + { wrapThrowsList, WRAP_NEVER}, //NOI18N
197.353 + { wrapMethodCallArgs, WRAP_NEVER}, //NOI18N
197.354 + { wrapAnnotationArgs, WRAP_NEVER}, //NOI18N
197.355 + { wrapChainedMethodCalls, WRAP_NEVER}, //NOI18N
197.356 + { wrapArrayInit, WRAP_NEVER}, //NOI18N
197.357 + { wrapFor, WRAP_NEVER}, //NOI18N
197.358 + { wrapForStatement, WRAP_ALWAYS}, //NOI18N
197.359 + { wrapIfStatement, WRAP_ALWAYS}, //NOI18N
197.360 + { wrapWhileStatement, WRAP_ALWAYS}, //NOI18N
197.361 + { wrapDoWhileStatement, WRAP_ALWAYS}, //NOI18N
197.362 + { wrapAssert, WRAP_NEVER}, //NOI18N
197.363 + { wrapEnumConstants, WRAP_NEVER}, //NOI18N
197.364 + { wrapAnnotations, WRAP_ALWAYS}, //NOI18N
197.365 + { wrapBinaryOps, WRAP_NEVER}, //NOI18N
197.366 + { wrapTernaryOps, WRAP_NEVER}, //NOI18N
197.367 + { wrapAssignOps, WRAP_NEVER}, //NOI18N
197.368 +
197.369 + { blankLinesBeforePackage, "0"}, //NOI18N
197.370 + { blankLinesAfterPackage, "1"}, //NOI18N
197.371 + { blankLinesBeforeImports, "1"}, //NOI18N
197.372 + { blankLinesAfterImports, "1"}, //NOI18N
197.373 + { blankLinesBeforeClass, "1"}, //NOI18N
197.374 + { blankLinesAfterClass, "0"}, //NOI18N
197.375 + { blankLinesAfterClassHeader, "1"}, //NOI18N
197.376 + { blankLinesBeforeFields, "0"}, //NOI18N
197.377 + { blankLinesAfterFields, "0"}, //NOI18N
197.378 + { blankLinesBeforeMethods, "1"}, //NOI18N
197.379 + { blankLinesAfterMethods, "0"}, //NOI18N
197.380 +
197.381 + { spaceBeforeWhile, TRUE}, //NOI18N // XXX
197.382 + { spaceBeforeElse, TRUE}, //NOI18N // XXX
197.383 + { spaceBeforeCatch, TRUE}, //NOI18N // XXX
197.384 + { spaceBeforeFinally, TRUE}, //NOI18N // XXX
197.385 + { spaceBeforeMethodDeclParen, FALSE}, //NOI18N
197.386 + { spaceBeforeMethodCallParen, FALSE}, //NOI18N
197.387 + { spaceBeforeIfParen, TRUE}, //NOI18N
197.388 + { spaceBeforeForParen, TRUE}, //NOI18N
197.389 + { spaceBeforeWhileParen, TRUE}, //NOI18N
197.390 + { spaceBeforeCatchParen, TRUE}, //NOI18N
197.391 + { spaceBeforeSwitchParen, TRUE}, //NOI18N
197.392 + { spaceBeforeSynchronizedParen, TRUE}, //NOI18N
197.393 + { spaceBeforeAnnotationParen, FALSE}, //NOI18N
197.394 + { spaceAroundUnaryOps, FALSE}, //NOI18N
197.395 + { spaceAroundBinaryOps, TRUE}, //NOI18N
197.396 + { spaceAroundTernaryOps, TRUE}, //NOI18N
197.397 + { spaceAroundAssignOps, TRUE}, //NOI18N
197.398 + { spaceBeforeClassDeclLeftBrace, TRUE}, //NOI18N
197.399 + { spaceBeforeMethodDeclLeftBrace, TRUE}, //NOI18N
197.400 + { spaceBeforeIfLeftBrace, TRUE}, //NOI18N
197.401 + { spaceBeforeElseLeftBrace, TRUE}, //NOI18N
197.402 + { spaceBeforeWhileLeftBrace, TRUE}, //NOI18N
197.403 + { spaceBeforeForLeftBrace, TRUE}, //NOI18N
197.404 + { spaceBeforeDoLeftBrace, TRUE}, //NOI18N
197.405 + { spaceBeforeSwitchLeftBrace, TRUE}, //NOI18N
197.406 + { spaceBeforeTryLeftBrace, TRUE}, //NOI18N
197.407 + { spaceBeforeCatchLeftBrace, TRUE}, //NOI18N
197.408 + { spaceBeforeFinallyLeftBrace, TRUE}, //NOI18N
197.409 + { spaceBeforeSynchronizedLeftBrace, TRUE}, //NOI18N
197.410 + { spaceBeforeStaticInitLeftBrace, TRUE}, //NOI18N
197.411 + { spaceBeforeArrayInitLeftBrace, FALSE}, //NOI18N
197.412 + { spaceWithinParens, FALSE}, //NOI18N
197.413 + { spaceWithinMethodDeclParens, FALSE}, //NOI18N
197.414 + { spaceWithinMethodCallParens, FALSE}, //NOI18N
197.415 + { spaceWithinIfParens, FALSE}, //NOI18N
197.416 + { spaceWithinForParens, FALSE}, //NOI18N
197.417 + { spaceWithinWhileParens, FALSE}, //NOI18N
197.418 + { spaceWithinSwitchParens, FALSE}, //NOI18N
197.419 + { spaceWithinCatchParens, FALSE}, //NOI18N
197.420 + { spaceWithinSynchronizedParens, FALSE}, //NOI18N
197.421 + { spaceWithinTypeCastParens, FALSE}, //NOI18N
197.422 + { spaceWithinAnnotationParens, FALSE}, //NOI18N
197.423 + { spaceWithinBraces, FALSE}, //NOI18N
197.424 + { spaceWithinArrayInitBrackets, FALSE}, //NOI18N
197.425 + { spaceBeforeComma, FALSE}, //NOI18N
197.426 + { spaceAfterComma, TRUE}, //NOI18N
197.427 + { spaceBeforeSemi, FALSE}, //NOI18N
197.428 + { spaceAfterSemi, TRUE}, //NOI18N
197.429 + { spaceBeforeColon, TRUE}, //NOI18N
197.430 + { spaceAfterColon, TRUE}, //NOI18N
197.431 + { spaceAfterTypeCast, TRUE}, //NOI18N
197.432 + */
197.433 + // Spaces
197.434 + {addSpaceAroundOperators, TRUE},
197.435 + {removeSpaceInParens, TRUE},
197.436 + {addSpaceAfterComma, TRUE},
197.437 + {removeSpaceBeforeSep, TRUE},
197.438 + {removeSpaceInParamAssign, TRUE},
197.439 + {collapseSpaces, TRUE},
197.440 + // Imports
197.441 + {formatImports, TRUE},
197.442 + {oneImportPerLine, TRUE},
197.443 + {removeDuplicates, TRUE},
197.444 + {systemLibsFirst, TRUE},
197.445 + {preferSymbolImports, TRUE},
197.446 + {sortImports, TRUE},
197.447 + {cleanupUnusedImports, IMP_LEAVE_ALONE},
197.448 + {separateFromImps, FALSE},};
197.449 +
197.450 + defaults = new HashMap<>();
197.451 +
197.452 + for (java.lang.String[] strings : defaultValues) {
197.453 + defaults.put(strings[0], strings[1]);
197.454 + }
197.455 +
197.456 + }
197.457 +
197.458 + // Support section ---------------------------------------------------------
197.459 + public static class CategorySupport implements ActionListener, DocumentListener, PreviewProvider, PreferencesCustomizer {
197.460 + public static final String OPTION_ID = "org.netbeans.modules.python.editor.options.FormatingOptions.ID";
197.461 + private static final int LOAD = 0;
197.462 + private static final int STORE = 1;
197.463 + private static final int ADD_LISTENERS = 2;
197.464 + private static final ComboItem wrap[] = new ComboItem[]{
197.465 + new ComboItem(WrapStyle.WRAP_ALWAYS.name(), "LBL_wrp_WRAP_ALWAYS"), // NOI18N
197.466 + new ComboItem(WrapStyle.WRAP_IF_LONG.name(), "LBL_wrp_WRAP_IF_LONG"), // NOI18N
197.467 + new ComboItem(WrapStyle.WRAP_NEVER.name(), "LBL_wrp_WRAP_NEVER") // NOI18N
197.468 + };
197.469 + private static final ComboItem cleanupImports[] = new ComboItem[]{
197.470 + new ComboItem(ImportCleanupStyle.LEAVE_ALONE.name(), "LBL_imp_LEAVE_ALONE"), // NOI18N
197.471 + new ComboItem(ImportCleanupStyle.COMMENT_OUT.name(), "LBL_imp_COMMENT_OUT"), // NOI18N
197.472 + new ComboItem(ImportCleanupStyle.DELETE.name(), "LBL_imp_DELETE") // NOI18N
197.473 + };
197.474 + private final String previewText;
197.475 + private final String id;
197.476 + protected final JPanel panel;
197.477 + private final List<JComponent> components = new LinkedList<>();
197.478 + private JEditorPane previewPane;
197.479 + private final Preferences preferences;
197.480 + private final Preferences previewPrefs;
197.481 +
197.482 + protected CategorySupport(Preferences preferences, String id, JPanel panel, String previewText, String[]... forcedOptions) {
197.483 + this.preferences = preferences;
197.484 + this.id = id;
197.485 + this.panel = panel;
197.486 + this.previewText = previewText != null ? previewText : NbBundle.getMessage(FmtOptions.class, "SAMPLE_Default"); //NOI18N
197.487 +
197.488 + // Scan the panel for its components
197.489 + scan(panel, components);
197.490 +
197.491 + // Initialize the preview preferences
197.492 + Preferences forcedPrefs = new PreviewPreferences();
197.493 + for (String[] option : forcedOptions) {
197.494 + forcedPrefs.put(option[0], option[1]);
197.495 + }
197.496 + this.previewPrefs = new ProxyPreferences(preferences, forcedPrefs);
197.497 +
197.498 + // Load and hook up all the components
197.499 + loadFrom(preferences);
197.500 + addListeners();
197.501 + }
197.502 +
197.503 + protected void addListeners() {
197.504 + scan(ADD_LISTENERS, null);
197.505 + }
197.506 +
197.507 + protected void loadFrom(Preferences preferences) {
197.508 +// loaded = true;
197.509 + scan(LOAD, preferences);
197.510 +// loaded = false;
197.511 + }
197.512 +//
197.513 +// public void applyChanges() {
197.514 +// storeTo(preferences);
197.515 +// }
197.516 +//
197.517 +
197.518 + protected void storeTo(Preferences p) {
197.519 + scan(STORE, p);
197.520 + }
197.521 +
197.522 + protected void notifyChanged() {
197.523 +// if (loaded)
197.524 +// return;
197.525 + storeTo(preferences);
197.526 + refreshPreview();
197.527 + }
197.528 +
197.529 + // ActionListener implementation ---------------------------------------
197.530 + @Override
197.531 + public void actionPerformed(ActionEvent e) {
197.532 + notifyChanged();
197.533 + }
197.534 +
197.535 + // DocumentListener implementation -------------------------------------
197.536 + @Override
197.537 + public void insertUpdate(DocumentEvent e) {
197.538 + notifyChanged();
197.539 + }
197.540 +
197.541 + @Override
197.542 + public void removeUpdate(DocumentEvent e) {
197.543 + notifyChanged();
197.544 + }
197.545 +
197.546 + @Override
197.547 + public void changedUpdate(DocumentEvent e) {
197.548 + notifyChanged();
197.549 + }
197.550 +
197.551 + // PreviewProvider methods -----------------------------------------------------
197.552 + @Override
197.553 + public JComponent getPreviewComponent() {
197.554 + if (previewPane == null) {
197.555 + previewPane = new JEditorPane();
197.556 + previewPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtOptions.class, "AN_Preview")); //NOI18N
197.557 + previewPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtOptions.class, "AD_Preview")); //NOI18N
197.558 + previewPane.putClientProperty("HighlightsLayerIncludes", "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.SyntaxHighlighting$"); //NOI18N
197.559 + previewPane.setEditorKit(CloneableEditorSupport.getEditorKit(PythonMIMEResolver.PYTHON_MIME_TYPE));
197.560 + previewPane.setEditable(false);
197.561 + }
197.562 + return previewPane;
197.563 + }
197.564 +
197.565 + @Override
197.566 + public void refreshPreview() {
197.567 + JEditorPane jep = (JEditorPane)getPreviewComponent();
197.568 + try {
197.569 + int rm = previewPrefs.getInt(rightMargin, getDefaultAsInt(rightMargin));
197.570 + jep.putClientProperty("TextLimitLine", rm); //NOI18N
197.571 + } catch (NumberFormatException e) {
197.572 + // Ignore it
197.573 + }
197.574 + try {
197.575 + Class.forName(CodeStyle.class.getName(), true, CodeStyle.class.getClassLoader());
197.576 + } catch (ClassNotFoundException cnfe) {
197.577 + // ignore
197.578 + }
197.579 +
197.580 + CodeStyle codeStyle = codeStyleProducer.create(previewPrefs);
197.581 + jep.setIgnoreRepaint(true);
197.582 +
197.583 +// if (jep.getDocument() instanceof BaseDocument) {
197.584 +// BaseDocument document = (BaseDocument) jep.getDocument();
197.585 +// final org.netbeans.editor.Formatter f = document.getFormatter();
197.586 +// try {
197.587 +// f.reformatLock();
197.588 +// try {
197.589 +// int reformattedLen = f.reformat(document, 0, document.getLength());
197.590 +// } catch (BadLocationException ex) {
197.591 +// Exceptions.printStackTrace(ex);
197.592 +// }
197.593 +// } finally {
197.594 +// f.reformatUnlock();
197.595 +// }
197.596 +// }
197.597 +
197.598 + // Hacky code to do preview: We want to preview blank text without
197.599 + // a data object... this doesn't work very well so requires some hacks
197.600 + // to create a temp file, format it, then save it and delete it
197.601 + // (to avoid save confirmation dialogs on the modified file etc)
197.602 + PythonFormatter formatter = new PythonFormatter(codeStyle);
197.603 + PythonParserResult info = null;
197.604 + File tmp = null;
197.605 + FileObject tmpFo = null;
197.606 + if (formatter.needsParserResult()) {
197.607 + try {
197.608 + tmp = File.createTempFile("preview", ".py"); // NOI18N
197.609 + BufferedWriter writer = new BufferedWriter(new FileWriter(tmp));
197.610 + writer.write(previewText);
197.611 + writer.close();
197.612 + final FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(tmp));
197.613 + tmpFo = fo;
197.614 + // TODO - I need to get the classpath involved here such that it can
197.615 + // find used/unused libraries
197.616 +// if (!SourceUtils.isScanInProgress()) {
197.617 +// // I'm using custom GSF code here because I want to set up an explicit
197.618 +// // source path for the fake file object which includes the Python
197.619 +// // libraries (since we need them for the isSystemModule lookup
197.620 +// //SourceModel model = SourceModelFactory.getInstance().getModel(fo);
197.621 +// //if (model != null && !model.isScanInProgress()) {
197.622 +// List<FileObject> roots = new ArrayList<FileObject>(new PythonLanguage().getCoreLibraries());
197.623 +//
197.624 +// final PythonPlatformManager manager = PythonPlatformManager.getInstance();
197.625 +// final String platformName = manager.getDefaultPlatform();
197.626 +// PythonPlatform activePlatform = manager.getPlatform(platformName);
197.627 +// if (activePlatform != null) {
197.628 +// roots.addAll(activePlatform.getUniqueLibraryRoots());
197.629 +// ClassPath boot = ClassPathSupport.createClassPath(roots.toArray(new FileObject[roots.size()]));
197.630 +// ClassPath source = ClassPathSupport.createClassPath(new FileObject[]{fo.getParent()});
197.631 +// ClassPath compile = source;
197.632 +//
197.633 +// ClasspathInfo cpInfo = ClasspathInfo.create(boot, compile, source);
197.634 +// Source model = Source.create(cpInfo, fo);
197.635 +// if (model != null) {
197.636 +// final CompilationInfo[] infoHolder = new CompilationInfo[1];
197.637 +// //model.runUserActionTask(new CancellableTask<CompilationInfo>() {
197.638 +// model.runUserActionTask(new CancellableTask<CompilationController>() {
197.639 +// public void cancel() {
197.640 +// }
197.641 +//
197.642 +// //public void run(CompilationInfo info) throws Exception {
197.643 +// public void run(CompilationController info) throws Exception {
197.644 +// info.toPhase(Phase.RESOLVED);
197.645 +// infoHolder[0] = info;
197.646 +// // Force open so info.getFileObject will succeed
197.647 +// GsfUtilities.getDocument(fo, true);
197.648 +// }
197.649 +// }, false);
197.650 +// info = infoHolder[0];
197.651 +// }
197.652 +// }
197.653 +// }
197.654 + } catch (IOException ex) {
197.655 + Exceptions.printStackTrace(ex);
197.656 + }
197.657 + }
197.658 + try {
197.659 + if (info != null && info.getSnapshot().getSource().getDocument(false) != null) {
197.660 + Document doc = info.getSnapshot().getSource().getDocument(false);
197.661 + formatter.reformat(null, doc, 0, doc.getLength(), info);
197.662 + jep.setText(doc.getText(0, doc.getLength()));
197.663 + // Save file to avoid warning on exit
197.664 + DataObject dobj = DataObject.find(info.getSnapshot().getSource().getFileObject());
197.665 + SaveCookie cookie = dobj.getCookie(SaveCookie.class);
197.666 + if (cookie != null) {
197.667 + cookie.save();
197.668 + }
197.669 + } else {
197.670 + Document doc = jep.getDocument();
197.671 + if (doc.getLength() > 0) {
197.672 + doc.remove(0, doc.getLength());
197.673 + }
197.674 + doc.insertString(0, previewText, null);
197.675 + formatter.reformat(null, doc, 0, doc.getLength(), null);
197.676 + jep.setText(doc.getText(0, doc.getLength()));
197.677 + }
197.678 + } catch (DataObjectNotFoundException dof) {
197.679 + Exceptions.printStackTrace(dof);
197.680 + } catch (IOException | BadLocationException ioe) {
197.681 + Exceptions.printStackTrace(ioe);
197.682 + }
197.683 +
197.684 + if (tmpFo != null) {
197.685 + try {
197.686 + tmpFo.delete();
197.687 + } catch (IOException ex) {
197.688 + Exceptions.printStackTrace(ex);
197.689 + }
197.690 + } else if (tmp != null) {
197.691 + tmp.delete();
197.692 + }
197.693 +
197.694 +
197.695 + jep.setIgnoreRepaint(false);
197.696 + jep.scrollRectToVisible(new Rectangle(0, 0, 10, 10));
197.697 + jep.repaint(100);
197.698 + }
197.699 +
197.700 + // PreferencesCustomizer implementation --------------------------------
197.701 + @Override
197.702 + public JComponent getComponent() {
197.703 + return panel;
197.704 + }
197.705 +
197.706 + @Override
197.707 + public String getDisplayName() {
197.708 + return panel.getName();
197.709 + }
197.710 +
197.711 + @Override
197.712 + public String getId() {
197.713 + return id;
197.714 + }
197.715 +
197.716 + @Override
197.717 + public HelpCtx getHelpCtx() {
197.718 + return null;
197.719 + }
197.720 +
197.721 + // PreferencesCustomizer.Factory implementation ------------------------
197.722 + public static final class Factory implements PreferencesCustomizer.Factory {
197.723 + private final String id;
197.724 + private final Class<? extends JPanel> panelClass;
197.725 + private final String previewText;
197.726 + private final String[][] forcedOptions;
197.727 +
197.728 + public Factory(String id, Class<? extends JPanel> panelClass, String previewText, String[]... forcedOptions) {
197.729 + this.id = id;
197.730 + this.panelClass = panelClass;
197.731 + this.previewText = previewText;
197.732 + this.forcedOptions = forcedOptions;
197.733 + }
197.734 +
197.735 + @Override
197.736 + public PreferencesCustomizer create(Preferences preferences) {
197.737 + try {
197.738 + return new CategorySupport(preferences, id, panelClass.newInstance(), previewText, forcedOptions);
197.739 + } catch (IllegalAccessException | InstantiationException e) {
197.740 + return null;
197.741 + }
197.742 + }
197.743 + } // End of CategorySupport.Factory class
197.744 +
197.745 + // Private methods -----------------------------------------------------
197.746 + private void performOperation(int operation, JComponent jc, String optionID, Preferences p) {
197.747 + switch (operation) {
197.748 + case LOAD:
197.749 + loadData(jc, optionID, p);
197.750 + break;
197.751 + case STORE:
197.752 + storeData(jc, optionID, p);
197.753 + break;
197.754 + case ADD_LISTENERS:
197.755 + addListener(jc);
197.756 + break;
197.757 + }
197.758 + }
197.759 +
197.760 + private void scan(int what, Preferences p) {
197.761 + for (JComponent jc : components) {
197.762 + Object o = jc.getClientProperty(OPTION_ID);
197.763 + if (o instanceof String) {
197.764 + performOperation(what, jc, (String)o, p);
197.765 + } else if (o instanceof String[]) {
197.766 + for (String oid : (String[])o) {
197.767 + performOperation(what, jc, oid, p);
197.768 + }
197.769 + }
197.770 + }
197.771 + }
197.772 +
197.773 + private void scan(Container container, List<JComponent> components) {
197.774 + for (Component c : container.getComponents()) {
197.775 + if (c instanceof JComponent) {
197.776 + JComponent jc = (JComponent)c;
197.777 + Object o = jc.getClientProperty(OPTION_ID);
197.778 + if (o instanceof String || o instanceof String[]) {
197.779 + components.add(jc);
197.780 + }
197.781 + }
197.782 + if (c instanceof Container) {
197.783 + scan((Container)c, components);
197.784 + }
197.785 + }
197.786 + }
197.787 +
197.788 + /** Very smart method which tries to set the values in the components correctly
197.789 + */
197.790 + private void loadData(JComponent jc, String optionID, Preferences node) {
197.791 +
197.792 + if (jc instanceof JTextField) {
197.793 + JTextField field = (JTextField)jc;
197.794 + field.setText(node.get(optionID, getDefaultAsString(optionID)));
197.795 + } else if (jc instanceof JCheckBox) {
197.796 + JCheckBox checkBox = (JCheckBox)jc;
197.797 + boolean df = getDefaultAsBoolean(optionID);
197.798 + checkBox.setSelected(node.getBoolean(optionID, df));
197.799 + } else if (jc instanceof JComboBox) {
197.800 + JComboBox cb = (JComboBox)jc;
197.801 + String value = node.get(optionID, getDefaultAsString(optionID));
197.802 + ComboBoxModel model = createModel(value);
197.803 + cb.setModel(model);
197.804 + ComboItem item = whichItem(value, model);
197.805 + cb.setSelectedItem(item);
197.806 + }
197.807 +
197.808 + }
197.809 +
197.810 + private void storeData(JComponent jc, String optionID, Preferences node) {
197.811 +
197.812 + if (jc instanceof JTextField) {
197.813 + JTextField field = (JTextField)jc;
197.814 +
197.815 + String text = field.getText();
197.816 +
197.817 + // XXX test for numbers
197.818 + if (isInteger(optionID)) {
197.819 + try {
197.820 + int i = Integer.parseInt(text);
197.821 + } catch (NumberFormatException e) {
197.822 + return;
197.823 + }
197.824 + }
197.825 +
197.826 + // XXX: watch out, tabSize, spacesPerTab, indentSize and expandTabToSpaces
197.827 + // fall back on getGlopalXXX() values and not getDefaultAsXXX value,
197.828 + // which is why we must not remove them. Proper solution would be to
197.829 + // store formatting preferences to MimeLookup and not use NbPreferences.
197.830 + // The problem currently is that MimeLookup based Preferences do not support subnodes.
197.831 + if (!optionID.equals(tabSize) &&
197.832 + !optionID.equals(spacesPerTab) && !optionID.equals(indentSize) &&
197.833 + getDefaultAsString(optionID).equals(text)) {
197.834 + node.remove(optionID);
197.835 + } else {
197.836 + node.put(optionID, text);
197.837 + }
197.838 + } else if (jc instanceof JCheckBox) {
197.839 + JCheckBox checkBox = (JCheckBox)jc;
197.840 + if (!optionID.equals(expandTabToSpaces) && getDefaultAsBoolean(optionID) == checkBox.isSelected()) {
197.841 + node.remove(optionID);
197.842 + } else {
197.843 + node.putBoolean(optionID, checkBox.isSelected());
197.844 + }
197.845 + } else if (jc instanceof JComboBox) {
197.846 + JComboBox cb = (JComboBox)jc;
197.847 + // Logger.global.info( cb.getSelectedItem() + " " + optionID);
197.848 + String value = ((ComboItem)cb.getSelectedItem()).value;
197.849 + if (getDefaultAsString(optionID).equals(value)) {
197.850 + node.remove(optionID);
197.851 + } else {
197.852 + node.put(optionID, value);
197.853 + }
197.854 + }
197.855 + }
197.856 +
197.857 + private void addListener(JComponent jc) {
197.858 + if (jc instanceof JTextField) {
197.859 + JTextField field = (JTextField)jc;
197.860 + field.addActionListener(this);
197.861 + field.getDocument().addDocumentListener(this);
197.862 + } else if (jc instanceof JCheckBox) {
197.863 + JCheckBox checkBox = (JCheckBox)jc;
197.864 + checkBox.addActionListener(this);
197.865 + } else if (jc instanceof JComboBox) {
197.866 + JComboBox cb = (JComboBox)jc;
197.867 + cb.addActionListener(this);
197.868 + }
197.869 + }
197.870 +
197.871 + private ComboBoxModel createModel(String value) {
197.872 +
197.873 + // is it imports?
197.874 + for (ComboItem comboItem : cleanupImports) {
197.875 + if (value.equals(comboItem.value)) {
197.876 + return new DefaultComboBoxModel(cleanupImports);
197.877 + }
197.878 + }
197.879 +
197.880 + // is it wrap
197.881 + for (ComboItem comboItem : wrap) {
197.882 + if (value.equals(comboItem.value)) {
197.883 + return new DefaultComboBoxModel(wrap);
197.884 + }
197.885 + }
197.886 +
197.887 + return null;
197.888 + }
197.889 +
197.890 + private static ComboItem whichItem(String value, ComboBoxModel model) {
197.891 +
197.892 + for (int i = 0; i < model.getSize(); i++) {
197.893 + ComboItem item = (ComboItem)model.getElementAt(i);
197.894 + if (value.equals(item.value)) {
197.895 + return item;
197.896 + }
197.897 + }
197.898 + return null;
197.899 + }
197.900 +
197.901 + private static class ComboItem {
197.902 + String value;
197.903 + String displayName;
197.904 +
197.905 + public ComboItem(String value, String key) {
197.906 + this.value = value;
197.907 + this.displayName = NbBundle.getMessage(FmtOptions.class, key);
197.908 + }
197.909 +
197.910 + @Override
197.911 + public String toString() {
197.912 + return displayName;
197.913 + }
197.914 + }
197.915 + }
197.916 +
197.917 + public static class PreviewPreferences extends AbstractPreferences {
197.918 + private Map<String, Object> map = new HashMap<>();
197.919 +
197.920 + public PreviewPreferences() {
197.921 + super(null, ""); // NOI18N
197.922 + }
197.923 +
197.924 + @Override
197.925 + protected void putSpi(String key, String value) {
197.926 + map.put(key, value);
197.927 + }
197.928 +
197.929 + @Override
197.930 + protected String getSpi(String key) {
197.931 + return (String)map.get(key);
197.932 + }
197.933 +
197.934 + @Override
197.935 + protected void removeSpi(String key) {
197.936 + map.remove(key);
197.937 + }
197.938 +
197.939 + @Override
197.940 + protected void removeNodeSpi() throws BackingStoreException {
197.941 + throw new UnsupportedOperationException("Not supported yet.");
197.942 + }
197.943 +
197.944 + @Override
197.945 + protected String[] keysSpi() throws BackingStoreException {
197.946 + String array[] = new String[map.keySet().size()];
197.947 + return map.keySet().toArray(array);
197.948 + }
197.949 +
197.950 + @Override
197.951 + protected String[] childrenNamesSpi() throws BackingStoreException {
197.952 + throw new UnsupportedOperationException("Not supported yet.");
197.953 + }
197.954 +
197.955 + @Override
197.956 + protected AbstractPreferences childSpi(String name) {
197.957 + throw new UnsupportedOperationException("Not supported yet.");
197.958 + }
197.959 +
197.960 + @Override
197.961 + protected void syncSpi() throws BackingStoreException {
197.962 + throw new UnsupportedOperationException("Not supported yet.");
197.963 + }
197.964 +
197.965 + @Override
197.966 + protected void flushSpi() throws BackingStoreException {
197.967 + throw new UnsupportedOperationException("Not supported yet.");
197.968 + }
197.969 + }
197.970 +
197.971 + // read-only, no subnodes
197.972 + public static final class ProxyPreferences extends AbstractPreferences {
197.973 + private final Preferences[] delegates;
197.974 +
197.975 + public ProxyPreferences(Preferences... delegates) {
197.976 + super(null, ""); // NOI18N
197.977 + this.delegates = delegates;
197.978 + }
197.979 +
197.980 + @Override
197.981 + protected void putSpi(String key, String value) {
197.982 + throw new UnsupportedOperationException("Not supported yet.");
197.983 + }
197.984 +
197.985 + @Override
197.986 + protected String getSpi(String key) {
197.987 + for (Preferences p : delegates) {
197.988 + String value = p.get(key, null);
197.989 + if (value != null) {
197.990 + return value;
197.991 + }
197.992 + }
197.993 + return null;
197.994 + }
197.995 +
197.996 + @Override
197.997 + protected void removeSpi(String key) {
197.998 + throw new UnsupportedOperationException("Not supported yet.");
197.999 + }
197.1000 +
197.1001 + @Override
197.1002 + protected void removeNodeSpi() throws BackingStoreException {
197.1003 + throw new UnsupportedOperationException("Not supported yet.");
197.1004 + }
197.1005 +
197.1006 + @Override
197.1007 + protected String[] keysSpi() throws BackingStoreException {
197.1008 + Set<String> keys = new HashSet<>();
197.1009 + for (Preferences p : delegates) {
197.1010 + keys.addAll(Arrays.asList(p.keys()));
197.1011 + }
197.1012 + return keys.toArray(new String[keys.size()]);
197.1013 + }
197.1014 +
197.1015 + @Override
197.1016 + protected String[] childrenNamesSpi() throws BackingStoreException {
197.1017 + throw new UnsupportedOperationException("Not supported yet.");
197.1018 + }
197.1019 +
197.1020 + @Override
197.1021 + protected AbstractPreferences childSpi(String name) {
197.1022 + throw new UnsupportedOperationException("Not supported yet.");
197.1023 + }
197.1024 +
197.1025 + @Override
197.1026 + protected void syncSpi() throws BackingStoreException {
197.1027 + throw new UnsupportedOperationException("Not supported yet.");
197.1028 + }
197.1029 +
197.1030 + @Override
197.1031 + protected void flushSpi() throws BackingStoreException {
197.1032 + throw new UnsupportedOperationException("Not supported yet.");
197.1033 + }
197.1034 + } // End of ProxyPreferences class
197.1035 +
197.1036 + public static interface CodeStyleProducer {
197.1037 + public CodeStyle create(Preferences preferences);
197.1038 + }
197.1039 +}
198.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
198.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtSpaces.form Mon Sep 21 13:01:16 2015 +0200
198.3 @@ -0,0 +1,104 @@
198.4 +<?xml version="1.0" encoding="UTF-8" ?>
198.5 +
198.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
198.7 + <Properties>
198.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Spaces" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.10 + </Property>
198.11 + <Property name="opaque" type="boolean" value="false"/>
198.12 + </Properties>
198.13 + <AuxValues>
198.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
198.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
198.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
198.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
198.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
198.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
198.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
198.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
198.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
198.23 + </AuxValues>
198.24 +
198.25 + <Layout>
198.26 + <DimensionLayout dim="0">
198.27 + <Group type="103" groupAlignment="0" attributes="0">
198.28 + <Group type="102" attributes="0">
198.29 + <Group type="103" groupAlignment="0" attributes="0">
198.30 + <Component id="addAroundOp" alignment="0" min="-2" max="-2" attributes="0"/>
198.31 + <Group type="102" alignment="0" attributes="0">
198.32 + <EmptySpace min="27" pref="27" max="27" attributes="0"/>
198.33 + <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
198.34 + </Group>
198.35 + <Component id="removeInParen" alignment="0" min="-2" max="-2" attributes="0"/>
198.36 + <Component id="addAfterComma" alignment="0" min="-2" max="-2" attributes="0"/>
198.37 + <Component id="removeBeforeSep" alignment="0" min="-2" max="-2" attributes="0"/>
198.38 + <Component id="collapseSpacesCb" alignment="0" min="-2" max="-2" attributes="0"/>
198.39 + </Group>
198.40 + <EmptySpace max="32767" attributes="0"/>
198.41 + </Group>
198.42 + </Group>
198.43 + </DimensionLayout>
198.44 + <DimensionLayout dim="1">
198.45 + <Group type="103" groupAlignment="0" attributes="0">
198.46 + <Group type="102" alignment="0" attributes="0">
198.47 + <Component id="addAroundOp" min="-2" max="-2" attributes="0"/>
198.48 + <EmptySpace max="-2" attributes="0"/>
198.49 + <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
198.50 + <EmptySpace max="-2" attributes="0"/>
198.51 + <Component id="removeInParen" min="-2" max="-2" attributes="0"/>
198.52 + <EmptySpace max="-2" attributes="0"/>
198.53 + <Component id="addAfterComma" min="-2" max="-2" attributes="0"/>
198.54 + <EmptySpace max="-2" attributes="0"/>
198.55 + <Component id="removeBeforeSep" min="-2" max="-2" attributes="0"/>
198.56 + <EmptySpace max="-2" attributes="0"/>
198.57 + <Component id="collapseSpacesCb" min="-2" max="-2" attributes="0"/>
198.58 + <EmptySpace max="32767" attributes="0"/>
198.59 + </Group>
198.60 + </Group>
198.61 + </DimensionLayout>
198.62 + </Layout>
198.63 + <SubComponents>
198.64 + <Component class="javax.swing.JCheckBox" name="addAroundOp">
198.65 + <Properties>
198.66 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.67 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAroundOp.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.68 + </Property>
198.69 + </Properties>
198.70 + </Component>
198.71 + <Component class="javax.swing.JCheckBox" name="removeInParam">
198.72 + <Properties>
198.73 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.74 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParam.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.75 + </Property>
198.76 + </Properties>
198.77 + </Component>
198.78 + <Component class="javax.swing.JCheckBox" name="removeInParen">
198.79 + <Properties>
198.80 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.81 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.82 + </Property>
198.83 + </Properties>
198.84 + </Component>
198.85 + <Component class="javax.swing.JCheckBox" name="addAfterComma">
198.86 + <Properties>
198.87 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.88 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAfterComma.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.89 + </Property>
198.90 + </Properties>
198.91 + </Component>
198.92 + <Component class="javax.swing.JCheckBox" name="removeBeforeSep">
198.93 + <Properties>
198.94 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.95 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeBeforeSep.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.96 + </Property>
198.97 + </Properties>
198.98 + </Component>
198.99 + <Component class="javax.swing.JCheckBox" name="collapseSpacesCb">
198.100 + <Properties>
198.101 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.102 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.collapseSpacesCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.103 + </Property>
198.104 + </Properties>
198.105 + </Component>
198.106 + </SubComponents>
198.107 +</Form>
199.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
199.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtSpaces.java Mon Sep 21 13:01:16 2015 +0200
199.3 @@ -0,0 +1,143 @@
199.4 +/*
199.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
199.6 + *
199.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
199.8 + *
199.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
199.10 + * Other names may be trademarks of their respective owners.
199.11 + *
199.12 + * The contents of this file are subject to the terms of either the GNU
199.13 + * General Public License Version 2 only ("GPL") or the Common
199.14 + * Development and Distribution License("CDDL") (collectively, the
199.15 + * "License"). You may not use this file except in compliance with the
199.16 + * License. You can obtain a copy of the License at
199.17 + * http://www.netbeans.org/cddl-gplv2.html
199.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
199.19 + * specific language governing permissions and limitations under the
199.20 + * License. When distributing the software, include this License Header
199.21 + * Notice in each file and include the License file at
199.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
199.23 + * particular file as subject to the "Classpath" exception as provided
199.24 + * by Oracle in the GPL Version 2 section of the License file that
199.25 + * accompanied this code. If applicable, add the following below the
199.26 + * License Header, with the fields enclosed by brackets [] replaced by
199.27 + * your own identifying information:
199.28 + * "Portions Copyrighted [year] [name of copyright owner]"
199.29 + *
199.30 + * Contributor(s):
199.31 + *
199.32 + * The Original Software is NetBeans. The Initial Developer of the Original
199.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
199.34 + * Microsystems, Inc. All Rights Reserved.
199.35 + *
199.36 + * If you wish your version of this file to be governed by only the CDDL
199.37 + * or only the GPL Version 2, indicate your decision by adding
199.38 + * "[Contributor] elects to include this software in this distribution
199.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
199.40 + * single choice of license, a recipient has the option to distribute
199.41 + * your version of this file under either the CDDL, the GPL Version 2 or
199.42 + * to extend the choice of license to its licensees as provided above.
199.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
199.44 + * Version 2 license, then the option applies only if the new code is
199.45 + * made subject to such option by the copyright holder.
199.46 + */
199.47 +
199.48 +package org.netbeans.modules.python.source.ui;
199.49 +
199.50 +import javax.swing.JPanel;
199.51 +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
199.52 +import static org.netbeans.modules.python.source.ui.FmtOptions.*;
199.53 +import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
199.54 +
199.55 +/**
199.56 + * Preferences for formatting related to spaces
199.57 + *
199.58 + * @author Tor Norbye
199.59 + */
199.60 +public class FmtSpaces extends JPanel {
199.61 + public FmtSpaces() {
199.62 + initComponents();
199.63 +
199.64 + addAroundOp.putClientProperty(OPTION_ID, addSpaceAroundOperators);
199.65 + addAfterComma.putClientProperty(OPTION_ID, addSpaceAfterComma);
199.66 + removeBeforeSep.putClientProperty(OPTION_ID, removeSpaceBeforeSep);
199.67 + removeInParam.putClientProperty(OPTION_ID, removeSpaceInParamAssign);
199.68 + removeInParen.putClientProperty(OPTION_ID, removeSpaceInParens);
199.69 + collapseSpacesCb.putClientProperty(OPTION_ID, collapseSpaces);
199.70 + }
199.71 +
199.72 + public static PreferencesCustomizer.Factory getController() {
199.73 + return new CategorySupport.Factory("spaces", FmtSpaces.class, // NOI18N
199.74 + org.openide.util.NbBundle.getMessage(FmtSpaces.class, "SAMPLE_Spaces"));
199.75 + }
199.76 +
199.77 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
199.78 + private void initComponents() {
199.79 +
199.80 + addAroundOp = new javax.swing.JCheckBox();
199.81 + removeInParam = new javax.swing.JCheckBox();
199.82 + removeInParen = new javax.swing.JCheckBox();
199.83 + addAfterComma = new javax.swing.JCheckBox();
199.84 + removeBeforeSep = new javax.swing.JCheckBox();
199.85 + collapseSpacesCb = new javax.swing.JCheckBox();
199.86 +
199.87 + setName(org.openide.util.NbBundle.getMessage(FmtSpaces.class, "LBL_Spaces")); // NOI18N
199.88 + setOpaque(false);
199.89 +
199.90 + org.openide.awt.Mnemonics.setLocalizedText(addAroundOp, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAroundOp.text")); // NOI18N
199.91 +
199.92 + org.openide.awt.Mnemonics.setLocalizedText(removeInParam, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParam.text")); // NOI18N
199.93 +
199.94 + org.openide.awt.Mnemonics.setLocalizedText(removeInParen, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParen.text")); // NOI18N
199.95 +
199.96 + org.openide.awt.Mnemonics.setLocalizedText(addAfterComma, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAfterComma.text")); // NOI18N
199.97 +
199.98 + org.openide.awt.Mnemonics.setLocalizedText(removeBeforeSep, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeBeforeSep.text")); // NOI18N
199.99 +
199.100 + org.openide.awt.Mnemonics.setLocalizedText(collapseSpacesCb, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.collapseSpacesCb.text")); // NOI18N
199.101 +
199.102 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
199.103 + this.setLayout(layout);
199.104 + layout.setHorizontalGroup(
199.105 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
199.106 + .addGroup(layout.createSequentialGroup()
199.107 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
199.108 + .addComponent(addAroundOp)
199.109 + .addGroup(layout.createSequentialGroup()
199.110 + .addGap(27, 27, 27)
199.111 + .addComponent(removeInParam))
199.112 + .addComponent(removeInParen)
199.113 + .addComponent(addAfterComma)
199.114 + .addComponent(removeBeforeSep)
199.115 + .addComponent(collapseSpacesCb))
199.116 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
199.117 + );
199.118 + layout.setVerticalGroup(
199.119 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
199.120 + .addGroup(layout.createSequentialGroup()
199.121 + .addComponent(addAroundOp)
199.122 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
199.123 + .addComponent(removeInParam)
199.124 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
199.125 + .addComponent(removeInParen)
199.126 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
199.127 + .addComponent(addAfterComma)
199.128 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
199.129 + .addComponent(removeBeforeSep)
199.130 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
199.131 + .addComponent(collapseSpacesCb)
199.132 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
199.133 + );
199.134 + }// </editor-fold>//GEN-END:initComponents
199.135 +
199.136 +
199.137 + // Variables declaration - do not modify//GEN-BEGIN:variables
199.138 + private javax.swing.JCheckBox addAfterComma;
199.139 + private javax.swing.JCheckBox addAroundOp;
199.140 + private javax.swing.JCheckBox collapseSpacesCb;
199.141 + private javax.swing.JCheckBox removeBeforeSep;
199.142 + private javax.swing.JCheckBox removeInParam;
199.143 + private javax.swing.JCheckBox removeInParen;
199.144 + // End of variables declaration//GEN-END:variables
199.145 +
199.146 +}
200.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
200.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtTabsIndents.form Mon Sep 21 13:01:16 2015 +0200
200.3 @@ -0,0 +1,127 @@
200.4 +<?xml version="1.0" encoding="UTF-8" ?>
200.5 +
200.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
200.7 + <Properties>
200.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
200.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_TabsAndIndents" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
200.10 + </Property>
200.11 + <Property name="opaque" type="boolean" value="false"/>
200.12 + </Properties>
200.13 + <AuxValues>
200.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
200.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
200.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
200.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
200.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
200.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
200.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
200.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
200.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
200.23 + </AuxValues>
200.24 +
200.25 + <Layout>
200.26 + <DimensionLayout dim="0">
200.27 + <Group type="103" groupAlignment="0" attributes="0">
200.28 + <Group type="102" alignment="0" attributes="0">
200.29 + <Group type="103" groupAlignment="0" attributes="0">
200.30 + <Component id="continuationIndentSizeLabel" max="32767" attributes="0"/>
200.31 + <Component id="labelIndentLabel" min="-2" max="-2" attributes="0"/>
200.32 + </Group>
200.33 + <EmptySpace max="-2" attributes="0"/>
200.34 + <Group type="103" groupAlignment="1" attributes="0">
200.35 + <Component id="continuationIndentSizeField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
200.36 + <Component id="labelIndentField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
200.37 + </Group>
200.38 + </Group>
200.39 + <Component id="indentCasesFromSwitchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
200.40 + <Component id="indentTopLevelClassMembersCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
200.41 + <Component id="absoluteLabelIndentCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
200.42 + </Group>
200.43 + </DimensionLayout>
200.44 + <DimensionLayout dim="1">
200.45 + <Group type="103" groupAlignment="0" attributes="0">
200.46 + <Group type="102" attributes="0">
200.47 + <EmptySpace max="-2" attributes="0"/>
200.48 + <Group type="103" groupAlignment="3" attributes="0">
200.49 + <Component id="continuationIndentSizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
200.50 + <Component id="continuationIndentSizeField" alignment="3" min="-2" max="-2" attributes="0"/>
200.51 + </Group>
200.52 + <EmptySpace min="-2" max="-2" attributes="0"/>
200.53 + <Group type="103" groupAlignment="3" attributes="0">
200.54 + <Component id="labelIndentLabel" alignment="3" min="-2" max="-2" attributes="0"/>
200.55 + <Component id="labelIndentField" alignment="3" min="-2" max="-2" attributes="0"/>
200.56 + </Group>
200.57 + <EmptySpace type="unrelated" max="-2" attributes="0"/>
200.58 + <Component id="absoluteLabelIndentCheckBox" min="-2" max="-2" attributes="0"/>
200.59 + <EmptySpace max="-2" attributes="0"/>
200.60 + <Component id="indentTopLevelClassMembersCheckBox" min="-2" max="-2" attributes="0"/>
200.61 + <EmptySpace max="-2" attributes="0"/>
200.62 + <Component id="indentCasesFromSwitchCheckBox" min="-2" max="-2" attributes="0"/>
200.63 + <EmptySpace max="32767" attributes="0"/>
200.64 + </Group>
200.65 + </Group>
200.66 + </DimensionLayout>
200.67 + </Layout>
200.68 + <SubComponents>
200.69 + <Component class="javax.swing.JLabel" name="continuationIndentSizeLabel">
200.70 + <Properties>
200.71 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
200.72 + <ComponentRef name="continuationIndentSizeField"/>
200.73 + </Property>
200.74 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
200.75 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_ContinuationIndentSize" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
200.76 + </Property>
200.77 + </Properties>
200.78 + </Component>
200.79 + <Component class="javax.swing.JTextField" name="continuationIndentSizeField">
200.80 + </Component>
200.81 + <Component class="javax.swing.JLabel" name="labelIndentLabel">
200.82 + <Properties>
200.83 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
200.84 + <ComponentRef name="labelIndentField"/>
200.85 + </Property>
200.86 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
200.87 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_LabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
200.88 + </Property>
200.89 + </Properties>
200.90 + </Component>
200.91 + <Component class="javax.swing.JTextField" name="labelIndentField">
200.92 + </Component>
200.93 + <Component class="javax.swing.JCheckBox" name="absoluteLabelIndentCheckBox">
200.94 + <Properties>
200.95 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
200.96 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_AbsoluteLabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
200.97 + </Property>
200.98 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
200.99 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
200.100 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
200.101 + </Border>
200.102 + </Property>
200.103 + </Properties>
200.104 + </Component>
200.105 + <Component class="javax.swing.JCheckBox" name="indentTopLevelClassMembersCheckBox">
200.106 + <Properties>
200.107 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
200.108 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentTopLevelClassMemberts" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
200.109 + </Property>
200.110 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
200.111 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
200.112 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
200.113 + </Border>
200.114 + </Property>
200.115 + </Properties>
200.116 + </Component>
200.117 + <Component class="javax.swing.JCheckBox" name="indentCasesFromSwitchCheckBox">
200.118 + <Properties>
200.119 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
200.120 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentCasesFromSwitch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
200.121 + </Property>
200.122 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
200.123 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
200.124 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
200.125 + </Border>
200.126 + </Property>
200.127 + </Properties>
200.128 + </Component>
200.129 + </SubComponents>
200.130 +</Form>
201.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
201.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtTabsIndents.java Mon Sep 21 13:01:16 2015 +0200
201.3 @@ -0,0 +1,196 @@
201.4 +/*
201.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
201.6 + *
201.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
201.8 + *
201.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
201.10 + * Other names may be trademarks of their respective owners.
201.11 + *
201.12 + * The contents of this file are subject to the terms of either the GNU
201.13 + * General Public License Version 2 only ("GPL") or the Common
201.14 + * Development and Distribution License("CDDL") (collectively, the
201.15 + * "License"). You may not use this file except in compliance with the
201.16 + * License. You can obtain a copy of the License at
201.17 + * http://www.netbeans.org/cddl-gplv2.html
201.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
201.19 + * specific language governing permissions and limitations under the
201.20 + * License. When distributing the software, include this License Header
201.21 + * Notice in each file and include the License file at
201.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
201.23 + * particular file as subject to the "Classpath" exception as provided
201.24 + * by Oracle in the GPL Version 2 section of the License file that
201.25 + * accompanied this code. If applicable, add the following below the
201.26 + * License Header, with the fields enclosed by brackets [] replaced by
201.27 + * your own identifying information:
201.28 + * "Portions Copyrighted [year] [name of copyright owner]"
201.29 + *
201.30 + * Contributor(s):
201.31 + *
201.32 + * The Original Software is NetBeans. The Initial Developer of the Original
201.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
201.34 + * Microsystems, Inc. All Rights Reserved.
201.35 + *
201.36 + * If you wish your version of this file to be governed by only the CDDL
201.37 + * or only the GPL Version 2, indicate your decision by adding
201.38 + * "[Contributor] elects to include this software in this distribution
201.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
201.40 + * single choice of license, a recipient has the option to distribute
201.41 + * your version of this file under either the CDDL, the GPL Version 2 or
201.42 + * to extend the choice of license to its licensees as provided above.
201.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
201.44 + * Version 2 license, then the option applies only if the new code is
201.45 + * made subject to such option by the copyright holder.
201.46 + */
201.47 +
201.48 +package org.netbeans.modules.python.source.ui;
201.49 +
201.50 +//import org.netbeans.modules.python.source.CodeStyle.WrapStyle;
201.51 +//import static org.netbeans.modules.python.source.ui.FmtOptions.*;
201.52 +//import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
201.53 +//import org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport;
201.54 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
201.55 +
201.56 +/**
201.57 + *
201.58 + * @author phrebejk
201.59 + */
201.60 +public class FmtTabsIndents extends javax.swing.JPanel {
201.61 +
201.62 + /** Creates new form FmtTabsIndents */
201.63 + public FmtTabsIndents() {
201.64 + initComponents();
201.65 +/*
201.66 +// expandTabCheckBox.putClientProperty(OPTION_ID, expandTabToSpaces);
201.67 +// tabSizeField.putClientProperty(OPTION_ID, tabSize);
201.68 +// indentSizeField.putClientProperty(OPTION_ID, new String [] { indentSize, spacesPerTab });
201.69 + continuationIndentSizeField.putClientProperty(OPTION_ID, continuationIndentSize);
201.70 + labelIndentField.putClientProperty(OPTION_ID, labelIndent);
201.71 + absoluteLabelIndentCheckBox.putClientProperty(OPTION_ID, absoluteLabelIndent);
201.72 + indentTopLevelClassMembersCheckBox.putClientProperty(OPTION_ID, indentTopLevelClassMembers);
201.73 + indentCasesFromSwitchCheckBox.putClientProperty(OPTION_ID, indentCasesFromSwitch);
201.74 +// rightMarginField.putClientProperty(OPTION_ID, rightMargin);
201.75 + }
201.76 +
201.77 + public static PreferencesCustomizer.Factory getController() {
201.78 + return new CategorySupport.Factory(PreferencesCustomizer.TABS_AND_INDENTS_ID, FmtTabsIndents.class, //NOI18N
201.79 + org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "SAMPLE_TabsIndents"), // NOI18N
201.80 + new String[] { FmtOptions.rightMargin, "30" }, //NOI18N
201.81 + new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
201.82 + new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
201.83 + new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
201.84 + new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
201.85 + new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
201.86 + new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
201.87 + new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
201.88 + new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
201.89 + new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
201.90 + new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
201.91 + new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
201.92 + new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
201.93 + new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
201.94 + new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
201.95 + new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
201.96 + new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
201.97 + new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
201.98 + new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
201.99 + new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
201.100 + new String[] { FmtOptions.alignMultilineArrayInit, Boolean.FALSE.toString() },
201.101 + new String[] { FmtOptions.alignMultilineAssignment, Boolean.FALSE.toString() },
201.102 + new String[] { FmtOptions.alignMultilineBinaryOp, Boolean.FALSE.toString() },
201.103 + new String[] { FmtOptions.alignMultilineCallArgs, Boolean.FALSE.toString() },
201.104 + new String[] { FmtOptions.alignMultilineFor, Boolean.FALSE.toString() },
201.105 + new String[] { FmtOptions.alignMultilineImplements, Boolean.FALSE.toString() },
201.106 + new String[] { FmtOptions.alignMultilineMethodParams, Boolean.FALSE.toString() },
201.107 + new String[] { FmtOptions.alignMultilineParenthesized, Boolean.FALSE.toString() },
201.108 + new String[] { FmtOptions.alignMultilineTernaryOp, Boolean.FALSE.toString() },
201.109 + new String[] { FmtOptions.alignMultilineThrows, Boolean.FALSE.toString() }
201.110 + );
201.111 + */
201.112 + }
201.113 +
201.114 + /** This method is called from within the constructor to
201.115 + * initialize the form.
201.116 + * WARNING: Do NOT modify this code. The content of this method is
201.117 + * always regenerated by the Form Editor.
201.118 + */
201.119 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
201.120 + private void initComponents() {
201.121 +
201.122 + continuationIndentSizeLabel = new javax.swing.JLabel();
201.123 + continuationIndentSizeField = new javax.swing.JTextField();
201.124 + labelIndentLabel = new javax.swing.JLabel();
201.125 + labelIndentField = new javax.swing.JTextField();
201.126 + absoluteLabelIndentCheckBox = new javax.swing.JCheckBox();
201.127 + indentTopLevelClassMembersCheckBox = new javax.swing.JCheckBox();
201.128 + indentCasesFromSwitchCheckBox = new javax.swing.JCheckBox();
201.129 +
201.130 + setName(org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_TabsAndIndents")); // NOI18N
201.131 + setOpaque(false);
201.132 +
201.133 + continuationIndentSizeLabel.setLabelFor(continuationIndentSizeField);
201.134 + org.openide.awt.Mnemonics.setLocalizedText(continuationIndentSizeLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_ContinuationIndentSize")); // NOI18N
201.135 +
201.136 + labelIndentLabel.setLabelFor(labelIndentField);
201.137 + org.openide.awt.Mnemonics.setLocalizedText(labelIndentLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_LabelIndent")); // NOI18N
201.138 +
201.139 + org.openide.awt.Mnemonics.setLocalizedText(absoluteLabelIndentCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_AbsoluteLabelIndent")); // NOI18N
201.140 + absoluteLabelIndentCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
201.141 +
201.142 + org.openide.awt.Mnemonics.setLocalizedText(indentTopLevelClassMembersCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentTopLevelClassMemberts")); // NOI18N
201.143 + indentTopLevelClassMembersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
201.144 +
201.145 + org.openide.awt.Mnemonics.setLocalizedText(indentCasesFromSwitchCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentCasesFromSwitch")); // NOI18N
201.146 + indentCasesFromSwitchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
201.147 +
201.148 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
201.149 + this.setLayout(layout);
201.150 + layout.setHorizontalGroup(
201.151 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
201.152 + .addGroup(layout.createSequentialGroup()
201.153 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
201.154 + .addComponent(continuationIndentSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
201.155 + .addComponent(labelIndentLabel))
201.156 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
201.157 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
201.158 + .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
201.159 + .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)))
201.160 + .addComponent(indentCasesFromSwitchCheckBox)
201.161 + .addComponent(indentTopLevelClassMembersCheckBox)
201.162 + .addComponent(absoluteLabelIndentCheckBox)
201.163 + );
201.164 +
201.165 + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {continuationIndentSizeField, labelIndentField});
201.166 +
201.167 + layout.setVerticalGroup(
201.168 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
201.169 + .addGroup(layout.createSequentialGroup()
201.170 + .addContainerGap()
201.171 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
201.172 + .addComponent(continuationIndentSizeLabel)
201.173 + .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
201.174 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
201.175 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
201.176 + .addComponent(labelIndentLabel)
201.177 + .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
201.178 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
201.179 + .addComponent(absoluteLabelIndentCheckBox)
201.180 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
201.181 + .addComponent(indentTopLevelClassMembersCheckBox)
201.182 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
201.183 + .addComponent(indentCasesFromSwitchCheckBox)
201.184 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
201.185 + );
201.186 + }// </editor-fold>//GEN-END:initComponents
201.187 +
201.188 +
201.189 + // Variables declaration - do not modify//GEN-BEGIN:variables
201.190 + private javax.swing.JCheckBox absoluteLabelIndentCheckBox;
201.191 + private javax.swing.JTextField continuationIndentSizeField;
201.192 + private javax.swing.JLabel continuationIndentSizeLabel;
201.193 + private javax.swing.JCheckBox indentCasesFromSwitchCheckBox;
201.194 + private javax.swing.JCheckBox indentTopLevelClassMembersCheckBox;
201.195 + private javax.swing.JTextField labelIndentField;
201.196 + private javax.swing.JLabel labelIndentLabel;
201.197 + // End of variables declaration//GEN-END:variables
201.198 +
201.199 +}
202.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
202.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtWrapping.form Mon Sep 21 13:01:16 2015 +0200
202.3 @@ -0,0 +1,706 @@
202.4 +<?xml version="1.0" encoding="UTF-8" ?>
202.5 +
202.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
202.7 + <Properties>
202.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Wrapping" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.10 + </Property>
202.11 + <Property name="opaque" type="boolean" value="false"/>
202.12 + </Properties>
202.13 + <AuxValues>
202.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
202.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
202.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
202.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
202.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
202.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
202.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
202.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
202.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
202.23 + <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,45,0,0,1,42"/>
202.24 + </AuxValues>
202.25 +
202.26 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
202.27 + <SubComponents>
202.28 + <Container class="javax.swing.JScrollPane" name="scrollPane">
202.29 + <Properties>
202.30 + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
202.31 + <Dimension value="[300, 200]"/>
202.32 + </Property>
202.33 + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
202.34 + <Dimension value="[350, 600]"/>
202.35 + </Property>
202.36 + </Properties>
202.37 + <Constraints>
202.38 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
202.39 + <BorderConstraints direction="Center"/>
202.40 + </Constraint>
202.41 + </Constraints>
202.42 +
202.43 + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
202.44 + <SubComponents>
202.45 + <Container class="javax.swing.JPanel" name="panel1">
202.46 + <Properties>
202.47 + <Property name="opaque" type="boolean" value="false"/>
202.48 + </Properties>
202.49 +
202.50 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
202.51 + <SubComponents>
202.52 + <Component class="javax.swing.JLabel" name="extendsImplemetsKeywordLabel">
202.53 + <Properties>
202.54 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.55 + <ComponentRef name="extendsImplementsKeywordCombo"/>
202.56 + </Property>
202.57 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.58 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.59 + </Property>
202.60 + </Properties>
202.61 + <Constraints>
202.62 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.63 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="8" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.64 + </Constraint>
202.65 + </Constraints>
202.66 + </Component>
202.67 + <Component class="javax.swing.JComboBox" name="extendsImplementsKeywordCombo">
202.68 + <Properties>
202.69 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.70 + <StringArray count="4">
202.71 + <StringItem index="0" value="Item 1"/>
202.72 + <StringItem index="1" value="Item 2"/>
202.73 + <StringItem index="2" value="Item 3"/>
202.74 + <StringItem index="3" value="Item 4"/>
202.75 + </StringArray>
202.76 + </Property>
202.77 + </Properties>
202.78 + <Constraints>
202.79 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.80 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="8" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="1.0" weightY="0.0"/>
202.81 + </Constraint>
202.82 + </Constraints>
202.83 + </Component>
202.84 + <Component class="javax.swing.JLabel" name="extendsImplementsListLabel">
202.85 + <Properties>
202.86 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.87 + <ComponentRef name="extendsImplementsListCombo"/>
202.88 + </Property>
202.89 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.90 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.91 + </Property>
202.92 + </Properties>
202.93 + <Constraints>
202.94 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.95 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.96 + </Constraint>
202.97 + </Constraints>
202.98 + </Component>
202.99 + <Component class="javax.swing.JComboBox" name="extendsImplementsListCombo">
202.100 + <Properties>
202.101 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.102 + <StringArray count="4">
202.103 + <StringItem index="0" value="Item 1"/>
202.104 + <StringItem index="1" value="Item 2"/>
202.105 + <StringItem index="2" value="Item 3"/>
202.106 + <StringItem index="3" value="Item 4"/>
202.107 + </StringArray>
202.108 + </Property>
202.109 + </Properties>
202.110 + <Constraints>
202.111 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.112 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.113 + </Constraint>
202.114 + </Constraints>
202.115 + </Component>
202.116 + <Component class="javax.swing.JLabel" name="methodParamsLabel">
202.117 + <Properties>
202.118 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.119 + <ComponentRef name="methodParamsCombo"/>
202.120 + </Property>
202.121 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.122 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodParameters" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.123 + </Property>
202.124 + </Properties>
202.125 + <Constraints>
202.126 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.127 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.128 + </Constraint>
202.129 + </Constraints>
202.130 + </Component>
202.131 + <Component class="javax.swing.JComboBox" name="methodParamsCombo">
202.132 + <Properties>
202.133 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.134 + <StringArray count="4">
202.135 + <StringItem index="0" value="Item 1"/>
202.136 + <StringItem index="1" value="Item 2"/>
202.137 + <StringItem index="2" value="Item 3"/>
202.138 + <StringItem index="3" value="Item 4"/>
202.139 + </StringArray>
202.140 + </Property>
202.141 + </Properties>
202.142 + <Constraints>
202.143 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.144 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.145 + </Constraint>
202.146 + </Constraints>
202.147 + </Component>
202.148 + <Component class="javax.swing.JLabel" name="methodCallArgsLabel">
202.149 + <Properties>
202.150 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.151 + <ComponentRef name="methodCallArgsCombo"/>
202.152 + </Property>
202.153 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.154 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodCallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.155 + </Property>
202.156 + </Properties>
202.157 + <Constraints>
202.158 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.159 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.160 + </Constraint>
202.161 + </Constraints>
202.162 + </Component>
202.163 + <Component class="javax.swing.JComboBox" name="methodCallArgsCombo">
202.164 + <Properties>
202.165 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.166 + <StringArray count="4">
202.167 + <StringItem index="0" value="Item 1"/>
202.168 + <StringItem index="1" value="Item 2"/>
202.169 + <StringItem index="2" value="Item 3"/>
202.170 + <StringItem index="3" value="Item 4"/>
202.171 + </StringArray>
202.172 + </Property>
202.173 + </Properties>
202.174 + <Constraints>
202.175 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.176 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.177 + </Constraint>
202.178 + </Constraints>
202.179 + </Component>
202.180 + <Component class="javax.swing.JLabel" name="annotationArgsLabel">
202.181 + <Properties>
202.182 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.183 + <ComponentRef name="annotationArgsCombo"/>
202.184 + </Property>
202.185 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.186 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.187 + </Property>
202.188 + </Properties>
202.189 + <Constraints>
202.190 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.191 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.192 + </Constraint>
202.193 + </Constraints>
202.194 + </Component>
202.195 + <Component class="javax.swing.JComboBox" name="annotationArgsCombo">
202.196 + <Properties>
202.197 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.198 + <StringArray count="4">
202.199 + <StringItem index="0" value="Item 1"/>
202.200 + <StringItem index="1" value="Item 2"/>
202.201 + <StringItem index="2" value="Item 3"/>
202.202 + <StringItem index="3" value="Item 4"/>
202.203 + </StringArray>
202.204 + </Property>
202.205 + </Properties>
202.206 + <Constraints>
202.207 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.208 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.209 + </Constraint>
202.210 + </Constraints>
202.211 + </Component>
202.212 + <Component class="javax.swing.JLabel" name="chainedMethodCallsLabel">
202.213 + <Properties>
202.214 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.215 + <ComponentRef name="chainedMethodCallsCombo"/>
202.216 + </Property>
202.217 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.218 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_chainedMethodCalls" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.219 + </Property>
202.220 + </Properties>
202.221 + <Constraints>
202.222 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.223 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.224 + </Constraint>
202.225 + </Constraints>
202.226 + </Component>
202.227 + <Component class="javax.swing.JComboBox" name="chainedMethodCallsCombo">
202.228 + <Properties>
202.229 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.230 + <StringArray count="4">
202.231 + <StringItem index="0" value="Item 1"/>
202.232 + <StringItem index="1" value="Item 2"/>
202.233 + <StringItem index="2" value="Item 3"/>
202.234 + <StringItem index="3" value="Item 4"/>
202.235 + </StringArray>
202.236 + </Property>
202.237 + </Properties>
202.238 + <Constraints>
202.239 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.240 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.241 + </Constraint>
202.242 + </Constraints>
202.243 + </Component>
202.244 + <Component class="javax.swing.JLabel" name="throwsKeywordLabel">
202.245 + <Properties>
202.246 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.247 + <ComponentRef name="throwsKeywordCombo"/>
202.248 + </Property>
202.249 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.250 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.251 + </Property>
202.252 + </Properties>
202.253 + <Constraints>
202.254 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.255 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.256 + </Constraint>
202.257 + </Constraints>
202.258 + </Component>
202.259 + <Component class="javax.swing.JComboBox" name="throwsKeywordCombo">
202.260 + <Properties>
202.261 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.262 + <StringArray count="4">
202.263 + <StringItem index="0" value="Item 1"/>
202.264 + <StringItem index="1" value="Item 2"/>
202.265 + <StringItem index="2" value="Item 3"/>
202.266 + <StringItem index="3" value="Item 4"/>
202.267 + </StringArray>
202.268 + </Property>
202.269 + </Properties>
202.270 + <Constraints>
202.271 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.272 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.273 + </Constraint>
202.274 + </Constraints>
202.275 + </Component>
202.276 + <Component class="javax.swing.JLabel" name="throwsListLabel">
202.277 + <Properties>
202.278 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.279 + <ComponentRef name="throwsListCombo"/>
202.280 + </Property>
202.281 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.282 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.283 + </Property>
202.284 + </Properties>
202.285 + <Constraints>
202.286 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.287 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.288 + </Constraint>
202.289 + </Constraints>
202.290 + </Component>
202.291 + <Component class="javax.swing.JComboBox" name="throwsListCombo">
202.292 + <Properties>
202.293 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.294 + <StringArray count="4">
202.295 + <StringItem index="0" value="Item 1"/>
202.296 + <StringItem index="1" value="Item 2"/>
202.297 + <StringItem index="2" value="Item 3"/>
202.298 + <StringItem index="3" value="Item 4"/>
202.299 + </StringArray>
202.300 + </Property>
202.301 + </Properties>
202.302 + <Constraints>
202.303 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.304 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.305 + </Constraint>
202.306 + </Constraints>
202.307 + </Component>
202.308 + <Component class="javax.swing.JLabel" name="arrayInitLabel">
202.309 + <Properties>
202.310 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.311 + <ComponentRef name="arrayInitCombo"/>
202.312 + </Property>
202.313 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.314 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_arrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.315 + </Property>
202.316 + </Properties>
202.317 + <Constraints>
202.318 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.319 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.320 + </Constraint>
202.321 + </Constraints>
202.322 + </Component>
202.323 + <Component class="javax.swing.JComboBox" name="arrayInitCombo">
202.324 + <Properties>
202.325 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.326 + <StringArray count="4">
202.327 + <StringItem index="0" value="Item 1"/>
202.328 + <StringItem index="1" value="Item 2"/>
202.329 + <StringItem index="2" value="Item 3"/>
202.330 + <StringItem index="3" value="Item 4"/>
202.331 + </StringArray>
202.332 + </Property>
202.333 + </Properties>
202.334 + <Constraints>
202.335 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.336 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.337 + </Constraint>
202.338 + </Constraints>
202.339 + </Component>
202.340 + <Component class="javax.swing.JLabel" name="forLabel">
202.341 + <Properties>
202.342 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.343 + <ComponentRef name="forCombo"/>
202.344 + </Property>
202.345 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.346 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_for" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.347 + </Property>
202.348 + </Properties>
202.349 + <Constraints>
202.350 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.351 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.352 + </Constraint>
202.353 + </Constraints>
202.354 + </Component>
202.355 + <Component class="javax.swing.JComboBox" name="forCombo">
202.356 + <Properties>
202.357 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.358 + <StringArray count="4">
202.359 + <StringItem index="0" value="Item 1"/>
202.360 + <StringItem index="1" value="Item 2"/>
202.361 + <StringItem index="2" value="Item 3"/>
202.362 + <StringItem index="3" value="Item 4"/>
202.363 + </StringArray>
202.364 + </Property>
202.365 + </Properties>
202.366 + <Constraints>
202.367 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.368 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.369 + </Constraint>
202.370 + </Constraints>
202.371 + </Component>
202.372 + <Component class="javax.swing.JLabel" name="forStatementLabel">
202.373 + <Properties>
202.374 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.375 + <ComponentRef name="forStatementCombo"/>
202.376 + </Property>
202.377 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.378 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_forStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.379 + </Property>
202.380 + </Properties>
202.381 + <Constraints>
202.382 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.383 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.384 + </Constraint>
202.385 + </Constraints>
202.386 + </Component>
202.387 + <Component class="javax.swing.JComboBox" name="forStatementCombo">
202.388 + <Properties>
202.389 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.390 + <StringArray count="4">
202.391 + <StringItem index="0" value="Item 1"/>
202.392 + <StringItem index="1" value="Item 2"/>
202.393 + <StringItem index="2" value="Item 3"/>
202.394 + <StringItem index="3" value="Item 4"/>
202.395 + </StringArray>
202.396 + </Property>
202.397 + </Properties>
202.398 + <Constraints>
202.399 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.400 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="1.0" weightY="0.0"/>
202.401 + </Constraint>
202.402 + </Constraints>
202.403 + </Component>
202.404 + <Component class="javax.swing.JLabel" name="ifStatementLabel">
202.405 + <Properties>
202.406 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.407 + <ComponentRef name="ifStatementCombo"/>
202.408 + </Property>
202.409 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.410 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ifStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.411 + </Property>
202.412 + </Properties>
202.413 + <Constraints>
202.414 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.415 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.416 + </Constraint>
202.417 + </Constraints>
202.418 + </Component>
202.419 + <Component class="javax.swing.JComboBox" name="ifStatementCombo">
202.420 + <Properties>
202.421 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.422 + <StringArray count="4">
202.423 + <StringItem index="0" value="Item 1"/>
202.424 + <StringItem index="1" value="Item 2"/>
202.425 + <StringItem index="2" value="Item 3"/>
202.426 + <StringItem index="3" value="Item 4"/>
202.427 + </StringArray>
202.428 + </Property>
202.429 + </Properties>
202.430 + <Constraints>
202.431 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.432 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.433 + </Constraint>
202.434 + </Constraints>
202.435 + </Component>
202.436 + <Component class="javax.swing.JLabel" name="whileStatementLabel">
202.437 + <Properties>
202.438 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.439 + <ComponentRef name="whileStatementComboBox"/>
202.440 + </Property>
202.441 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.442 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_whileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.443 + </Property>
202.444 + </Properties>
202.445 + <Constraints>
202.446 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.447 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.448 + </Constraint>
202.449 + </Constraints>
202.450 + </Component>
202.451 + <Component class="javax.swing.JComboBox" name="whileStatementComboBox">
202.452 + <Properties>
202.453 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.454 + <StringArray count="4">
202.455 + <StringItem index="0" value="Item 1"/>
202.456 + <StringItem index="1" value="Item 2"/>
202.457 + <StringItem index="2" value="Item 3"/>
202.458 + <StringItem index="3" value="Item 4"/>
202.459 + </StringArray>
202.460 + </Property>
202.461 + </Properties>
202.462 + <Constraints>
202.463 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.464 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.465 + </Constraint>
202.466 + </Constraints>
202.467 + </Component>
202.468 + <Component class="javax.swing.JLabel" name="doWhileStatementLabel">
202.469 + <Properties>
202.470 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.471 + <ComponentRef name="doWhileStatementCombo"/>
202.472 + </Property>
202.473 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.474 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_doWhileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.475 + </Property>
202.476 + </Properties>
202.477 + <Constraints>
202.478 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.479 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.480 + </Constraint>
202.481 + </Constraints>
202.482 + </Component>
202.483 + <Component class="javax.swing.JComboBox" name="doWhileStatementCombo">
202.484 + <Properties>
202.485 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.486 + <StringArray count="4">
202.487 + <StringItem index="0" value="Item 1"/>
202.488 + <StringItem index="1" value="Item 2"/>
202.489 + <StringItem index="2" value="Item 3"/>
202.490 + <StringItem index="3" value="Item 4"/>
202.491 + </StringArray>
202.492 + </Property>
202.493 + </Properties>
202.494 + <Constraints>
202.495 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.496 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.497 + </Constraint>
202.498 + </Constraints>
202.499 + </Component>
202.500 + <Component class="javax.swing.JLabel" name="assertLabel">
202.501 + <Properties>
202.502 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.503 + <ComponentRef name="assertCombo"/>
202.504 + </Property>
202.505 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.506 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assert" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.507 + </Property>
202.508 + </Properties>
202.509 + <Constraints>
202.510 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.511 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.512 + </Constraint>
202.513 + </Constraints>
202.514 + </Component>
202.515 + <Component class="javax.swing.JComboBox" name="assertCombo">
202.516 + <Properties>
202.517 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.518 + <StringArray count="4">
202.519 + <StringItem index="0" value="Item 1"/>
202.520 + <StringItem index="1" value="Item 2"/>
202.521 + <StringItem index="2" value="Item 3"/>
202.522 + <StringItem index="3" value="Item 4"/>
202.523 + </StringArray>
202.524 + </Property>
202.525 + </Properties>
202.526 + <Constraints>
202.527 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.528 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.529 + </Constraint>
202.530 + </Constraints>
202.531 + </Component>
202.532 + <Component class="javax.swing.JLabel" name="enumConstantsLabel">
202.533 + <Properties>
202.534 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.535 + <ComponentRef name="enumConstantsCombo"/>
202.536 + </Property>
202.537 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.538 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_enumConstants" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.539 + </Property>
202.540 + </Properties>
202.541 + <Constraints>
202.542 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.543 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.544 + </Constraint>
202.545 + </Constraints>
202.546 + </Component>
202.547 + <Component class="javax.swing.JComboBox" name="enumConstantsCombo">
202.548 + <Properties>
202.549 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.550 + <StringArray count="4">
202.551 + <StringItem index="0" value="Item 1"/>
202.552 + <StringItem index="1" value="Item 2"/>
202.553 + <StringItem index="2" value="Item 3"/>
202.554 + <StringItem index="3" value="Item 4"/>
202.555 + </StringArray>
202.556 + </Property>
202.557 + </Properties>
202.558 + <Constraints>
202.559 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.560 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.561 + </Constraint>
202.562 + </Constraints>
202.563 + </Component>
202.564 + <Component class="javax.swing.JLabel" name="annotationsLabel">
202.565 + <Properties>
202.566 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.567 + <ComponentRef name="annotationsCombo"/>
202.568 + </Property>
202.569 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.570 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotations" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.571 + </Property>
202.572 + </Properties>
202.573 + <Constraints>
202.574 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.575 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.576 + </Constraint>
202.577 + </Constraints>
202.578 + </Component>
202.579 + <Component class="javax.swing.JComboBox" name="annotationsCombo">
202.580 + <Properties>
202.581 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.582 + <StringArray count="4">
202.583 + <StringItem index="0" value="Item 1"/>
202.584 + <StringItem index="1" value="Item 2"/>
202.585 + <StringItem index="2" value="Item 3"/>
202.586 + <StringItem index="3" value="Item 4"/>
202.587 + </StringArray>
202.588 + </Property>
202.589 + </Properties>
202.590 + <Constraints>
202.591 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.592 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.593 + </Constraint>
202.594 + </Constraints>
202.595 + </Component>
202.596 + <Component class="javax.swing.JLabel" name="binaryOpsLabel">
202.597 + <Properties>
202.598 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.599 + <ComponentRef name="binaryOpsCombo"/>
202.600 + </Property>
202.601 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.602 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_binaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.603 + </Property>
202.604 + </Properties>
202.605 + <Constraints>
202.606 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.607 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.608 + </Constraint>
202.609 + </Constraints>
202.610 + </Component>
202.611 + <Component class="javax.swing.JComboBox" name="binaryOpsCombo">
202.612 + <Properties>
202.613 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.614 + <StringArray count="4">
202.615 + <StringItem index="0" value="Item 1"/>
202.616 + <StringItem index="1" value="Item 2"/>
202.617 + <StringItem index="2" value="Item 3"/>
202.618 + <StringItem index="3" value="Item 4"/>
202.619 + </StringArray>
202.620 + </Property>
202.621 + </Properties>
202.622 + <Constraints>
202.623 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.624 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.625 + </Constraint>
202.626 + </Constraints>
202.627 + </Component>
202.628 + <Component class="javax.swing.JLabel" name="ternaryOpsLabel">
202.629 + <Properties>
202.630 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.631 + <ComponentRef name="ternaryOpsCombo"/>
202.632 + </Property>
202.633 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.634 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ternaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.635 + </Property>
202.636 + </Properties>
202.637 + <Constraints>
202.638 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.639 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.640 + </Constraint>
202.641 + </Constraints>
202.642 + </Component>
202.643 + <Component class="javax.swing.JComboBox" name="ternaryOpsCombo">
202.644 + <Properties>
202.645 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.646 + <StringArray count="4">
202.647 + <StringItem index="0" value="Item 1"/>
202.648 + <StringItem index="1" value="Item 2"/>
202.649 + <StringItem index="2" value="Item 3"/>
202.650 + <StringItem index="3" value="Item 4"/>
202.651 + </StringArray>
202.652 + </Property>
202.653 + </Properties>
202.654 + <Constraints>
202.655 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.656 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.657 + </Constraint>
202.658 + </Constraints>
202.659 + </Component>
202.660 + <Component class="javax.swing.JLabel" name="assignOpsLabel">
202.661 + <Properties>
202.662 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
202.663 + <ComponentRef name="assignOpsCombo"/>
202.664 + </Property>
202.665 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
202.666 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assignOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
202.667 + </Property>
202.668 + </Properties>
202.669 + <Constraints>
202.670 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.671 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="4" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
202.672 + </Constraint>
202.673 + </Constraints>
202.674 + </Component>
202.675 + <Component class="javax.swing.JComboBox" name="assignOpsCombo">
202.676 + <Properties>
202.677 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
202.678 + <StringArray count="4">
202.679 + <StringItem index="0" value="Item 1"/>
202.680 + <StringItem index="1" value="Item 2"/>
202.681 + <StringItem index="2" value="Item 3"/>
202.682 + <StringItem index="3" value="Item 4"/>
202.683 + </StringArray>
202.684 + </Property>
202.685 + </Properties>
202.686 + <Constraints>
202.687 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.688 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="4" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
202.689 + </Constraint>
202.690 + </Constraints>
202.691 + </Component>
202.692 + <Container class="javax.swing.JPanel" name="spacerPanel1">
202.693 + <Properties>
202.694 + <Property name="opaque" type="boolean" value="false"/>
202.695 + </Properties>
202.696 + <Constraints>
202.697 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
202.698 + <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="0" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0" insetsRight="8" anchor="10" weightX="0.0" weightY="1.0"/>
202.699 + </Constraint>
202.700 + </Constraints>
202.701 +
202.702 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
202.703 + </Container>
202.704 + </SubComponents>
202.705 + </Container>
202.706 + </SubComponents>
202.707 + </Container>
202.708 + </SubComponents>
202.709 +</Form>
203.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
203.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtWrapping.java Mon Sep 21 13:01:16 2015 +0200
203.3 @@ -0,0 +1,505 @@
203.4 +/*
203.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
203.6 + *
203.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
203.8 + *
203.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
203.10 + * Other names may be trademarks of their respective owners.
203.11 + *
203.12 + * The contents of this file are subject to the terms of either the GNU
203.13 + * General Public License Version 2 only ("GPL") or the Common
203.14 + * Development and Distribution License("CDDL") (collectively, the
203.15 + * "License"). You may not use this file except in compliance with the
203.16 + * License. You can obtain a copy of the License at
203.17 + * http://www.netbeans.org/cddl-gplv2.html
203.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
203.19 + * specific language governing permissions and limitations under the
203.20 + * License. When distributing the software, include this License Header
203.21 + * Notice in each file and include the License file at
203.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
203.23 + * particular file as subject to the "Classpath" exception as provided
203.24 + * by Oracle in the GPL Version 2 section of the License file that
203.25 + * accompanied this code. If applicable, add the following below the
203.26 + * License Header, with the fields enclosed by brackets [] replaced by
203.27 + * your own identifying information:
203.28 + * "Portions Copyrighted [year] [name of copyright owner]"
203.29 + *
203.30 + * Contributor(s):
203.31 + *
203.32 + * The Original Software is NetBeans. The Initial Developer of the Original
203.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
203.34 + * Microsystems, Inc. All Rights Reserved.
203.35 + *
203.36 + * If you wish your version of this file to be governed by only the CDDL
203.37 + * or only the GPL Version 2, indicate your decision by adding
203.38 + * "[Contributor] elects to include this software in this distribution
203.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
203.40 + * single choice of license, a recipient has the option to distribute
203.41 + * your version of this file under either the CDDL, the GPL Version 2 or
203.42 + * to extend the choice of license to its licensees as provided above.
203.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
203.44 + * Version 2 license, then the option applies only if the new code is
203.45 + * made subject to such option by the copyright holder.
203.46 + */
203.47 +
203.48 +package org.netbeans.modules.python.source.ui;
203.49 +
203.50 +//import org.netbeans.modules.python.source.CodeStyle;
203.51 +//import static org.netbeans.modules.python.source.ui.FmtOptions.*;
203.52 +//import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
203.53 +//import org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport;
203.54 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
203.55 +
203.56 +
203.57 +/**
203.58 + *
203.59 + * @author phrebejk
203.60 + */
203.61 +public class FmtWrapping extends javax.swing.JPanel {
203.62 +
203.63 + /** Creates new form FmtWrapping */
203.64 + public FmtWrapping() {
203.65 + initComponents();
203.66 +
203.67 + scrollPane.getViewport().setBackground(java.awt.SystemColor.controlLtHighlight);
203.68 +
203.69 +/*
203.70 + extendsImplementsKeywordCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsKeyword);
203.71 + extendsImplementsListCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsList);
203.72 + methodParamsCombo.putClientProperty(OPTION_ID, wrapMethodParams);
203.73 + methodCallArgsCombo.putClientProperty(OPTION_ID, wrapMethodCallArgs);
203.74 + annotationArgsCombo.putClientProperty(OPTION_ID, wrapAnnotationArgs);
203.75 + chainedMethodCallsCombo.putClientProperty(OPTION_ID, wrapChainedMethodCalls);
203.76 + throwsKeywordCombo.putClientProperty(OPTION_ID, wrapThrowsKeyword);
203.77 + throwsListCombo.putClientProperty(OPTION_ID, wrapThrowsList);
203.78 + arrayInitCombo.putClientProperty(OPTION_ID, wrapArrayInit);
203.79 + forCombo.putClientProperty(OPTION_ID, wrapFor);
203.80 + forStatementCombo.putClientProperty(OPTION_ID, wrapForStatement );
203.81 + ifStatementCombo.putClientProperty(OPTION_ID, wrapIfStatement);
203.82 + whileStatementComboBox.putClientProperty(OPTION_ID, wrapWhileStatement);
203.83 + doWhileStatementCombo.putClientProperty(OPTION_ID, wrapDoWhileStatement);
203.84 + assertCombo.putClientProperty(OPTION_ID, wrapAssert);
203.85 + enumConstantsCombo.putClientProperty(OPTION_ID, wrapEnumConstants);
203.86 + annotationsCombo.putClientProperty(OPTION_ID, wrapAnnotations);
203.87 + binaryOpsCombo.putClientProperty(OPTION_ID, wrapBinaryOps);
203.88 + ternaryOpsCombo.putClientProperty(OPTION_ID, wrapTernaryOps);
203.89 + assignOpsCombo.putClientProperty(OPTION_ID, wrapAssignOps);
203.90 + }
203.91 +
203.92 + public static PreferencesCustomizer.Factory getController() {
203.93 + return new CategorySupport.Factory("wrapping", FmtWrapping.class, //NOI18N
203.94 + org.openide.util.NbBundle.getMessage(FmtWrapping.class, "SAMPLE_Wrapping"), //NOI18N
203.95 + new String[] { FmtOptions.rightMargin, "30" } //NOI18N
203.96 +// new String[] { FmtOptions.redundantDoWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
203.97 +// new String[] { FmtOptions.redundantForBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
203.98 +// new String[] { FmtOptions.redundantIfBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
203.99 +// new String[] { FmtOptions.redundantWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() }
203.100 + ); // NOI18N
203.101 + */
203.102 + }
203.103 +
203.104 + /** This method is called from within the constructor to
203.105 + * initialize the form.
203.106 + * WARNING: Do NOT modify this code. The content of this method is
203.107 + * always regenerated by the Form Editor.
203.108 + */
203.109 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
203.110 + private void initComponents() {
203.111 + java.awt.GridBagConstraints gridBagConstraints;
203.112 +
203.113 + scrollPane = new javax.swing.JScrollPane();
203.114 + panel1 = new javax.swing.JPanel();
203.115 + extendsImplemetsKeywordLabel = new javax.swing.JLabel();
203.116 + extendsImplementsKeywordCombo = new javax.swing.JComboBox();
203.117 + extendsImplementsListLabel = new javax.swing.JLabel();
203.118 + extendsImplementsListCombo = new javax.swing.JComboBox();
203.119 + methodParamsLabel = new javax.swing.JLabel();
203.120 + methodParamsCombo = new javax.swing.JComboBox();
203.121 + methodCallArgsLabel = new javax.swing.JLabel();
203.122 + methodCallArgsCombo = new javax.swing.JComboBox();
203.123 + annotationArgsLabel = new javax.swing.JLabel();
203.124 + annotationArgsCombo = new javax.swing.JComboBox();
203.125 + chainedMethodCallsLabel = new javax.swing.JLabel();
203.126 + chainedMethodCallsCombo = new javax.swing.JComboBox();
203.127 + throwsKeywordLabel = new javax.swing.JLabel();
203.128 + throwsKeywordCombo = new javax.swing.JComboBox();
203.129 + throwsListLabel = new javax.swing.JLabel();
203.130 + throwsListCombo = new javax.swing.JComboBox();
203.131 + arrayInitLabel = new javax.swing.JLabel();
203.132 + arrayInitCombo = new javax.swing.JComboBox();
203.133 + forLabel = new javax.swing.JLabel();
203.134 + forCombo = new javax.swing.JComboBox();
203.135 + forStatementLabel = new javax.swing.JLabel();
203.136 + forStatementCombo = new javax.swing.JComboBox();
203.137 + ifStatementLabel = new javax.swing.JLabel();
203.138 + ifStatementCombo = new javax.swing.JComboBox();
203.139 + whileStatementLabel = new javax.swing.JLabel();
203.140 + whileStatementComboBox = new javax.swing.JComboBox();
203.141 + doWhileStatementLabel = new javax.swing.JLabel();
203.142 + doWhileStatementCombo = new javax.swing.JComboBox();
203.143 + assertLabel = new javax.swing.JLabel();
203.144 + assertCombo = new javax.swing.JComboBox();
203.145 + enumConstantsLabel = new javax.swing.JLabel();
203.146 + enumConstantsCombo = new javax.swing.JComboBox();
203.147 + annotationsLabel = new javax.swing.JLabel();
203.148 + annotationsCombo = new javax.swing.JComboBox();
203.149 + binaryOpsLabel = new javax.swing.JLabel();
203.150 + binaryOpsCombo = new javax.swing.JComboBox();
203.151 + ternaryOpsLabel = new javax.swing.JLabel();
203.152 + ternaryOpsCombo = new javax.swing.JComboBox();
203.153 + assignOpsLabel = new javax.swing.JLabel();
203.154 + assignOpsCombo = new javax.swing.JComboBox();
203.155 + spacerPanel1 = new javax.swing.JPanel();
203.156 +
203.157 + setName(org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_Wrapping")); // NOI18N
203.158 + setOpaque(false);
203.159 + setLayout(new java.awt.BorderLayout());
203.160 +
203.161 + scrollPane.setMinimumSize(new java.awt.Dimension(300, 200));
203.162 + scrollPane.setPreferredSize(new java.awt.Dimension(350, 600));
203.163 +
203.164 + panel1.setOpaque(false);
203.165 + panel1.setLayout(new java.awt.GridBagLayout());
203.166 +
203.167 + extendsImplemetsKeywordLabel.setLabelFor(extendsImplementsKeywordCombo);
203.168 + org.openide.awt.Mnemonics.setLocalizedText(extendsImplemetsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsKeyword")); // NOI18N
203.169 + gridBagConstraints = new java.awt.GridBagConstraints();
203.170 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.171 + gridBagConstraints.insets = new java.awt.Insets(8, 8, 4, 0);
203.172 + panel1.add(extendsImplemetsKeywordLabel, gridBagConstraints);
203.173 +
203.174 + extendsImplementsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.175 + gridBagConstraints = new java.awt.GridBagConstraints();
203.176 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.177 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.178 + gridBagConstraints.weightx = 1.0;
203.179 + gridBagConstraints.insets = new java.awt.Insets(8, 6, 4, 8);
203.180 + panel1.add(extendsImplementsKeywordCombo, gridBagConstraints);
203.181 +
203.182 + extendsImplementsListLabel.setLabelFor(extendsImplementsListCombo);
203.183 + org.openide.awt.Mnemonics.setLocalizedText(extendsImplementsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsList")); // NOI18N
203.184 + gridBagConstraints = new java.awt.GridBagConstraints();
203.185 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.186 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.187 + panel1.add(extendsImplementsListLabel, gridBagConstraints);
203.188 +
203.189 + extendsImplementsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.190 + gridBagConstraints = new java.awt.GridBagConstraints();
203.191 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.192 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.193 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.194 + panel1.add(extendsImplementsListCombo, gridBagConstraints);
203.195 +
203.196 + methodParamsLabel.setLabelFor(methodParamsCombo);
203.197 + org.openide.awt.Mnemonics.setLocalizedText(methodParamsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodParameters")); // NOI18N
203.198 + gridBagConstraints = new java.awt.GridBagConstraints();
203.199 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.200 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.201 + panel1.add(methodParamsLabel, gridBagConstraints);
203.202 +
203.203 + methodParamsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.204 + gridBagConstraints = new java.awt.GridBagConstraints();
203.205 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.206 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.207 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.208 + panel1.add(methodParamsCombo, gridBagConstraints);
203.209 +
203.210 + methodCallArgsLabel.setLabelFor(methodCallArgsCombo);
203.211 + org.openide.awt.Mnemonics.setLocalizedText(methodCallArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodCallArgs")); // NOI18N
203.212 + gridBagConstraints = new java.awt.GridBagConstraints();
203.213 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.214 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.215 + panel1.add(methodCallArgsLabel, gridBagConstraints);
203.216 +
203.217 + methodCallArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.218 + gridBagConstraints = new java.awt.GridBagConstraints();
203.219 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.220 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.221 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.222 + panel1.add(methodCallArgsCombo, gridBagConstraints);
203.223 +
203.224 + annotationArgsLabel.setLabelFor(annotationArgsCombo);
203.225 + org.openide.awt.Mnemonics.setLocalizedText(annotationArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotationArgs")); // NOI18N
203.226 + gridBagConstraints = new java.awt.GridBagConstraints();
203.227 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.228 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.229 + panel1.add(annotationArgsLabel, gridBagConstraints);
203.230 +
203.231 + annotationArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.232 + gridBagConstraints = new java.awt.GridBagConstraints();
203.233 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.234 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.235 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.236 + panel1.add(annotationArgsCombo, gridBagConstraints);
203.237 +
203.238 + chainedMethodCallsLabel.setLabelFor(chainedMethodCallsCombo);
203.239 + org.openide.awt.Mnemonics.setLocalizedText(chainedMethodCallsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_chainedMethodCalls")); // NOI18N
203.240 + gridBagConstraints = new java.awt.GridBagConstraints();
203.241 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.242 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.243 + panel1.add(chainedMethodCallsLabel, gridBagConstraints);
203.244 +
203.245 + chainedMethodCallsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.246 + gridBagConstraints = new java.awt.GridBagConstraints();
203.247 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.248 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.249 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.250 + panel1.add(chainedMethodCallsCombo, gridBagConstraints);
203.251 +
203.252 + throwsKeywordLabel.setLabelFor(throwsKeywordCombo);
203.253 + org.openide.awt.Mnemonics.setLocalizedText(throwsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsKeyword")); // NOI18N
203.254 + gridBagConstraints = new java.awt.GridBagConstraints();
203.255 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.256 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.257 + panel1.add(throwsKeywordLabel, gridBagConstraints);
203.258 +
203.259 + throwsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.260 + gridBagConstraints = new java.awt.GridBagConstraints();
203.261 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.262 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.263 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.264 + panel1.add(throwsKeywordCombo, gridBagConstraints);
203.265 +
203.266 + throwsListLabel.setLabelFor(throwsListCombo);
203.267 + org.openide.awt.Mnemonics.setLocalizedText(throwsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsList")); // NOI18N
203.268 + gridBagConstraints = new java.awt.GridBagConstraints();
203.269 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.270 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.271 + panel1.add(throwsListLabel, gridBagConstraints);
203.272 +
203.273 + throwsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.274 + gridBagConstraints = new java.awt.GridBagConstraints();
203.275 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.276 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.277 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.278 + panel1.add(throwsListCombo, gridBagConstraints);
203.279 +
203.280 + arrayInitLabel.setLabelFor(arrayInitCombo);
203.281 + org.openide.awt.Mnemonics.setLocalizedText(arrayInitLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_arrayInit")); // NOI18N
203.282 + gridBagConstraints = new java.awt.GridBagConstraints();
203.283 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.284 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.285 + panel1.add(arrayInitLabel, gridBagConstraints);
203.286 +
203.287 + arrayInitCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.288 + gridBagConstraints = new java.awt.GridBagConstraints();
203.289 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.290 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.291 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.292 + panel1.add(arrayInitCombo, gridBagConstraints);
203.293 +
203.294 + forLabel.setLabelFor(forCombo);
203.295 + org.openide.awt.Mnemonics.setLocalizedText(forLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_for")); // NOI18N
203.296 + gridBagConstraints = new java.awt.GridBagConstraints();
203.297 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.298 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.299 + panel1.add(forLabel, gridBagConstraints);
203.300 +
203.301 + forCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.302 + gridBagConstraints = new java.awt.GridBagConstraints();
203.303 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.304 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.305 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.306 + panel1.add(forCombo, gridBagConstraints);
203.307 +
203.308 + forStatementLabel.setLabelFor(forStatementCombo);
203.309 + org.openide.awt.Mnemonics.setLocalizedText(forStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_forStatement")); // NOI18N
203.310 + gridBagConstraints = new java.awt.GridBagConstraints();
203.311 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.312 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.313 + panel1.add(forStatementLabel, gridBagConstraints);
203.314 +
203.315 + forStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.316 + gridBagConstraints = new java.awt.GridBagConstraints();
203.317 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.318 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.319 + gridBagConstraints.weightx = 1.0;
203.320 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.321 + panel1.add(forStatementCombo, gridBagConstraints);
203.322 +
203.323 + ifStatementLabel.setLabelFor(ifStatementCombo);
203.324 + org.openide.awt.Mnemonics.setLocalizedText(ifStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ifStatement")); // NOI18N
203.325 + gridBagConstraints = new java.awt.GridBagConstraints();
203.326 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.327 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.328 + panel1.add(ifStatementLabel, gridBagConstraints);
203.329 +
203.330 + ifStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.331 + gridBagConstraints = new java.awt.GridBagConstraints();
203.332 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.333 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.334 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.335 + panel1.add(ifStatementCombo, gridBagConstraints);
203.336 +
203.337 + whileStatementLabel.setLabelFor(whileStatementComboBox);
203.338 + org.openide.awt.Mnemonics.setLocalizedText(whileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_whileStatement")); // NOI18N
203.339 + gridBagConstraints = new java.awt.GridBagConstraints();
203.340 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.341 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.342 + panel1.add(whileStatementLabel, gridBagConstraints);
203.343 +
203.344 + whileStatementComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.345 + gridBagConstraints = new java.awt.GridBagConstraints();
203.346 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.347 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.348 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.349 + panel1.add(whileStatementComboBox, gridBagConstraints);
203.350 +
203.351 + doWhileStatementLabel.setLabelFor(doWhileStatementCombo);
203.352 + org.openide.awt.Mnemonics.setLocalizedText(doWhileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_doWhileStatement")); // NOI18N
203.353 + gridBagConstraints = new java.awt.GridBagConstraints();
203.354 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.355 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.356 + panel1.add(doWhileStatementLabel, gridBagConstraints);
203.357 +
203.358 + doWhileStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.359 + gridBagConstraints = new java.awt.GridBagConstraints();
203.360 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.361 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.362 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.363 + panel1.add(doWhileStatementCombo, gridBagConstraints);
203.364 +
203.365 + assertLabel.setLabelFor(assertCombo);
203.366 + org.openide.awt.Mnemonics.setLocalizedText(assertLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assert")); // NOI18N
203.367 + gridBagConstraints = new java.awt.GridBagConstraints();
203.368 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.369 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.370 + panel1.add(assertLabel, gridBagConstraints);
203.371 +
203.372 + assertCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.373 + gridBagConstraints = new java.awt.GridBagConstraints();
203.374 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.375 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.376 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.377 + panel1.add(assertCombo, gridBagConstraints);
203.378 +
203.379 + enumConstantsLabel.setLabelFor(enumConstantsCombo);
203.380 + org.openide.awt.Mnemonics.setLocalizedText(enumConstantsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_enumConstants")); // NOI18N
203.381 + gridBagConstraints = new java.awt.GridBagConstraints();
203.382 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.383 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.384 + panel1.add(enumConstantsLabel, gridBagConstraints);
203.385 +
203.386 + enumConstantsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.387 + gridBagConstraints = new java.awt.GridBagConstraints();
203.388 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.389 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.390 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.391 + panel1.add(enumConstantsCombo, gridBagConstraints);
203.392 +
203.393 + annotationsLabel.setLabelFor(annotationsCombo);
203.394 + org.openide.awt.Mnemonics.setLocalizedText(annotationsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotations")); // NOI18N
203.395 + gridBagConstraints = new java.awt.GridBagConstraints();
203.396 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.397 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.398 + panel1.add(annotationsLabel, gridBagConstraints);
203.399 +
203.400 + annotationsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.401 + gridBagConstraints = new java.awt.GridBagConstraints();
203.402 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.403 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.404 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.405 + panel1.add(annotationsCombo, gridBagConstraints);
203.406 +
203.407 + binaryOpsLabel.setLabelFor(binaryOpsCombo);
203.408 + org.openide.awt.Mnemonics.setLocalizedText(binaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_binaryOps")); // NOI18N
203.409 + gridBagConstraints = new java.awt.GridBagConstraints();
203.410 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.411 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.412 + panel1.add(binaryOpsLabel, gridBagConstraints);
203.413 +
203.414 + binaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.415 + gridBagConstraints = new java.awt.GridBagConstraints();
203.416 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.417 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.418 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.419 + panel1.add(binaryOpsCombo, gridBagConstraints);
203.420 +
203.421 + ternaryOpsLabel.setLabelFor(ternaryOpsCombo);
203.422 + org.openide.awt.Mnemonics.setLocalizedText(ternaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ternaryOps")); // NOI18N
203.423 + gridBagConstraints = new java.awt.GridBagConstraints();
203.424 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.425 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.426 + panel1.add(ternaryOpsLabel, gridBagConstraints);
203.427 +
203.428 + ternaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.429 + gridBagConstraints = new java.awt.GridBagConstraints();
203.430 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.431 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.432 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.433 + panel1.add(ternaryOpsCombo, gridBagConstraints);
203.434 +
203.435 + assignOpsLabel.setLabelFor(assignOpsCombo);
203.436 + org.openide.awt.Mnemonics.setLocalizedText(assignOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assignOps")); // NOI18N
203.437 + gridBagConstraints = new java.awt.GridBagConstraints();
203.438 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
203.439 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
203.440 + panel1.add(assignOpsLabel, gridBagConstraints);
203.441 +
203.442 + assignOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
203.443 + gridBagConstraints = new java.awt.GridBagConstraints();
203.444 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.445 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
203.446 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
203.447 + panel1.add(assignOpsCombo, gridBagConstraints);
203.448 +
203.449 + spacerPanel1.setOpaque(false);
203.450 + gridBagConstraints = new java.awt.GridBagConstraints();
203.451 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
203.452 + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
203.453 + gridBagConstraints.weighty = 1.0;
203.454 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 8);
203.455 + panel1.add(spacerPanel1, gridBagConstraints);
203.456 +
203.457 + scrollPane.setViewportView(panel1);
203.458 +
203.459 + add(scrollPane, java.awt.BorderLayout.CENTER);
203.460 + }// </editor-fold>//GEN-END:initComponents
203.461 +
203.462 + // Variables declaration - do not modify//GEN-BEGIN:variables
203.463 + private javax.swing.JComboBox annotationArgsCombo;
203.464 + private javax.swing.JLabel annotationArgsLabel;
203.465 + private javax.swing.JComboBox annotationsCombo;
203.466 + private javax.swing.JLabel annotationsLabel;
203.467 + private javax.swing.JComboBox arrayInitCombo;
203.468 + private javax.swing.JLabel arrayInitLabel;
203.469 + private javax.swing.JComboBox assertCombo;
203.470 + private javax.swing.JLabel assertLabel;
203.471 + private javax.swing.JComboBox assignOpsCombo;
203.472 + private javax.swing.JLabel assignOpsLabel;
203.473 + private javax.swing.JComboBox binaryOpsCombo;
203.474 + private javax.swing.JLabel binaryOpsLabel;
203.475 + private javax.swing.JComboBox chainedMethodCallsCombo;
203.476 + private javax.swing.JLabel chainedMethodCallsLabel;
203.477 + private javax.swing.JComboBox doWhileStatementCombo;
203.478 + private javax.swing.JLabel doWhileStatementLabel;
203.479 + private javax.swing.JComboBox enumConstantsCombo;
203.480 + private javax.swing.JLabel enumConstantsLabel;
203.481 + private javax.swing.JComboBox extendsImplementsKeywordCombo;
203.482 + private javax.swing.JComboBox extendsImplementsListCombo;
203.483 + private javax.swing.JLabel extendsImplementsListLabel;
203.484 + private javax.swing.JLabel extendsImplemetsKeywordLabel;
203.485 + private javax.swing.JComboBox forCombo;
203.486 + private javax.swing.JLabel forLabel;
203.487 + private javax.swing.JComboBox forStatementCombo;
203.488 + private javax.swing.JLabel forStatementLabel;
203.489 + private javax.swing.JComboBox ifStatementCombo;
203.490 + private javax.swing.JLabel ifStatementLabel;
203.491 + private javax.swing.JComboBox methodCallArgsCombo;
203.492 + private javax.swing.JLabel methodCallArgsLabel;
203.493 + private javax.swing.JComboBox methodParamsCombo;
203.494 + private javax.swing.JLabel methodParamsLabel;
203.495 + private javax.swing.JPanel panel1;
203.496 + private javax.swing.JScrollPane scrollPane;
203.497 + private javax.swing.JPanel spacerPanel1;
203.498 + private javax.swing.JComboBox ternaryOpsCombo;
203.499 + private javax.swing.JLabel ternaryOpsLabel;
203.500 + private javax.swing.JComboBox throwsKeywordCombo;
203.501 + private javax.swing.JLabel throwsKeywordLabel;
203.502 + private javax.swing.JComboBox throwsListCombo;
203.503 + private javax.swing.JLabel throwsListLabel;
203.504 + private javax.swing.JComboBox whileStatementComboBox;
203.505 + private javax.swing.JLabel whileStatementLabel;
203.506 + // End of variables declaration//GEN-END:variables
203.507 +
203.508 +}
204.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
204.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/NumericKeyListener.java Mon Sep 21 13:01:16 2015 +0200
204.3 @@ -0,0 +1,74 @@
204.4 +/*
204.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
204.6 + *
204.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
204.8 + *
204.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
204.10 + * Other names may be trademarks of their respective owners.
204.11 + *
204.12 + * The contents of this file are subject to the terms of either the GNU
204.13 + * General Public License Version 2 only ("GPL") or the Common
204.14 + * Development and Distribution License("CDDL") (collectively, the
204.15 + * "License"). You may not use this file except in compliance with the
204.16 + * License. You can obtain a copy of the License at
204.17 + * http://www.netbeans.org/cddl-gplv2.html
204.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
204.19 + * specific language governing permissions and limitations under the
204.20 + * License. When distributing the software, include this License Header
204.21 + * Notice in each file and include the License file at
204.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
204.23 + * particular file as subject to the "Classpath" exception as provided
204.24 + * by Oracle in the GPL Version 2 section of the License file that
204.25 + * accompanied this code. If applicable, add the following below the
204.26 + * License Header, with the fields enclosed by brackets [] replaced by
204.27 + * your own identifying information:
204.28 + * "Portions Copyrighted [year] [name of copyright owner]"
204.29 + *
204.30 + * If you wish your version of this file to be governed by only the CDDL
204.31 + * or only the GPL Version 2, indicate your decision by adding
204.32 + * "[Contributor] elects to include this software in this distribution
204.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
204.34 + * single choice of license, a recipient has the option to distribute
204.35 + * your version of this file under either the CDDL, the GPL Version 2 or
204.36 + * to extend the choice of license to its licensees as provided above.
204.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
204.38 + * Version 2 license, then the option applies only if the new code is
204.39 + * made subject to such option by the copyright holder.
204.40 + *
204.41 + * Contributor(s):
204.42 + *
204.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
204.44 + */
204.45 +package org.netbeans.modules.python.editor.options;
204.46 +
204.47 +import java.awt.Component;
204.48 +import java.awt.event.KeyEvent;
204.49 +import java.awt.event.KeyListener;
204.50 +
204.51 +/**
204.52 + *
204.53 + * @author tester
204.54 + */
204.55 +public class NumericKeyListener implements KeyListener {
204.56 + public NumericKeyListener() {
204.57 + }
204.58 +
204.59 + @Override
204.60 + public void keyPressed(KeyEvent evt) {
204.61 + }
204.62 +
204.63 + @Override
204.64 + public void keyReleased(KeyEvent evt) {
204.65 + }
204.66 +
204.67 + @Override
204.68 + public void keyTyped(KeyEvent evt) {
204.69 + if (!Character.isDigit(evt.getKeyChar()) && !Character.isISOControl(evt.getKeyChar())) {
204.70 + evt.consume();
204.71 + Component c = evt.getComponent();
204.72 + if (c != null) {
204.73 + c.getToolkit().beep();
204.74 + }
204.75 + }
204.76 + }
204.77 +}