1.1 --- a/o.jython/manifest.mf Mon Aug 31 12:40:19 2015 +0200
1.2 +++ b/o.jython/manifest.mf Wed Sep 02 20:31:18 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.11
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 Mon Aug 31 12:40:19 2015 +0200
2.2 +++ b/o.jython/nbproject/project.xml Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
3.2 +++ b/python.editor/nbproject/project.properties Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
4.2 +++ b/python.editor/nbproject/project.xml Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
6.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/GoToSuperTypeAction.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
8.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonCodeCompleter.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
9.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonDeclarationFinder.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
17.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonInstantRename.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
18.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonKeystrokeHandler.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
19.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonLanguage.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
20.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonOccurrencesMarker.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
23.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonSemanticHighlighter.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
26.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/PythonTypeAnalyzer.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,529 +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 - // Keywords - according to http://docs.python.org/ref/keywords.html
27.196 - static final String[] PYTHON_KEYWORDS = new String[]{
27.197 - "and", // NOI18N
27.198 - "as", // NOI18N
27.199 - "assert", // NOI18N
27.200 - "break", // NOI18N
27.201 - "class", // NOI18N
27.202 - "continue", // NOI18N
27.203 - "def", // NOI18N
27.204 - "del", // NOI18N
27.205 - "elif", // NOI18N
27.206 - "else", // NOI18N
27.207 - "except", // NOI18N
27.208 - "exec", // NOI18N
27.209 - "finally", // NOI18N
27.210 - "for", // NOI18N
27.211 - "from", // NOI18N
27.212 - "global", // NOI18N
27.213 - "if", // NOI18N
27.214 - "import", // NOI18N
27.215 - "in", // NOI18N
27.216 - "is", // NOI18N
27.217 - "lambda", // NOI18N
27.218 - "not", // NOI18N
27.219 - "or", // NOI18N
27.220 - "pass", // NOI18N
27.221 - "print", // NOI18N
27.222 - "raise", // NOI18N
27.223 - "return", // NOI18N
27.224 - "try", // NOI18N
27.225 - "while", // NOI18N
27.226 - "with", // NOI18N
27.227 - "yield", // NOI18N
27.228 - };
27.229 -
27.230 - public static boolean isPythonKeyword(String name) {
27.231 - for (String s : PYTHON_KEYWORDS) {
27.232 - if (s.equals(name)) {
27.233 - return true;
27.234 - }
27.235 - }
27.236 -
27.237 - return false;
27.238 - }
27.239 -
27.240 - /**
27.241 - * Return true iff the name is a class name
27.242 - * @param name The name
27.243 - * @param emptyDefault Whether empty or _ names should be considered a class name or not
27.244 - * @return True iff the name looks like a class name
27.245 - */
27.246 - public static boolean isClassName(String name, boolean emptyDefault) {
27.247 - if (name == null || name.length() == 0) {
27.248 - return emptyDefault;
27.249 - }
27.250 - if (name.startsWith("_") && name.length() > 1) {
27.251 - return Character.isUpperCase(name.charAt(1));
27.252 - }
27.253 -
27.254 - return Character.isUpperCase(name.charAt(0));
27.255 - }
27.256 -
27.257 - /**
27.258 - * Return true iff the name is a method name
27.259 - * @param name The name
27.260 - * @param emptyDefault Whether empty or _ names should be considered a class name or not
27.261 - * @return True iff the name looks like a method name
27.262 - */
27.263 - public static boolean isMethodName(String name, boolean emptyDefault) {
27.264 - if (name == null || name.length() == 0) {
27.265 - return emptyDefault;
27.266 - }
27.267 - if (name.startsWith("__") && name.length() > 2) {
27.268 - return Character.isLowerCase(name.charAt(2));
27.269 - }
27.270 - if (name.startsWith("_") && name.length() > 1) {
27.271 - return Character.isLowerCase(name.charAt(1));
27.272 - }
27.273 -
27.274 - return Character.isLowerCase(name.charAt(0));
27.275 - }
27.276 -
27.277 - public static String getCodeTemplate(CodeTemplateManager ctm, String abbrev, String textPrefix, String wrongTextPrefix) {
27.278 - String templateText = null;
27.279 - for (CodeTemplate t : ctm.getCodeTemplates()) {
27.280 - if (abbrev.equals(t.getAbbreviation())) {
27.281 - templateText = t.getParametrizedText();
27.282 - break;
27.283 - }
27.284 - }
27.285 - if (templateText == null) {
27.286 - for (CodeTemplate t : ctm.getCodeTemplates()) {
27.287 - String text = t.getParametrizedText();
27.288 - if (text.startsWith(textPrefix) && (wrongTextPrefix == null || !text.startsWith(wrongTextPrefix))) {
27.289 - templateText = text;
27.290 - break;
27.291 - }
27.292 - }
27.293 - }
27.294 -
27.295 - return templateText;
27.296 - }
27.297 -
27.298 - public static boolean isValidPythonClassName(String name) {
27.299 - if (isPythonKeyword(name)) {
27.300 - return false;
27.301 - }
27.302 -
27.303 - if (name.trim().length() == 0) {
27.304 - return false;
27.305 - }
27.306 -
27.307 - if (!Character.isUpperCase(name.charAt(0))) {
27.308 - return false;
27.309 - }
27.310 -
27.311 - for (int i = 1; i < name.length(); i++) {
27.312 - char c = name.charAt(i);
27.313 - if (!Character.isJavaIdentifierPart(c)) {
27.314 - return false;
27.315 - }
27.316 -
27.317 - }
27.318 -
27.319 - return true;
27.320 - }
27.321 -
27.322 - /** Is this name a valid operator name? */
27.323 - public static boolean isOperator(String name) {
27.324 - // TODO - update to Python
27.325 - if (name.length() == 0) {
27.326 - return false;
27.327 - }
27.328 -
27.329 - switch (name.charAt(0)) {
27.330 - case '+':
27.331 - return name.equals("+") || name.equals("+@");
27.332 - case '-':
27.333 - return name.equals("-") || name.equals("-@");
27.334 - case '*':
27.335 - return name.equals("*") || name.equals("**");
27.336 - case '<':
27.337 - return name.equals("<") || name.equals("<<") || name.equals("<=") || name.equals("<=>");
27.338 - case '>':
27.339 - return name.equals(">") || name.equals(">>") || name.equals(">=");
27.340 - case '=':
27.341 - return name.equals("=") || name.equals("==") || name.equals("===") || name.equals("=~");
27.342 - case '!':
27.343 - return name.equals("!=") || name.equals("!~");
27.344 - case '&':
27.345 - return name.equals("&") || name.equals("&&");
27.346 - case '|':
27.347 - return name.equals("|") || name.equals("||");
27.348 - case '[':
27.349 - return name.equals("[]") || name.equals("[]=");
27.350 - case '%':
27.351 - return name.equals("%");
27.352 - case '/':
27.353 - return name.equals("/");
27.354 - case '~':
27.355 - return name.equals("~");
27.356 - case '^':
27.357 - return name.equals("^");
27.358 - case '`':
27.359 - return name.equals("`");
27.360 - default:
27.361 - return false;
27.362 - }
27.363 - }
27.364 -
27.365 - public static boolean isValidPythonMethodName(String name) {
27.366 - if (isPythonKeyword(name)) {
27.367 - return false;
27.368 - }
27.369 -
27.370 - if (name.trim().length() == 0) {
27.371 - return false;
27.372 - }
27.373 -
27.374 - // TODO - allow operators
27.375 - if (isOperator(name)) {
27.376 - return true;
27.377 - }
27.378 -
27.379 - if (Character.isUpperCase(name.charAt(0)) || Character.isWhitespace(name.charAt(0))) {
27.380 - return false;
27.381 - }
27.382 -
27.383 - for (int i = 0; i < name.length(); i++) {
27.384 - char c = name.charAt(i);
27.385 - if (!(Character.isLetterOrDigit(c) || c == '_')) {
27.386 - return false;
27.387 - }
27.388 -
27.389 - }
27.390 -
27.391 - return true;
27.392 - }
27.393 -
27.394 - public static boolean isValidPythonIdentifier(String name) {
27.395 - if (isPythonKeyword(name)) {
27.396 - return false;
27.397 - }
27.398 -
27.399 - if (name.trim().length() == 0) {
27.400 - return false;
27.401 - }
27.402 -
27.403 - for (int i = 0; i < name.length(); i++) {
27.404 - // Identifier char isn't really accurate - I can have a function named "[]" etc.
27.405 - // so just look for -obvious- mistakes
27.406 - if (Character.isWhitespace(name.charAt(i))) {
27.407 - return false;
27.408 - }
27.409 -
27.410 - // TODO - make this more accurate, like the method validifier
27.411 - }
27.412 -
27.413 - return true;
27.414 - }
27.415 -
27.416 - /**
27.417 - * Ruby identifiers should consist of [a-zA-Z0-9_]
27.418 - * http://www.headius.com/rubyspec/index.php/Variables
27.419 - * <p>
27.420 - * This method also accepts the field/global chars
27.421 - * since it's unlikely
27.422 - */
27.423 - public static boolean isSafeIdentifierName(String name, int fromIndex) {
27.424 - int i = fromIndex;
27.425 - for (; i < name.length(); i++) {
27.426 - char c = name.charAt(i);
27.427 - if (!(c == '$' || c == '@' || c == ':')) {
27.428 - break;
27.429 - }
27.430 - }
27.431 - for (; i < name.length(); i++) {
27.432 - char c = name.charAt(i);
27.433 - if (!((c >= 'a' && c <= 'z') || (c == '_') ||
27.434 - (c >= 'A' && c <= 'Z') ||
27.435 - (c >= '0' && c <= '9') ||
27.436 - (c == '?') || (c == '=') || (c == '!'))) { // Method suffixes; only allowed on the last line
27.437 -
27.438 - if (isOperator(name)) {
27.439 - return true;
27.440 - }
27.441 -
27.442 - return false;
27.443 - }
27.444 - }
27.445 -
27.446 - return true;
27.447 - }
27.448 -
27.449 - /**
27.450 - * Return null if the given identifier name is valid, otherwise a localized
27.451 - * error message explaining the problem.
27.452 - */
27.453 - public static String getIdentifierWarning(String name, int fromIndex) {
27.454 - if (isSafeIdentifierName(name, fromIndex)) {
27.455 - return null;
27.456 - } else {
27.457 - return NbBundle.getMessage(PythonUtils.class, "UnsafeIdentifierName");
27.458 - }
27.459 - }
27.460 -
27.461 - /** @todo Move into GsfUtilities after 6.5 */
27.462 - public static int getOffsetByLineCol(String source, int line, int col) {
27.463 - int offset = 0;
27.464 - for (int i = 0; i < line; i++) {
27.465 - offset = source.indexOf('\n', offset);
27.466 - if (offset == -1) {
27.467 - offset = source.length();
27.468 - break;
27.469 - }
27.470 - offset++;
27.471 - }
27.472 - if (col > 0) { // -1: invalid
27.473 - offset += col;
27.474 - }
27.475 -
27.476 - return offset;
27.477 - }
27.478 - public static Comparator NAME_NODE_COMPARATOR = new Comparator<Name>() {
27.479 - @Override
27.480 - public int compare(Name n1, Name n2) {
27.481 - return n1.getInternalId().compareTo(n2.getInternalId());
27.482 - }
27.483 - };
27.484 - public static Comparator ATTRIBUTE_NAME_NODE_COMPARATOR = new Comparator<Object>() {
27.485 - @SuppressWarnings("unchecked")
27.486 - @Override
27.487 - public int compare(Object n1, Object n2) {
27.488 - String s1 = "";
27.489 - String s2 = "";
27.490 -
27.491 - if (n1 instanceof Name) {
27.492 - s1 = ((Name)n1).getInternalId();
27.493 - } else if (n1 instanceof Attribute) {
27.494 - Attribute a = (Attribute)n1;
27.495 - String v = PythonAstUtils.getName(a.getInternalValue());
27.496 - if (v != null) {
27.497 - s1 = a.getInternalAttr() + "." + v;
27.498 - } else {
27.499 - s1 = a.getInternalAttr();
27.500 - }
27.501 - }
27.502 -
27.503 - if (n2 instanceof Name) {
27.504 - s2 = ((Name)n2).getInternalId();
27.505 - } else if (n2 instanceof Attribute) {
27.506 - Attribute a = (Attribute)n2;
27.507 - String v = PythonAstUtils.getName(a.getInternalValue());
27.508 - if (v != null) {
27.509 - s2 = a.getInternalAttr() + "." + v;
27.510 - } else {
27.511 - s2 = a.getInternalAttr();
27.512 - }
27.513 - }
27.514 -
27.515 - return s1.compareTo(s2);
27.516 - }
27.517 - };
27.518 - public static Comparator NODE_POS_COMPARATOR = new Comparator<PythonTree>() {
27.519 - @Override
27.520 - public int compare(PythonTree p1, PythonTree p2) {
27.521 - int ret = p1.getCharStartIndex() - p2.getCharStartIndex();
27.522 - if (ret != 0) {
27.523 - return ret;
27.524 - }
27.525 - ret = p2.getCharStopIndex() - p1.getCharStopIndex();
27.526 - if (ret != 0) {
27.527 - return ret;
27.528 - }
27.529 - return p2.getAntlrType() - p1.getAntlrType();
27.530 - }
27.531 - };
27.532 -}
28.1 --- a/python.editor/src/org/netbeans/modules/python/editor/QuerySupportFactory.java Mon Aug 31 12:40:19 2015 +0200
28.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/QuerySupportFactory.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
30.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codecoverage/PythonCoverageProvider.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
31.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/ClassCodeGenerator.java Wed Sep 02 20:31:18 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 Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
33.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/ConstructorGenerator.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
34.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/codegen/MethodCodeGenerator.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
62.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
62.3 @@ -1,228 +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 - List<HintFix> fixList = new ArrayList<>(3);
62.108 - // Is is a reference to a module?
62.109 - boolean tryModule = false;
62.110 - if (node.getParent() instanceof Call) {
62.111 - Call call = (Call)node.getParent();
62.112 - PythonTree t = call.getInternalFunc();
62.113 - if (t instanceof Attribute) {
62.114 - tryModule = true;
62.115 - }
62.116 - }
62.117 - String message = NbBundle.getMessage(NameRule.class, "UnresolvedVariable", name);
62.118 - if (name.equals("true")) { // NOI18N
62.119 - // Help for new language converts...
62.120 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "True"); // NOI18N
62.121 - } else if (name.equals("false")) {
62.122 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "False"); // NOI18N
62.123 - } else if (name.equals("nil") || name.equals("null")) {
62.124 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "None"); // NOI18N
62.125 - } else if (name.equals("this")) {
62.126 - message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "self"); // NOI18N
62.127 - } else if (tryModule) {
62.128 - Set<IndexedElement> moduleElements = index.getModules(name, QuerySupport.Kind.EXACT);
62.129 - if (moduleElements.size() > 0) {
62.130 - fixList.add(new ImportFix(context, node, name));
62.131 - }
62.132 - } else {
62.133 - Set<String> modules = index.getImportsFor(name, true);
62.134 - if (modules.size() > 0) {
62.135 - for (String module : modules) {
62.136 - fixList.add(new ImportFix(context, node, module));
62.137 - }
62.138 - }
62.139 - }
62.140 -
62.141 - OffsetRange range = PythonAstUtils.getNameRange(info, node);
62.142 - range = PythonLexerUtils.getLexerOffsets(info, range);
62.143 - if (range != OffsetRange.NONE) {
62.144 - Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
62.145 - result.add(desc);
62.146 - }
62.147 - }
62.148 - }
62.149 - }
62.150 -
62.151 - @Override
62.152 - public String getId() {
62.153 - return "Unresolved"; // NOI18N
62.154 - }
62.155 -
62.156 - @Override
62.157 - public String getDisplayName() {
62.158 - return NbBundle.getMessage(NameRule.class, "Unresolved");
62.159 - }
62.160 -
62.161 - @Override
62.162 - public String getDescription() {
62.163 - return NbBundle.getMessage(NameRule.class, "UnresolvedDesc");
62.164 - }
62.165 -
62.166 - @Override
62.167 - public boolean getDefaultEnabled() {
62.168 - return false;
62.169 - }
62.170 -
62.171 - @Override
62.172 - public boolean showInTasklist() {
62.173 - return true;
62.174 - }
62.175 -
62.176 - @Override
62.177 - public HintSeverity getDefaultSeverity() {
62.178 - return HintSeverity.ERROR;
62.179 - }
62.180 -
62.181 - @Override
62.182 - public JComponent getCustomizer(Preferences node) {
62.183 - return null;
62.184 - }
62.185 -
62.186 - private static class ImportFix implements HintFix {
62.187 - private final PythonRuleContext context;
62.188 - private final PythonTree node;
62.189 - private final String module;
62.190 -
62.191 - private ImportFix(PythonRuleContext context, PythonTree node, String module) {
62.192 - this.context = context;
62.193 - this.node = node;
62.194 - this.module = module;
62.195 - }
62.196 -
62.197 - @Override
62.198 - public String getDescription() {
62.199 - return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
62.200 - }
62.201 -
62.202 - @Override
62.203 - public void implement() throws Exception {
62.204 - String mod = this.module;
62.205 - String symbol = null;
62.206 - int colon = mod.indexOf(':');
62.207 - if (colon != -1) {
62.208 - int end = mod.indexOf('(', colon + 1);
62.209 - if (end == -1) {
62.210 - end = mod.indexOf(';', colon + 1);
62.211 - if (end == -1) {
62.212 - end = mod.length();
62.213 - }
62.214 - }
62.215 - symbol = mod.substring(colon + 1, end).trim();
62.216 - mod = mod.substring(0, colon).trim();
62.217 - }
62.218 - new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
62.219 - }
62.220 -
62.221 - @Override
62.222 - public boolean isSafe() {
62.223 - return true;
62.224 - }
62.225 -
62.226 - @Override
62.227 - public boolean isInteractive() {
62.228 - return false;
62.229 - }
62.230 - }
62.231 -}
63.1 --- a/python.editor/src/org/netbeans/modules/python/editor/hints/UnusedDetector.java Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
67.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/imports/FastImportAction.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
68.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/imports/FixImportsAction.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
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 Mon Aug 31 12:40:19 2015 +0200
71.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/imports/ImportModulePanel.java Wed Sep 02 20:31:18 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 Mon Aug 31 12:40:19 2015 +0200
72.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/layer.xml Wed Sep 02 20:31:18 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/Call.java Mon Aug 31 12:40:19 2015 +0200
73.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
73.3 @@ -1,322 +0,0 @@
73.4 -/*
73.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
73.6 - *
73.7 - * Copyright 1997-2010 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 - * Contributor(s):
73.31 - *
73.32 - * The Original Software is NetBeans. The Initial Developer of the Original
73.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
73.34 - * Microsystems, Inc. All Rights Reserved.
73.35 - *
73.36 - * If you wish your version of this file to be governed by only the CDDL
73.37 - * or only the GPL Version 2, indicate your decision by adding
73.38 - * "[Contributor] elects to include this software in this distribution
73.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
73.40 - * single choice of license, a recipient has the option to distribute
73.41 - * your version of this file under either the CDDL, the GPL Version 2 or
73.42 - * to extend the choice of license to its licensees as provided above.
73.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
73.44 - * Version 2 license, then the option applies only if the new code is
73.45 - * made subject to such option by the copyright holder.
73.46 - */
73.47 -package org.netbeans.modules.python.editor.lexer;
73.48 -
73.49 -import javax.swing.text.BadLocationException;
73.50 -import javax.swing.text.Document;
73.51 -import org.netbeans.api.annotations.common.NonNull;
73.52 -
73.53 -import org.netbeans.api.lexer.Token;
73.54 -import org.netbeans.api.lexer.TokenHierarchy;
73.55 -import org.netbeans.api.lexer.TokenId;
73.56 -import org.netbeans.api.lexer.TokenSequence;
73.57 -import org.netbeans.editor.BaseDocument;
73.58 -import org.netbeans.editor.Utilities;
73.59 -import org.openide.util.Exceptions;
73.60 -
73.61 -/**
73.62 - * Class which represents a Call in the source
73.63 - */
73.64 -public class Call {
73.65 - public static final Call LOCAL = new Call(null, null, false, false);
73.66 - public static final Call NONE = new Call(null, null, false, false);
73.67 - public static final Call UNKNOWN = new Call(null, null, false, false);
73.68 - private final String type;
73.69 - private final String lhs;
73.70 - private final boolean isStatic;
73.71 - private final boolean methodExpected;
73.72 -
73.73 - public Call(String type, String lhs, boolean isStatic, boolean methodExpected) {
73.74 - super();
73.75 - this.type = type;
73.76 - this.lhs = lhs;
73.77 - this.methodExpected = methodExpected;
73.78 - if (lhs == null) {
73.79 - lhs = type;
73.80 - }
73.81 - this.isStatic = isStatic;
73.82 - }
73.83 -
73.84 - public String getType() {
73.85 - return type;
73.86 - }
73.87 -
73.88 - public String getLhs() {
73.89 - return lhs;
73.90 - }
73.91 -
73.92 - public boolean isStatic() {
73.93 - return isStatic;
73.94 - }
73.95 -
73.96 - public boolean isSimpleIdentifier() {
73.97 - if (lhs == null) {
73.98 - return false;
73.99 - }
73.100 - // TODO - replace with the new PythonUtil validations
73.101 - for (int i = 0, n = lhs.length(); i < n; i++) {
73.102 - char c = lhs.charAt(i);
73.103 - if (Character.isJavaIdentifierPart(c)) {
73.104 - continue;
73.105 - }
73.106 - return false;
73.107 - }
73.108 - return true;
73.109 - }
73.110 -
73.111 - @Override
73.112 - public String toString() {
73.113 - if (this == LOCAL) {
73.114 - return "LOCAL";
73.115 - } else if (this == NONE) {
73.116 - return "NONE";
73.117 - } else if (this == UNKNOWN) {
73.118 - return "UNKNOWN";
73.119 - } else {
73.120 - return "Call(" + type + "," + lhs + "," + isStatic + ")";
73.121 - }
73.122 - }
73.123 -
73.124 - /** foo.| or foo.b| -> we're expecting a method call. For Foo:: we don't know. */
73.125 - public boolean isMethodExpected() {
73.126 - return this.methodExpected;
73.127 - }
73.128 -
73.129 - /**
73.130 - * Determine whether the given offset corresponds to a method call on another
73.131 - * object. This would happen in these cases:
73.132 - * Foo::|, Foo::Bar::|, Foo.|, Foo.x|, foo.|, foo.x|
73.133 - * and not here:
73.134 - * |, Foo|, foo|
73.135 - * The method returns the left hand side token, if any, such as "Foo", Foo::Bar",
73.136 - * and "foo". If not, it will return null.
73.137 - * Note that "self" and "super" are possible return values for the lhs, which mean
73.138 - * that you don't have a call on another object. Clients of this method should
73.139 - * handle that return value properly (I could return null here, but clients probably
73.140 - * want to distinguish self and super in this case so it's useful to return the info.)
73.141 - *
73.142 - * This method will also try to be smart such that if you have a block or array
73.143 - * call, it will return the relevant classnames (e.g. for [1,2].x| it returns "Array").
73.144 - */
73.145 - @SuppressWarnings("unchecked")
73.146 - @NonNull
73.147 - public static Call getCallType(BaseDocument doc, TokenHierarchy<Document> th, int offset) {
73.148 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(th, offset);
73.149 -
73.150 - if (ts == null) {
73.151 - return Call.NONE;
73.152 - }
73.153 -
73.154 - ts.move(offset);
73.155 -
73.156 - boolean methodExpected = false;
73.157 -
73.158 - if (!ts.moveNext() && !ts.movePrevious()) {
73.159 - return Call.NONE;
73.160 - }
73.161 -
73.162 - if (ts.offset() == offset) {
73.163 - // We're looking at the offset to the RIGHT of the caret
73.164 - // position, which could be whitespace, e.g.
73.165 - // "foo.x| " <-- looking at the whitespace
73.166 - ts.movePrevious();
73.167 - }
73.168 -
73.169 - Token<? extends PythonTokenId> token = ts.token();
73.170 -
73.171 - if (token != null) {
73.172 - TokenId id = token.id();
73.173 -
73.174 - if (id == PythonTokenId.WHITESPACE) {
73.175 - return Call.LOCAL;
73.176 - }
73.177 -
73.178 - // See if we're in the identifier - "x" in "foo.x"
73.179 - // I could also be a keyword in case the prefix happens to currently
73.180 - // match a keyword, such as "next"
73.181 - // However, if we're at the end of the document, x. will lex . as an
73.182 - // identifier of text ".", so handle this case specially
73.183 - if ((id == PythonTokenId.IDENTIFIER)/* || (id == PythonTokenId.CONSTANT)*/ ||
73.184 - id.primaryCategory().equals("keyword")) {
73.185 - String tokenText = token.text().toString();
73.186 -
73.187 - if (".".equals(tokenText)) {
73.188 - // Special case - continue - we'll handle this part next
73.189 - methodExpected = true;
73.190 - } else {
73.191 - methodExpected = true;
73.192 -
73.193 - if (Character.isUpperCase(tokenText.charAt(0))) {
73.194 - methodExpected = false;
73.195 - }
73.196 -
73.197 - if (!ts.movePrevious()) {
73.198 - return Call.LOCAL;
73.199 - }
73.200 - }
73.201 -
73.202 - token = ts.token();
73.203 - id = token.id();
73.204 - }
73.205 -
73.206 - // If we're not in the identifier we need to be in the dot (in "foo.x").
73.207 - // I can't just check for tokens DOT and COLON3 because for unparseable source
73.208 - // (like "File.|") the lexer will return the "." as an identifier.
73.209 - if (id == PythonTokenId.DOT) {
73.210 - methodExpected = true;
73.211 - } else if (id == PythonTokenId.IDENTIFIER) {
73.212 - String t = token.text().toString();
73.213 -
73.214 - if (t.equals(".")) {
73.215 - methodExpected = true;
73.216 - } else {
73.217 - return Call.LOCAL;
73.218 - }
73.219 - } else {
73.220 - return Call.LOCAL;
73.221 - }
73.222 -
73.223 - int lastSeparatorOffset = ts.offset();
73.224 - int beginOffset = lastSeparatorOffset;
73.225 - int lineStart = 0;
73.226 -
73.227 - try {
73.228 - if (offset > doc.getLength()) {
73.229 - offset = doc.getLength();
73.230 - }
73.231 -
73.232 - lineStart = Utilities.getRowStart(doc, offset);
73.233 - } catch (BadLocationException ble) {
73.234 - Exceptions.printStackTrace(ble);
73.235 - }
73.236 -
73.237 - // Find the beginning of the expression. We'll go past keywords, identifiers
73.238 - // and dots or double-colons
73.239 - while (ts.movePrevious()) {
73.240 - // If we get to the previous line we're done
73.241 - if (ts.offset() < lineStart) {
73.242 - break;
73.243 - }
73.244 -
73.245 - token = ts.token();
73.246 - id = token.id();
73.247 -
73.248 - String tokenText = null;
73.249 - if (id == PythonTokenId.ANY_KEYWORD || id == PythonTokenId.IDENTIFIER) {
73.250 - tokenText = token.text().toString();
73.251 - }
73.252 -
73.253 - if (id == PythonTokenId.WHITESPACE) {
73.254 - break;
73.255 - } else if (id == PythonTokenId.RBRACKET) {
73.256 - return new Call("ListType", null, false, methodExpected);
73.257 - } else if (id == PythonTokenId.RBRACE) {
73.258 - return new Call("DictType", null, false, methodExpected);
73.259 - } else if ((id == PythonTokenId.STRING_END)/* || (id == PythonTokenId.QUOTED_STRING_END)*/) {
73.260 - return new Call("StringType", null, false, methodExpected);
73.261 - } else if ((id == PythonTokenId.IDENTIFIER) && "True".equals(tokenText)) { // NOI18N
73.262 - return new Call("BooleanType", null, false, methodExpected);
73.263 - } else if ((id == PythonTokenId.IDENTIFIER) && "False".equals(tokenText)) { // NOI18N
73.264 - return new Call("BooleanType", null, false, methodExpected);
73.265 - } else if (((id == PythonTokenId.IDENTIFIER)) ||
73.266 - id.primaryCategory().equals("keyword") || (id == PythonTokenId.DOT)) {
73.267 -
73.268 - // We're building up a potential expression such as "Test::Unit" so continue looking
73.269 - beginOffset = ts.offset();
73.270 -
73.271 - continue;
73.272 - } else if ((id == PythonTokenId.LPAREN) || (id == PythonTokenId.LBRACE) ||
73.273 - (id == PythonTokenId.LBRACKET)) {
73.274 - // It's an expression for example within a parenthesis, e.g.
73.275 - // yield(^File.join())
73.276 - // in this case we can do top level completion
73.277 - // TODO: There are probably more valid contexts here
73.278 - break;
73.279 - } else if (id == PythonTokenId.ANY_OPERATOR) {
73.280 - break;
73.281 - } else {
73.282 - // Something else - such as "getFoo().x|" - at this point we don't know the type
73.283 - // so we'll just return unknown
73.284 - return Call.UNKNOWN;
73.285 - }
73.286 - }
73.287 -
73.288 - if (beginOffset < lastSeparatorOffset) {
73.289 - try {
73.290 - String lhs = doc.getText(beginOffset, lastSeparatorOffset - beginOffset);
73.291 -
73.292 - if (lhs.equals("super") || lhs.equals("self")) { // NOI18N
73.293 -
73.294 - return new Call(lhs, lhs, false, true);
73.295 - } else if (Character.isUpperCase(lhs.charAt(0))) {
73.296 -
73.297 -// // Detect constructor calls of the form String.new.^
73.298 -// if (lhs.endsWith(".new")) { // NOI18N
73.299 -// // See if it looks like a type prior to that
73.300 -// String type = lhs.substring(0, lhs.length()-4); // 4=".new".length()
73.301 -// if (PythonUtils.isValidPythonModuleName(type)) {
73.302 -// return new Call(type, lhs, false, methodExpected);
73.303 -// }
73.304 -// }
73.305 -
73.306 - String type = null;
73.307 -// if (PythonUtils.isValidPythonModuleName(lhs)) {
73.308 - type = lhs;
73.309 -// }
73.310 -
73.311 - return new Call(type, lhs, true, methodExpected);
73.312 - } else {
73.313 - return new Call(null, lhs, false, methodExpected);
73.314 - }
73.315 - } catch (BadLocationException ble) {
73.316 - Exceptions.printStackTrace(ble);
73.317 - }
73.318 - } else {
73.319 - return Call.UNKNOWN;
73.320 - }
73.321 - }
73.322 -
73.323 - return Call.LOCAL;
73.324 - }
73.325 -}
74.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonCommentLexer.java Mon Aug 31 12:40:19 2015 +0200
74.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
74.3 @@ -1,229 +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 org.netbeans.api.lexer.Token;
74.50 -import org.netbeans.spi.lexer.Lexer;
74.51 -import org.netbeans.spi.lexer.LexerInput;
74.52 -import org.netbeans.spi.lexer.LexerRestartInfo;
74.53 -import org.netbeans.spi.lexer.TokenFactory;
74.54 -
74.55 -/**
74.56 - * A lexer for python comments.
74.57 - *
74.58 - * Highlights TODO items and certain keywords (like @-param and @-type (without -)).
74.59 - *
74.60 - * @author Tor Norbye
74.61 - */
74.62 -public class PythonCommentLexer implements Lexer<PythonCommentTokenId> {
74.63 - private static final int EOF = LexerInput.EOF;
74.64 - private final LexerInput input;
74.65 - private final TokenFactory<PythonCommentTokenId> tokenFactory;
74.66 - private final boolean substituting;
74.67 -
74.68 - private static enum State {
74.69 - INIT,
74.70 - /** We've just seen @type */
74.71 - SEEN_TYPE_KEY,
74.72 - /** We've just seen @type< > */
74.73 - SEEN_TYPE_WS,
74.74 - /** We've just seen @type <varname> */
74.75 - SEEN_NAME,
74.76 - /** We've just seen @type varname< > */
74.77 - SEEN_NAME_WS
74.78 - };
74.79 - private State state;
74.80 -
74.81 - /**
74.82 - * A Lexer for Python strings
74.83 - * @param substituting If true, handle substitution rules for double quoted strings, otherwise
74.84 - * single quoted strings.
74.85 - */
74.86 - public PythonCommentLexer(LexerRestartInfo<PythonCommentTokenId> info, boolean substituting) {
74.87 - this.input = info.input();
74.88 - this.tokenFactory = info.tokenFactory();
74.89 - this.substituting = substituting;
74.90 - state = (State)info.state();
74.91 - if (state == null) {
74.92 - state = State.INIT;
74.93 - }
74.94 - }
74.95 -
74.96 - @Override
74.97 - public Object state() {
74.98 - return state;
74.99 - }
74.100 -
74.101 - @Override
74.102 - public Token<PythonCommentTokenId> nextToken() {
74.103 - switch (state) {
74.104 - case SEEN_NAME:
74.105 - case SEEN_TYPE_KEY:
74.106 - while (true) {
74.107 - int ch = input.read();
74.108 - if (ch == ':' && state == State.SEEN_NAME && input.readLength() == 1) {
74.109 - continue;
74.110 - }
74.111 - if (ch == EOF || !Character.isWhitespace(ch)) {
74.112 - if (ch != EOF) {
74.113 - input.backup(1);
74.114 - }
74.115 - if (input.readLength() > 0) {
74.116 - state = (state == State.SEEN_TYPE_KEY) ? State.SEEN_TYPE_WS : State.SEEN_NAME_WS;
74.117 - return tokenFactory.createToken(PythonCommentTokenId.SEPARATOR,
74.118 - input.readLength());
74.119 - } else {
74.120 - return null;
74.121 - }
74.122 - }
74.123 - }
74.124 -
74.125 - case SEEN_NAME_WS:
74.126 - case SEEN_TYPE_WS:
74.127 - while (true) {
74.128 - int ch = input.read();
74.129 - if (ch == EOF || Character.isWhitespace(ch) || ch == ':') {
74.130 - if (ch != EOF) {
74.131 - input.backup(1);
74.132 - }
74.133 - if (input.readLength() > 0) {
74.134 - State nextState;
74.135 - PythonCommentTokenId id;
74.136 - if (state == State.SEEN_TYPE_WS) {
74.137 - nextState = State.SEEN_NAME;
74.138 - id = PythonCommentTokenId.VARNAME;
74.139 - } else {
74.140 - nextState = State.INIT;
74.141 - id = PythonCommentTokenId.TYPE;
74.142 - }
74.143 - state = nextState;
74.144 - return tokenFactory.createToken(id, input.readLength());
74.145 - } else if (ch == EOF) {
74.146 - return null;
74.147 - } else {
74.148 - // Error - : without an actual var name
74.149 - state = State.INIT;
74.150 - return nextToken(); // recurse
74.151 - }
74.152 - }
74.153 - }
74.154 - default:
74.155 - case INIT: {
74.156 -
74.157 - int last = EOF;
74.158 - while (true) {
74.159 - int ch = input.read();
74.160 -
74.161 - switch (ch) {
74.162 - case EOF:
74.163 - if (input.readLength() > 0) {
74.164 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
74.165 - input.readLength());
74.166 - } else {
74.167 - return null;
74.168 - }
74.169 -
74.170 - case '@': {
74.171 - // Is it "@type"
74.172 - int initialReadLength = input.readLength();
74.173 - if (input.read() == 't' && input.read() == 'y' && input.read() == 'p' && input.read() == 'e') {
74.174 - if (input.readLength() > 5) {
74.175 - input.backup(5);
74.176 - // Finish this token such that we can do a dedicated token for the @type item.
74.177 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
74.178 - input.readLength());
74.179 - }
74.180 - state = State.SEEN_TYPE_KEY;
74.181 - return tokenFactory.createToken(PythonCommentTokenId.TYPEKEY,
74.182 - input.readLength());
74.183 - }
74.184 - if (input.readLength() > initialReadLength) {
74.185 - input.backup(input.readLength() - initialReadLength);
74.186 - } else {
74.187 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
74.188 - input.readLength());
74.189 - }
74.190 - }
74.191 - break;
74.192 -
74.193 - case 'T': {
74.194 - if (last == EOF || !Character.isLetter(last)) {
74.195 - // Is it "\wTODO\w" ?
74.196 - int initialReadLength = input.readLength();
74.197 - if (input.read() == 'O' && input.read() == 'D' && input.read() == 'O') {
74.198 - int peek = input.read();
74.199 - input.backup(1);
74.200 - if (peek == EOF || !Character.isLetter(peek)) {
74.201 - if (input.readLength() > 4) {
74.202 - input.backup(4);
74.203 - // Finish this token such that we can do a dedicated token for the @type item.
74.204 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
74.205 - input.readLength());
74.206 - }
74.207 - return tokenFactory.createToken(PythonCommentTokenId.TODO,
74.208 - input.readLength());
74.209 - }
74.210 - }
74.211 - if (input.readLength() > initialReadLength) {
74.212 - input.backup(input.readLength() - initialReadLength);
74.213 - } else {
74.214 - return tokenFactory.createToken(PythonCommentTokenId.TEXT,
74.215 - input.readLength());
74.216 - }
74.217 - }
74.218 - }
74.219 - break;
74.220 - }
74.221 -
74.222 - last = ch;
74.223 - }
74.224 -
74.225 - }
74.226 - }
74.227 - }
74.228 -
74.229 - @Override
74.230 - public void release() {
74.231 - }
74.232 -}
75.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonCommentTokenId.java Mon Aug 31 12:40:19 2015 +0200
75.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
75.3 @@ -1,120 +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 java.util.Collection;
75.50 -import java.util.EnumSet;
75.51 -import java.util.Map;
75.52 -
75.53 -import org.netbeans.api.lexer.InputAttributes;
75.54 -import org.netbeans.api.lexer.Language;
75.55 -import org.netbeans.api.lexer.LanguagePath;
75.56 -import org.netbeans.api.lexer.Token;
75.57 -import org.netbeans.api.lexer.TokenId;
75.58 -import org.netbeans.spi.lexer.LanguageEmbedding;
75.59 -import org.netbeans.spi.lexer.LanguageHierarchy;
75.60 -import org.netbeans.spi.lexer.Lexer;
75.61 -import org.netbeans.spi.lexer.LexerRestartInfo;
75.62 -
75.63 -/**
75.64 - *
75.65 - * @author Tor Norbye
75.66 - */
75.67 -public enum PythonCommentTokenId implements TokenId {
75.68 - TEXT("comment"),
75.69 - KEYWORD("comment"),
75.70 - SEPARATOR("comment"),
75.71 - TYPEKEY("comment"),
75.72 - VARNAME("comment"),
75.73 - TYPE("comment"),
75.74 - TODO("comment");
75.75 - private final String primaryCategory;
75.76 -
75.77 - PythonCommentTokenId() {
75.78 - this(null);
75.79 - }
75.80 -
75.81 - PythonCommentTokenId(String primaryCategory) {
75.82 - this.primaryCategory = primaryCategory;
75.83 - }
75.84 -
75.85 - @Override
75.86 - public String primaryCategory() {
75.87 - return primaryCategory;
75.88 - }
75.89 - public static final Language<PythonCommentTokenId> language =
75.90 - new LanguageHierarchy<PythonCommentTokenId>() {
75.91 - @Override
75.92 - protected Collection<PythonCommentTokenId> createTokenIds() {
75.93 - return EnumSet.allOf(PythonCommentTokenId.class);
75.94 - }
75.95 -
75.96 - @Override
75.97 - protected Map<String, Collection<PythonCommentTokenId>> createTokenCategories() {
75.98 - return null; // no extra categories
75.99 - }
75.100 -
75.101 - @Override
75.102 - protected Lexer<PythonCommentTokenId> createLexer(
75.103 - LexerRestartInfo<PythonCommentTokenId> info) {
75.104 - return new PythonCommentLexer(info, true);
75.105 - }
75.106 -
75.107 - @Override
75.108 - protected LanguageEmbedding<?> embedding(
75.109 - Token<PythonCommentTokenId> token, LanguagePath languagePath,
75.110 - InputAttributes inputAttributes) {
75.111 - return null; // No embedding
75.112 - }
75.113 -
75.114 - @Override
75.115 - public String mimeType() {
75.116 - return "text/x-python-comment"; // NOI18N
75.117 - }
75.118 - }.language();
75.119 -
75.120 - public static Language<PythonCommentTokenId> language() {
75.121 - return language;
75.122 - }
75.123 -}
76.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonLexer.java Mon Aug 31 12:40:19 2015 +0200
76.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
76.3 @@ -1,928 +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 org.netbeans.api.lexer.Token;
76.50 -import org.netbeans.api.lexer.TokenUtilities;
76.51 -import org.netbeans.spi.lexer.Lexer;
76.52 -import org.netbeans.spi.lexer.LexerInput;
76.53 -import org.netbeans.spi.lexer.LexerRestartInfo;
76.54 -import org.netbeans.spi.lexer.TokenFactory;
76.55 -
76.56 -/**
76.57 - * Lexer for Python.
76.58 - *
76.59 - * This is a hand written lexer for Python which recognizes the logical token types
76.60 - * we care about within the IDE support.
76.61 - *
76.62 - * Initially, we were using Jython's lexer directly here. However, that had some
76.63 - * problems:
76.64 - *
76.65 - * <ul>
76.66 - * <li>
76.67 - * In the IDE, we have to support incremental parsing. Not only is this a must
76.68 - * from a user performance perspective (typing a keystroke near the bottom of a
76.69 - * 2,000 line file shouldn't cause complete re-lexing of the entire document), but
76.70 - * the NetBeans APIs require it; they restart the lexer on the nearest token
76.71 - * boundary.
76.72 - * ANTLR doesn't support incremental lexing. I looked into what it would take
76.73 - * to patch it to do so (as I have done for JRuby in the Ruby support), but
76.74 - * it (a) wasn't trivial, and (b) would require a LOT of data to be stored for
76.75 - * every token boundary.
76.76 - * </li>
76.77 - * <li>
76.78 - * Similarly, we need to put our lexer on top of a LexerInput, and it is not
76.79 - * particularly compatible with the way ANTLR handles input. We had an
76.80 - * adapter class for this which was jumping through various hoops to expose
76.81 - * the LexerInput as ANTLR input. However, it had some severe problems with
76.82 - * large inputs.
76.83 - * </li>
76.84 - * <li>
76.85 - * We need slightly different token divisions. For example, for matching bracket
76.86 - * purposes, we'd like to have strings split into string delimiters and the
76.87 - * string contents. Similarly, Jython did some things like coalesce all whitespace
76.88 - * around a newline into that newline token which causes some complications
76.89 - * for our token analysis.
76.90 - * </li>
76.91 - * <li>
76.92 - * For Ruby, I decided to use the JRuby lexer because JRuby lexing is very
76.93 - * difficult. They have a huge complicated class to do the lexing - and there's
76.94 - * no Ruby language spec. Python on the other hand seems to have a very simple
76.95 - * lexing model, and a clear spec and grammar, so I don't feel worried that
76.96 - * our custom Python lexer is going to have a lot of corner case bugs.
76.97 - * </li>
76.98 - * </ul>
76.99 - *
76.100 - * @author Tor Norbye
76.101 - */
76.102 -public final class PythonLexer implements Lexer<PythonTokenId> {
76.103 - public static final String COMMENT_CAT = "comment";
76.104 - public static final String KEYWORD_CAT = "keyword"; // NOI18N
76.105 - public static final String STRING_CAT = "string"; // NOI18N
76.106 - public static final String WHITESPACE_CAT = "whitespace"; // NOI18N
76.107 - public static final String OPERATOR_CAT = "operator"; // NOI18N
76.108 - public static final String SEPARATOR_CAT = "separator"; // NOI18N
76.109 - public static final String ERROR_CAT = "error"; // NOI18N
76.110 - public static final String NUMBER_CAT = "number"; // NOI18N
76.111 - public static final String IDENTIFIER_CAT = "identifier"; // NOI18N
76.112 - private static final int EOF = LexerInput.EOF;
76.113 - private final LexerInput input;
76.114 - private final TokenFactory<PythonTokenId> tokenFactory;
76.115 -
76.116 - // Lexer state - preserved per token boundary
76.117 - private enum State {
76.118 - /** Normal state, same state as on entry into a Python file */
76.119 - INIT,
76.120 - /** We've processed the beginning string delimiter of a double-quoted short string */
76.121 - BEGIN_SHORTSTRING_DOUBLE,
76.122 - /** We've processed the beginning string delimiter of a single-quoted short string */
76.123 - BEGIN_SHORTSTRING_SINGLE,
76.124 - /** We've processed the beginning string delimiter of a double-quoted long string */
76.125 - BEGIN_LONGSTRING_DOUBLE,
76.126 - /** We've processed the beginning string delimiter of a singl-quoted long string */
76.127 - BEGIN_LONGSTRING_SINGLE,
76.128 - /** We've processed the string content in a double-quoted short string */
76.129 - END_SHORTSTRING_DOUBLE,
76.130 - /** We've processed the string content in a single-quoted short string */
76.131 - END_SHORTSTRING_SINGLE,
76.132 - /** We've processed the string content in a double-quoted long string */
76.133 - END_LONGSTRING_DOUBLE,
76.134 - /** We've processed the string content in a single-quoted long string */
76.135 - END_LONGSTRING_SINGLE,
76.136 - };
76.137 - private State state;
76.138 -
76.139 - public PythonLexer(LexerRestartInfo<PythonTokenId> info) {
76.140 - this.input = info.input();
76.141 - this.tokenFactory = info.tokenFactory();
76.142 -
76.143 - state = (State)info.state();
76.144 - if (state == null) {
76.145 - state = State.INIT;
76.146 - }
76.147 - }
76.148 -
76.149 - @Override
76.150 - public Object state() {
76.151 - return state;
76.152 - }
76.153 -
76.154 - private Token<PythonTokenId> createToken(PythonTokenId id, int tokenLength) {
76.155 - String fixedText = id.fixedText();
76.156 - return (fixedText != null) ? tokenFactory.getFlyweightToken(id, fixedText)
76.157 - : tokenFactory.createToken(id, tokenLength);
76.158 - }
76.159 -
76.160 - @SuppressWarnings("fallthrough")
76.161 - @Override
76.162 - public Token<PythonTokenId> nextToken() {
76.163 - switch (state) {
76.164 - case INIT: {
76.165 - int ch = input.read();
76.166 - switch (ch) {
76.167 - case EOF:
76.168 - return null;
76.169 -
76.170 - // Newline
76.171 - case '\n':
76.172 - assert input.readLength() == 1;
76.173 - return createToken(PythonTokenId.NEWLINE, 1);
76.174 -
76.175 - // Whitespace
76.176 - case ' ':
76.177 - case '\t': {
76.178 - for (; ch != EOF; ch = input.read()) {
76.179 - if (ch != ' ' && ch != '\t') {
76.180 - break;
76.181 - }
76.182 - }
76.183 - input.backup(1);
76.184 - return createToken(PythonTokenId.WHITESPACE, input.readLength());
76.185 - }
76.186 -
76.187 - // Comment
76.188 - case '#': {
76.189 - ch = input.read();
76.190 - while (ch != EOF && ch != '\n') {
76.191 - ch = input.read();
76.192 - }
76.193 - input.backup(1);
76.194 - return createToken(PythonTokenId.COMMENT, input.readLength());
76.195 - }
76.196 -
76.197 - case '.': {
76.198 - assert input.readLength() == 1;
76.199 - int peek = input.read();
76.200 - input.backup(1);
76.201 - if (!Character.isDigit(peek)) {
76.202 - return createToken(PythonTokenId.DOT, 1);
76.203 - } // else: Fallthrough to process the number!!
76.204 - } // FALLTHROUGH
76.205 - // FALLTHROUGH!!!!
76.206 -
76.207 - // Number (integer, float, complex)
76.208 - case '0':
76.209 - case '1':
76.210 - case '2':
76.211 - case '3':
76.212 - case '4':
76.213 - case '5':
76.214 - case '6':
76.215 - case '7':
76.216 - case '8':
76.217 - case '9': {
76.218 - if (ch == '0') {
76.219 - int peek = input.read();
76.220 - if (peek == 'x' || peek == 'X') {
76.221 - // Hex
76.222 - ch = input.read();
76.223 - while (ch != EOF) {
76.224 - if (!(Character.isDigit(ch) ||
76.225 - (ch >= 'a' && ch <= 'f') ||
76.226 - (ch >= 'A' && ch <= 'F'))) {
76.227 - break;
76.228 - }
76.229 - ch = input.read();
76.230 - }
76.231 - if (ch != 'l' && (ch != 'L')) {
76.232 - input.backup(1);
76.233 - }
76.234 - return createToken(PythonTokenId.INT_LITERAL, input.readLength());
76.235 - }
76.236 - input.backup(1);
76.237 - }
76.238 - boolean isFloat = false;
76.239 - digitLoop:
76.240 - for (; ch != EOF; ch = input.read()) {
76.241 - switch (ch) {
76.242 - case '0':
76.243 - case '1':
76.244 - case '2':
76.245 - case '3':
76.246 - case '4':
76.247 - case '5':
76.248 - case '6':
76.249 - case '7':
76.250 - case '8':
76.251 - case '9':
76.252 - continue;
76.253 - case '.':
76.254 - isFloat = true;
76.255 - continue;
76.256 - case 'e': // Exponent
76.257 - case 'E': {
76.258 - int peek = input.read();
76.259 - if (peek != '+' && peek != '-') {
76.260 - input.backup(1);
76.261 - }
76.262 - ch = input.read();
76.263 - while (ch != EOF) {
76.264 - if (!Character.isDigit(ch)) {
76.265 - break;
76.266 - }
76.267 - ch = input.read();
76.268 - }
76.269 - if (ch != 'j' && ch != 'J') {
76.270 - input.backup(1);
76.271 - }
76.272 - return createToken(PythonTokenId.FLOAT_LITERAL, input.readLength());
76.273 - }
76.274 - case 'j': // Imaginary
76.275 - case 'J':
76.276 - isFloat = true;
76.277 - break digitLoop;
76.278 - case 'l': // Long
76.279 - case 'L':
76.280 - break digitLoop;
76.281 - case EOF:
76.282 - default:
76.283 - input.backup(1);
76.284 - break digitLoop;
76.285 -
76.286 - }
76.287 - }
76.288 -
76.289 - return createToken(isFloat ? PythonTokenId.FLOAT_LITERAL : PythonTokenId.INT_LITERAL, input.readLength());
76.290 - }
76.291 -
76.292 - // Operators and delimiters
76.293 - case '+': // +,+=
76.294 - if (input.read() != '=') {
76.295 - input.backup(1);
76.296 - }
76.297 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.298 - case '-': // -,-=
76.299 - if (input.read() != '=') {
76.300 - input.backup(1);
76.301 - }
76.302 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.303 - case '*': { // *,**,*=, **=
76.304 - int peek = input.read();
76.305 - if (peek == '=') {
76.306 - // No need to back up, include it
76.307 - } else if (peek == '*') {
76.308 - peek = input.read();
76.309 - if (peek != '=') {
76.310 - input.backup(1);
76.311 - }
76.312 - } else {
76.313 - input.backup(1);
76.314 - }
76.315 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.316 - }
76.317 - case '/': {
76.318 - // Look for /,//, /=, //=
76.319 - int peek = input.read();
76.320 - if (peek == '=') {
76.321 - // No need to back up, include it
76.322 - } else if (peek == '/') {
76.323 - peek = input.read();
76.324 - if (peek != '=') {
76.325 - input.backup(1);
76.326 - }
76.327 - } else {
76.328 - input.backup(1);
76.329 - }
76.330 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.331 - }
76.332 - case '%': { // Look for %, %=
76.333 - if (input.read() != '=') {
76.334 - input.backup(1);
76.335 - }
76.336 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.337 - }
76.338 - case '<': {
76.339 - // Look for <, <<, <=, <>, <<=
76.340 - int peek = input.read();
76.341 - if (peek == '=') {
76.342 - // No need to back up, include it
76.343 - } else if (peek == '<') {
76.344 - peek = input.read();
76.345 - if (peek != '=') {
76.346 - input.backup(1);
76.347 - }
76.348 - } else if (peek != '>') {
76.349 - input.backup(1);
76.350 - }
76.351 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.352 - }
76.353 - case '>': {
76.354 - // Look for >, >>, >=, >>=
76.355 - int peek = input.read();
76.356 - if (peek == '=') {
76.357 - // No need to back up, include it
76.358 - } else if (peek == '>') {
76.359 - peek = input.read();
76.360 - if (peek != '=') {
76.361 - input.backup(1);
76.362 - }
76.363 - } else {
76.364 - input.backup(1);
76.365 - }
76.366 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.367 - }
76.368 - case '&': { // Look for &,&=
76.369 - if (input.read() != '=') {
76.370 - input.backup(1);
76.371 - }
76.372 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.373 - }
76.374 - case '|': { // Look for |, |=
76.375 - if (input.read() != '=') {
76.376 - input.backup(1);
76.377 - }
76.378 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.379 - }
76.380 - case '^': { // ^,^=
76.381 - if (input.read() != '=') {
76.382 - input.backup(1);
76.383 - }
76.384 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.385 - }
76.386 - case '=': {
76.387 - // Look for =,==
76.388 - if (input.read() != '=') {
76.389 - input.backup(1);
76.390 - }
76.391 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.392 - }
76.393 - case '!': {
76.394 - // Look for !=
76.395 - if (input.read() != '=') {
76.396 - input.backup(1);
76.397 - }
76.398 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.399 - }
76.400 - case '~':
76.401 - case '`':
76.402 - case ';':
76.403 - return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
76.404 -
76.405 - case ':':
76.406 - assert input.readLength() == 1;
76.407 - return createToken(PythonTokenId.COLON, 1);
76.408 - case '(':
76.409 - assert input.readLength() == 1;
76.410 - return createToken(PythonTokenId.LPAREN, 1);
76.411 - case ')':
76.412 - assert input.readLength() == 1;
76.413 - return createToken(PythonTokenId.RPAREN, 1);
76.414 - case '[':
76.415 - assert input.readLength() == 1;
76.416 - return createToken(PythonTokenId.LBRACKET, 1);
76.417 - case ']':
76.418 - assert input.readLength() == 1;
76.419 - return createToken(PythonTokenId.RBRACKET, 1);
76.420 - case '{':
76.421 - assert input.readLength() == 1;
76.422 - return createToken(PythonTokenId.LBRACE, 1);
76.423 - case '}':
76.424 - assert input.readLength() == 1;
76.425 - return createToken(PythonTokenId.RBRACE, 1);
76.426 - case ',':
76.427 - assert input.readLength() == 1;
76.428 - return createToken(PythonTokenId.COMMA, 1);
76.429 - case '\\':
76.430 - assert input.readLength() == 1;
76.431 - return createToken(PythonTokenId.ESC, 1);
76.432 -
76.433 - case '$':
76.434 - case '?':
76.435 - assert input.readLength() == 1;
76.436 - return createToken(PythonTokenId.ERROR, 1);
76.437 -
76.438 - // String?
76.439 - case '\'':
76.440 - case '"': {
76.441 - int peek = input.read();
76.442 - if (peek != ch) {
76.443 - input.backup(1);
76.444 - assert input.readLength() == 1;
76.445 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
76.446 - return createToken(PythonTokenId.STRING_BEGIN, 1);
76.447 - }
76.448 - // We've seen two quotes... it's either an empty string,
76.449 - // or the beginning of a longstring
76.450 - int peek2 = input.read();
76.451 - if (peek2 == peek) {
76.452 - // It's a longstring!
76.453 - assert input.readLength() == 3;
76.454 - state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
76.455 - return createToken(PythonTokenId.STRING_BEGIN, 3);
76.456 - } else {
76.457 - input.backup(2);
76.458 - assert input.readLength() == 1;
76.459 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
76.460 - return createToken(PythonTokenId.STRING_BEGIN, 1);
76.461 - }
76.462 - }
76.463 - case '@': { // Decorator
76.464 - // Identifier or keyword?
76.465 - ch = input.read();
76.466 - if (Character.isJavaIdentifierStart(ch)) {
76.467 - while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
76.468 - ch = input.read();
76.469 - }
76.470 - input.backup(1);
76.471 -
76.472 - return createToken(PythonTokenId.DECORATOR, input.readLength());
76.473 - }
76.474 - input.backup(1); // Remove the peeked char
76.475 -
76.476 - assert input.readLength() == 1;
76.477 - return createToken(PythonTokenId.DECORATOR, 1);
76.478 - }
76.479 -
76.480 - case 'r':
76.481 - case 'R':
76.482 - case 'u':
76.483 - case 'U': {
76.484 - // Digest the "u" and the "r" and position the input
76.485 - // before the following ' or "
76.486 - boolean isStringPrefix = false;
76.487 - int peek = input.read();
76.488 - if (ch == 'r' || ch == 'R') {
76.489 - if (peek == '\'' || peek == '"') {
76.490 - isStringPrefix = true;
76.491 - }
76.492 - input.backup(1);
76.493 - } else {
76.494 - assert ch == 'u' || ch == 'U';
76.495 - if (peek == 'r' || peek == 'R') {
76.496 - int peek2 = input.read();
76.497 - if (peek2 == '\'' || peek2 == '"') {
76.498 - isStringPrefix = true;
76.499 - }
76.500 - input.backup(1);
76.501 - } else if (peek == '\'' || peek == '"') {
76.502 - isStringPrefix = true;
76.503 - input.backup(1);
76.504 - }
76.505 - if (!isStringPrefix) {
76.506 - input.backup(1);
76.507 - }
76.508 - }
76.509 - if (isStringPrefix) {
76.510 - ch = input.read();
76.511 - assert ch == '\'' || ch == '"';
76.512 -
76.513 - peek = input.read();
76.514 - if (peek != ch) {
76.515 - input.backup(1);
76.516 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
76.517 - return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
76.518 - }
76.519 - // We've seen two quotes... it's either an empty string,
76.520 - // or the beginning of a longstring
76.521 - int peek2 = input.read();
76.522 - if (peek2 == peek) {
76.523 - // It's a longstring!
76.524 - state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
76.525 - return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
76.526 - } else {
76.527 - input.backup(2);
76.528 - state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
76.529 - return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
76.530 - }
76.531 - }// else: FALLTHROUGH!!! The "u" or "r" is probably an identifier prefix!!
76.532 - }
76.533 - // Fallthrough...
76.534 -
76.535 - default: {
76.536 - // Identifier or keyword?
76.537 - if (Character.isJavaIdentifierStart(ch)) {
76.538 - while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
76.539 - ch = input.read();
76.540 - }
76.541 - input.backup(1);
76.542 -
76.543 - // See if it's a keyword
76.544 - PythonTokenId pid = getKeywordToken(input.readText());
76.545 - if (pid != null) {
76.546 - return createToken(pid, input.readLength());
76.547 - } else {
76.548 - return createToken(PythonTokenId.IDENTIFIER, input.readLength());
76.549 - }
76.550 - }
76.551 -
76.552 - assert input.readLength() == 1;
76.553 - return createToken(PythonTokenId.ANY_OPERATOR, 1);
76.554 - }
76.555 - }
76.556 - }
76.557 -
76.558 - case BEGIN_LONGSTRING_SINGLE:
76.559 - case BEGIN_LONGSTRING_DOUBLE: {
76.560 - // In a long string. Look for the end.
76.561 - int ch = input.read();
76.562 - if (ch == EOF) {
76.563 - return null;
76.564 - }
76.565 - int term = (state == State.BEGIN_LONGSTRING_DOUBLE) ? '"' : '\'';
76.566 - while (ch != EOF) {
76.567 - if (ch == '\\') {
76.568 - // It's an escape - read escaped char
76.569 - input.read();
76.570 - } else if (ch == term) {
76.571 - int peek = input.read();
76.572 - if (peek == term) {
76.573 - int peek2 = input.read();
76.574 - if (peek2 == term) {
76.575 - // Found the end
76.576 - if (input.readLength() == 3) {
76.577 - // Empty string - go straight to closed state
76.578 - state = State.INIT;
76.579 - return createToken(PythonTokenId.STRING_END, input.readLength());
76.580 - }
76.581 - input.backup(3);
76.582 - if (state == State.BEGIN_LONGSTRING_DOUBLE) {
76.583 - state = State.END_LONGSTRING_DOUBLE;
76.584 - } else {
76.585 - assert state == State.BEGIN_LONGSTRING_SINGLE;
76.586 - state = State.END_LONGSTRING_SINGLE;
76.587 - }
76.588 - return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
76.589 - }
76.590 - input.backup(1);
76.591 - }
76.592 - input.backup(1);
76.593 - }
76.594 - ch = input.read();
76.595 - }
76.596 - // Literal not terminated
76.597 - state = State.INIT;
76.598 - return createToken(PythonTokenId.ERROR, input.readLength());
76.599 - }
76.600 - case BEGIN_SHORTSTRING_SINGLE:
76.601 - case BEGIN_SHORTSTRING_DOUBLE: {
76.602 - // In a short string. Look for the end.
76.603 - int ch = input.read();
76.604 - if (ch == EOF) {
76.605 - return null;
76.606 - }
76.607 - int term = (state == State.BEGIN_SHORTSTRING_DOUBLE) ? '"' : '\'';
76.608 - while (ch != EOF) {
76.609 - if (ch == '\\') {
76.610 - // It's an escape - read escaped char
76.611 - input.read();
76.612 - } else if (ch == '\n') {
76.613 - // Literal not terminated
76.614 - state = State.INIT;
76.615 - return createToken(PythonTokenId.ERROR, input.readLength());
76.616 - } else if (ch == term) {
76.617 - if (input.readLength() == 1) {
76.618 - // It's an empty string! Skip straight to the end state
76.619 - state = State.INIT;
76.620 - return createToken(PythonTokenId.STRING_END, input.readLength());
76.621 - }
76.622 - input.backup(1);
76.623 - if (state == State.BEGIN_SHORTSTRING_DOUBLE) {
76.624 - state = State.END_SHORTSTRING_DOUBLE;
76.625 - } else {
76.626 - assert state == State.BEGIN_SHORTSTRING_SINGLE;
76.627 - state = State.END_SHORTSTRING_SINGLE;
76.628 - }
76.629 - return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
76.630 - }
76.631 - ch = input.read();
76.632 - }
76.633 - // Literal not terminated
76.634 - state = State.INIT;
76.635 - return createToken(PythonTokenId.ERROR, input.readLength());
76.636 - }
76.637 -
76.638 - case END_LONGSTRING_SINGLE:
76.639 - case END_LONGSTRING_DOUBLE: {
76.640 - // In a long string. Look for the end.
76.641 - int ch = input.read();
76.642 - if (ch == EOF) {
76.643 - return null;
76.644 - }
76.645 - int term = (state == State.END_LONGSTRING_DOUBLE) ? '"' : '\'';
76.646 - while (ch != EOF) {
76.647 - if (ch == term) {
76.648 - int peek = input.read();
76.649 - if (peek == term) {
76.650 - int peek2 = input.read();
76.651 - if (peek2 == term) {
76.652 - // Found the end
76.653 - state = State.INIT;
76.654 - return createToken(PythonTokenId.STRING_END, input.readLength());
76.655 - }
76.656 - input.backup(1);
76.657 - }
76.658 - input.backup(1);
76.659 - }
76.660 - ch = input.read();
76.661 - }
76.662 - // Literal not terminated
76.663 - state = State.INIT;
76.664 - return createToken(PythonTokenId.ERROR, input.readLength());
76.665 - }
76.666 - case END_SHORTSTRING_SINGLE:
76.667 - case END_SHORTSTRING_DOUBLE: {
76.668 - // In a short string. Look for the end.
76.669 - int ch = input.read();
76.670 - if (ch == EOF) {
76.671 - return null;
76.672 - }
76.673 - int term = (state == State.END_SHORTSTRING_DOUBLE) ? '"' : '\'';
76.674 - if (ch == term) {
76.675 - state = State.INIT;
76.676 - return createToken(PythonTokenId.STRING_END, input.readLength());
76.677 - }
76.678 - state = State.INIT;
76.679 - return createToken(PythonTokenId.ERROR, input.readLength());
76.680 - }
76.681 -
76.682 - default:
76.683 - assert false : state;
76.684 - }
76.685 -
76.686 - return null;
76.687 - }
76.688 -
76.689 - @Override
76.690 - public void release() {
76.691 - }
76.692 -
76.693 - private PythonTokenId getKeywordToken(CharSequence s) {
76.694 - int length = s.length();
76.695 - if (length < 2) {
76.696 - return null;
76.697 - }
76.698 -
76.699 - if (s.toString().endsWith("Error")) {
76.700 - return PythonTokenId.ERROR;
76.701 - }
76.702 -
76.703 - char c1 = s.charAt(0);
76.704 - char c2 = s.charAt(1);
76.705 -
76.706 - switch (c1) {
76.707 - case 'a': // and, as, assert, async, await
76.708 - switch (c2) {
76.709 - case 'n': // and
76.710 - if (TokenUtilities.textEquals(s, "and")) { // NOI18N
76.711 - return PythonTokenId.ANY_KEYWORD;
76.712 - }
76.713 - break;
76.714 - case 's': // as, assert, async
76.715 - if (length == 2) { // as
76.716 - return PythonTokenId.ANY_KEYWORD;
76.717 - }
76.718 - if (length == 6 && TokenUtilities.textEquals(s, "assert")) { // NOI18N
76.719 - return PythonTokenId.ANY_KEYWORD;
76.720 - }
76.721 - if (length == 5 && TokenUtilities.textEquals(s, "async")) { // NOI18N
76.722 - return PythonTokenId.ANY_KEYWORD;
76.723 - }
76.724 - break;
76.725 - case 'w': // await
76.726 - if (length == 5 && TokenUtilities.textEquals(s, "await")) { // NOI18N
76.727 - return PythonTokenId.ANY_KEYWORD;
76.728 - }
76.729 - }
76.730 - break;
76.731 - case 'b': // break, bytes
76.732 - if (length == 5 && TokenUtilities.textEquals(s, "break")) { // NOI18N
76.733 - return PythonTokenId.ANY_KEYWORD;
76.734 - } else if (length == 5 && TokenUtilities.textEquals(s, "bytes")) { // NOI18N
76.735 - return PythonTokenId.STD_SYMBOLS;
76.736 - }
76.737 - break;
76.738 - case 'c': // class, continue
76.739 - switch (c2) {
76.740 - case 'l': // class
76.741 - if (length == 5 && TokenUtilities.textEquals(s, "class")) { // NOI18N
76.742 - return PythonTokenId.CLASS;
76.743 - }
76.744 - break;
76.745 - case 'o': // continue
76.746 - if (length == 8 && TokenUtilities.textEquals(s, "continue")) { // NOI18N
76.747 - return PythonTokenId.ANY_KEYWORD;
76.748 - }
76.749 - break;
76.750 - }
76.751 - break;
76.752 - case 'd': // def, del
76.753 - if (c2 == 'e' && length == 3) { // def, del
76.754 - char c3 = s.charAt(2);
76.755 - if (c3 == 'f') { // def
76.756 - return PythonTokenId.DEF;
76.757 - } else if (c3 == 'l') { // del
76.758 - return PythonTokenId.ANY_KEYWORD;
76.759 - }
76.760 - }
76.761 - break;
76.762 - case 'e': // elif, else, except, exec
76.763 - switch (c2) {
76.764 - case 'l': // elif, else
76.765 - if (length == 4) {
76.766 - if (TokenUtilities.textEquals(s, "elif")) { // NOI18N
76.767 - return PythonTokenId.ELIF;
76.768 - }
76.769 - if (TokenUtilities.textEquals(s, "else")) { // NOI18N
76.770 - return PythonTokenId.ELSE;
76.771 - }
76.772 - }
76.773 - break;
76.774 - case 'n': // enumerate
76.775 - if (length == 9 && TokenUtilities.textEquals(s, "enumerate")) { // NOI18N
76.776 - return PythonTokenId.STD_SYMBOLS;
76.777 - }
76.778 - case 'x': // except, exec
76.779 - if (length == 4 && TokenUtilities.textEquals(s, "exec")) { // NOI18N
76.780 - return PythonTokenId.ANY_KEYWORD;
76.781 - }
76.782 - if (length == 6 && TokenUtilities.textEquals(s, "except")) { // NOI18N
76.783 - return PythonTokenId.EXCEPT;
76.784 - }
76.785 - break;
76.786 - }
76.787 - break;
76.788 - case 'f': // finally,for,from
76.789 - switch (c2) {
76.790 - case 'i': // finally
76.791 - if (length == 7 && TokenUtilities.textEquals(s, "finally")) { // NOI18N
76.792 - return PythonTokenId.FINALLY;
76.793 - }
76.794 - break;
76.795 - case 'o': // for
76.796 - if (length == 3 && TokenUtilities.textEquals(s, "for")) { // NOI18N
76.797 - return PythonTokenId.ANY_KEYWORD;
76.798 - }
76.799 - break;
76.800 - case 'r': // from
76.801 - if (length == 4 && TokenUtilities.textEquals(s, "from")) { // NOI18N
76.802 - return PythonTokenId.FROM;
76.803 - }
76.804 - break;
76.805 - case 'l':
76.806 - if (length == 5 && TokenUtilities.textEquals(s, "float")) {
76.807 - return PythonTokenId.STD_SYMBOLS;
76.808 - }
76.809 - }
76.810 - break;
76.811 - case 'g': // global
76.812 - if (length == 6 && TokenUtilities.textEquals(s, "global")) { // NOI18N
76.813 - return PythonTokenId.ANY_KEYWORD;
76.814 - }
76.815 - break;
76.816 - case 'i': // if,import,in,is, int
76.817 - if (length == 2) {
76.818 - switch (c2) {
76.819 - case 'f': // if
76.820 - return PythonTokenId.IF;
76.821 - case 'n': // in
76.822 - if (length == 2 && TokenUtilities.textEquals(s, "in")) { //NOI18N
76.823 - return PythonTokenId.ANY_KEYWORD;
76.824 - }
76.825 - case 's': // is
76.826 - return PythonTokenId.ANY_KEYWORD;
76.827 - }
76.828 - } else if (c2 == 'm' && length == 6 && TokenUtilities.textEquals(s, "import")) { // NOI18N
76.829 - // import
76.830 - return PythonTokenId.IMPORT;
76.831 - } else if (length == 3 && TokenUtilities.textEquals(s, "int")) { // NOI18N
76.832 - return PythonTokenId.STD_SYMBOLS;
76.833 - } else if (length == 10 && TokenUtilities.textEquals(s, "isinstance")) { // NOI18N
76.834 - return PythonTokenId.STD_SYMBOLS;
76.835 - }
76.836 - break;
76.837 - case 'l': // lambda, len, list
76.838 - if (length == 6 && TokenUtilities.textEquals(s, "lambda")) { // NOI18N
76.839 - return PythonTokenId.ANY_KEYWORD;
76.840 - } else if (length == 3 && TokenUtilities.textEquals(s, "len")) { // NOI18N
76.841 - return PythonTokenId.STD_SYMBOLS;
76.842 - } else if (length == 4 && TokenUtilities.textEquals(s, "list")) { // NOI18N
76.843 - return PythonTokenId.STD_SYMBOLS;
76.844 - }
76.845 - break;
76.846 - case 'n': // not
76.847 - if (length == 3 && TokenUtilities.textEquals(s, "not")) { // NOI18N
76.848 - return PythonTokenId.ANY_KEYWORD;
76.849 - }
76.850 - break;
76.851 - case 'o': // or, object
76.852 - if (length == 2 && TokenUtilities.textEquals(s, "or")) { // NOI18N
76.853 - return PythonTokenId.ANY_KEYWORD;
76.854 - } else if (length == 6 && TokenUtilities.textEquals(s, "object")) { // NOI18N
76.855 - return PythonTokenId.STD_SYMBOLS;
76.856 - }
76.857 - break;
76.858 - case 'p': // pass,print
76.859 - if (c2 == 'a') { // pass
76.860 - if (length == 4 && TokenUtilities.textEquals(s, "pass")) { // NOI18N
76.861 - return PythonTokenId.PASS;
76.862 - }
76.863 - } else if (c2 == 'r') { // print
76.864 - if (length == 5 && TokenUtilities.textEquals(s, "print")) { // NOI18N
76.865 - return PythonTokenId.ANY_KEYWORD;
76.866 - }
76.867 - }
76.868 - break;
76.869 - case 'r': // raise,return
76.870 - if (c2 == 'a') { // raise
76.871 - if (length == 5 && TokenUtilities.textEquals(s, "raise")) { // NOI18N
76.872 - return PythonTokenId.RAISE;
76.873 - }
76.874 - } else if (c2 == 'e') { // return
76.875 - if (length == 6 && TokenUtilities.textEquals(s, "return")) { // NOI18N
76.876 - return PythonTokenId.RETURN;
76.877 - }
76.878 - }
76.879 - break;
76.880 - case 's': // self, set, str, super
76.881 - if (length == 4 && TokenUtilities.textEquals(s, "self")) { // NOI18N
76.882 - return PythonTokenId.ANY_KEYWORD;
76.883 - } else if (length == 3 && TokenUtilities.textEquals(s, "set")) { // NOI18N
76.884 - return PythonTokenId.STD_SYMBOLS;
76.885 - } else if (length == 3 && TokenUtilities.textEquals(s, "str")) { // NOI18N
76.886 - return PythonTokenId.STD_SYMBOLS;
76.887 - } else if (length == 5 && TokenUtilities.textEquals(s, "super")) { // NOI18N
76.888 - return PythonTokenId.ANY_KEYWORD;
76.889 - }
76.890 - case 't': // try, tuple, type
76.891 - if (length == 3 && TokenUtilities.textEquals(s, "try")) { // NOI18N
76.892 - return PythonTokenId.TRY;
76.893 - } else if (length == 5 && TokenUtilities.textEquals(s, "tuple")) { // NOI18N
76.894 - return PythonTokenId.STD_SYMBOLS;
76.895 - } else if (length == 4 && TokenUtilities.textEquals(s, "type")) { // NOI18N
76.896 - return PythonTokenId.STD_SYMBOLS;
76.897 - }
76.898 - break;
76.899 - case 'w': // while,with
76.900 - if (c2 == 'h') { // while
76.901 - if (length == 5 && TokenUtilities.textEquals(s, "while")) { // NOI18N
76.902 - return PythonTokenId.ANY_KEYWORD;
76.903 - }
76.904 - } else if (c2 == 'i') { // with
76.905 - if (length == 4 && TokenUtilities.textEquals(s, "with")) { // NOI18N
76.906 - return PythonTokenId.ANY_KEYWORD;
76.907 - }
76.908 - }
76.909 - break;
76.910 - case 'y': // yield
76.911 - if (length == 5 && TokenUtilities.textEquals(s, "yield")) { // NOI18N
76.912 - return PythonTokenId.ANY_KEYWORD;
76.913 - }
76.914 - break;
76.915 - case 'F': // False
76.916 - if (length == 5 && TokenUtilities.textEquals(s, "False")) { // NOI18N
76.917 - return PythonTokenId.FALSE;
76.918 - }
76.919 - case 'N': // None
76.920 - if (length == 4 && TokenUtilities.textEquals(s, "None")) { // NOI18N
76.921 - return PythonTokenId.NONE;
76.922 - }
76.923 - case 'T': // True
76.924 - if (length == 4 && TokenUtilities.textEquals(s, "True")) { // NOI18N
76.925 - return PythonTokenId.TRUE;
76.926 - }
76.927 - }
76.928 -
76.929 - return null;
76.930 - }
76.931 -}
77.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonLexerUtils.java Mon Aug 31 12:40:19 2015 +0200
77.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
77.3 @@ -1,558 +0,0 @@
77.4 -/*
77.5 - * To change this template, choose Tools | Templates
77.6 - * and open the template in the editor.
77.7 - */
77.8 -package org.netbeans.modules.python.editor.lexer;
77.9 -
77.10 -import java.util.Arrays;
77.11 -import java.util.List;
77.12 -import java.util.regex.Matcher;
77.13 -import java.util.regex.Pattern;
77.14 -import javax.swing.text.BadLocationException;
77.15 -import javax.swing.text.Document;
77.16 -import org.netbeans.api.lexer.Token;
77.17 -import org.netbeans.api.lexer.TokenHierarchy;
77.18 -import org.netbeans.api.lexer.TokenId;
77.19 -import org.netbeans.api.lexer.TokenSequence;
77.20 -import org.netbeans.editor.BaseDocument;
77.21 -import org.netbeans.editor.Utilities;
77.22 -import org.netbeans.modules.csl.api.OffsetRange;
77.23 -import org.netbeans.modules.python.editor.PythonParserResult;
77.24 -import org.openide.filesystems.FileUtil;
77.25 -import org.openide.loaders.DataObject;
77.26 -import org.openide.util.Exceptions;
77.27 -import org.python.antlr.PythonTree;
77.28 -
77.29 -/**
77.30 - * Utility functions around the Python lexer
77.31 - *
77.32 - * @author Tor Norbye
77.33 - */
77.34 -public class PythonLexerUtils {
77.35 - /**
77.36 - * Try to produce a more accurate location for the given name in the given import statement, located
77.37 - * at the lexRange provided
77.38 - */
77.39 - public static OffsetRange getImportNameOffset(BaseDocument doc, OffsetRange lexRange, PythonTree node, String name) {
77.40 - int docLength = doc.getLength();
77.41 - int start = Math.min(docLength, lexRange.getStart());
77.42 - int end = Math.min(docLength, lexRange.getEnd());
77.43 - try {
77.44 - String s = doc.getText(start, end - start);
77.45 -
77.46 - Pattern p = Pattern.compile(".*import\\s+\\b(" + name + ")\\b.*");
77.47 - Matcher m = p.matcher(s);
77.48 - if (m.matches()) {
77.49 - int offset = start + m.start(1);
77.50 - return new OffsetRange(offset, offset + name.length());
77.51 - }
77.52 -
77.53 - // Lame
77.54 - int searchIndex = s.indexOf("import ");
77.55 - if (searchIndex == -1) {
77.56 - searchIndex = 0;
77.57 - } else {
77.58 - searchIndex += 7;
77.59 - }
77.60 - int match = s.indexOf(name, searchIndex + 7);
77.61 - if (match != -1) {
77.62 - int offset = start + match;
77.63 - return new OffsetRange(offset, offset + name.length());
77.64 - }
77.65 -
77.66 - // Give up - use the whole range
77.67 - } catch (BadLocationException ex) {
77.68 - Exceptions.printStackTrace(ex);
77.69 - }
77.70 -
77.71 - return lexRange;
77.72 - }
77.73 -
77.74 - /** For a possibly generated offset in an AST, return the corresponding lexing/true document offset */
77.75 - public static int getLexerOffset(PythonParserResult result, int astOffset) {
77.76 - return result.getSnapshot().getOriginalOffset(astOffset);
77.77 - }
77.78 -
77.79 - public static OffsetRange getLexerOffsets(PythonParserResult result, OffsetRange astRange) {
77.80 - if (result != null) {
77.81 - int rangeStart = astRange.getStart();
77.82 - int start = result.getSnapshot().getOriginalOffset(rangeStart);
77.83 - if (start == rangeStart) {
77.84 - return astRange;
77.85 - } else if (start == -1) {
77.86 - return OffsetRange.NONE;
77.87 - } else {
77.88 - // Assumes the translated range maintains size
77.89 - return new OffsetRange(start, start + astRange.getLength());
77.90 - }
77.91 - }
77.92 -
77.93 - return astRange;
77.94 - }
77.95 -
77.96 - /**
77.97 - * Narrow a given lexical offset range to the closest AST-relevant offsets.
77.98 - * This means it will pass over things like comments and whitespace.
77.99 - * @param doc The document containing the range
77.100 - * @param range The start/end lexical range we want to narrow
77.101 - * @return An OffsetRange where the offsets begin and end at AST-relevant tokens
77.102 - */
77.103 - public static OffsetRange narrow(BaseDocument doc, OffsetRange range, boolean skipComments) {
77.104 - try {
77.105 - doc.readLock(); // For token hiearchy use
77.106 - // For token hiearchy use
77.107 - int start = range.getStart();
77.108 - TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, start);
77.109 - if (ts != null) {
77.110 - int delta = ts.move(start);
77.111 - while (ts.moveNext()) {
77.112 - Token<? extends PythonTokenId> token = ts.token();
77.113 - PythonTokenId id = token.id();
77.114 - if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
77.115 - if (delta != 0) {
77.116 - return OffsetRange.NONE;
77.117 - }
77.118 - start = ts.offset();
77.119 - break;
77.120 - } else {
77.121 - delta = 0;
77.122 - }
77.123 - }
77.124 - }
77.125 - int end = range.getEnd();
77.126 - ts = getPositionedSequence(doc, end);
77.127 - if (ts != null) {
77.128 - int delta = ts.move(end);
77.129 - while (delta > 0 ? ts.moveNext() : ts.movePrevious()) {
77.130 - Token<? extends PythonTokenId> token = ts.token();
77.131 - PythonTokenId id = token.id();
77.132 - if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
77.133 - if (delta != 0) {
77.134 - return OffsetRange.NONE;
77.135 - }
77.136 - end = ts.offset() + token.length();
77.137 - break;
77.138 - } else {
77.139 - delta = 0;
77.140 - }
77.141 - }
77.142 - }
77.143 -
77.144 - if (end < start) {
77.145 - return OffsetRange.NONE;
77.146 - }
77.147 -
77.148 - return new OffsetRange(start, end);
77.149 - } finally {
77.150 - doc.readUnlock();
77.151 - }
77.152 - }
77.153 -
77.154 - /** Find the ruby token sequence (in case it's embedded in something else at the top level */
77.155 - @SuppressWarnings("unchecked")
77.156 - public static TokenSequence<? extends PythonTokenId> getPythonSequence(BaseDocument doc, int offset) {
77.157 - TokenHierarchy<Document> th = TokenHierarchy.get((Document)doc);
77.158 - return getPythonSequence(th, offset);
77.159 - }
77.160 -
77.161 - @SuppressWarnings("unchecked")
77.162 - public static TokenSequence<? extends PythonTokenId> getPythonSequence(TokenHierarchy<Document> th, int offset) {
77.163 - TokenSequence<? extends PythonTokenId> ts = th.tokenSequence(PythonTokenId.language());
77.164 -
77.165 - if (ts == null) {
77.166 - // Possibly an embedding scenario such as an RHTML file
77.167 - // First try with backward bias true
77.168 - List<TokenSequence<?>> list = th.embeddedTokenSequences(offset, true);
77.169 -
77.170 - for (TokenSequence t : list) {
77.171 - if (t.language() == PythonTokenId.language()) {
77.172 - ts = t;
77.173 -
77.174 - break;
77.175 - }
77.176 - }
77.177 -
77.178 - if (ts == null) {
77.179 - list = th.embeddedTokenSequences(offset, false);
77.180 -
77.181 - for (TokenSequence t : list) {
77.182 - if (t.language() == PythonTokenId.language()) {
77.183 - ts = t;
77.184 -
77.185 - break;
77.186 - }
77.187 - }
77.188 - }
77.189 - }
77.190 -
77.191 - return ts;
77.192 - }
77.193 -
77.194 - public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset) {
77.195 - return getPositionedSequence(doc, offset, true);
77.196 - }
77.197 -
77.198 - public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset, boolean lookBack) {
77.199 - TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, offset);
77.200 -
77.201 - if (ts != null) {
77.202 - try {
77.203 - ts.move(offset);
77.204 - } catch (AssertionError e) {
77.205 - DataObject dobj = (DataObject)doc.getProperty(Document.StreamDescriptionProperty);
77.206 -
77.207 - if (dobj != null) {
77.208 - Exceptions.attachMessage(e, FileUtil.getFileDisplayName(dobj.getPrimaryFile()));
77.209 - }
77.210 -
77.211 - throw e;
77.212 - }
77.213 -
77.214 - if (!lookBack && !ts.moveNext()) {
77.215 - return null;
77.216 - } else if (lookBack && !ts.moveNext() && !ts.movePrevious()) {
77.217 - return null;
77.218 - }
77.219 -
77.220 - /* TODO - allow Python inside strings
77.221 - if (ts.token().id() == PythonTokenId.STRING_LITERAL) {
77.222 - TokenSequence<? extends PythonStringTokenId> ets = ts.embedded(PythonStringTokenId.language());
77.223 - if (ets != null) {
77.224 - ets.move(offset);
77.225 - if ((!lookBack && ets.moveNext()) || (lookBack && ets.movePrevious())) {
77.226 - TokenSequence<?extends PythonTokenId> epts = ets.embedded(PythonTokenId.language());
77.227 - if (epts != null) {
77.228 - epts.move(offset);
77.229 - if (!lookBack && !epts.moveNext()) {
77.230 - return null;
77.231 - } else if (lookBack && !epts.moveNext() && !epts.movePrevious()) {
77.232 - return null;
77.233 - }
77.234 - return epts;
77.235 - }
77.236 - }
77.237 - }
77.238 - }
77.239 - */
77.240 -
77.241 - return ts;
77.242 - }
77.243 -
77.244 - return null;
77.245 - }
77.246 -
77.247 - public static Token<? extends PythonTokenId> getToken(BaseDocument doc, int offset) {
77.248 - TokenSequence<? extends PythonTokenId> ts = getPositionedSequence(doc, offset);
77.249 -
77.250 - if (ts != null) {
77.251 - return ts.token();
77.252 - }
77.253 -
77.254 - return null;
77.255 - }
77.256 -
77.257 - public static char getTokenChar(BaseDocument doc, int offset) {
77.258 - Token<? extends PythonTokenId> token = getToken(doc, offset);
77.259 -
77.260 - if (token != null) {
77.261 - String text = token.text().toString();
77.262 -
77.263 - if (text.length() > 0) { // Usually true, but I could have gotten EOF right?
77.264 -
77.265 - return text.charAt(0);
77.266 - }
77.267 - }
77.268 -
77.269 - return 0;
77.270 - }
77.271 -
77.272 - public static Token<? extends PythonTokenId> findNextNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
77.273 - return findNext(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
77.274 - }
77.275 -
77.276 - public static Token<? extends PythonTokenId> findPreviousNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
77.277 - return findPrevious(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
77.278 - }
77.279 -
77.280 - public static Token<? extends PythonTokenId> findNext(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
77.281 - if (ignores.contains(ts.token().id())) {
77.282 - while (ts.moveNext() && ignores.contains(ts.token().id())) {
77.283 - }
77.284 - }
77.285 - return ts.token();
77.286 - }
77.287 -
77.288 - public static Token<? extends PythonTokenId> findNextIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
77.289 - while (ts.moveNext() && !includes.contains(ts.token().id())) {
77.290 - }
77.291 - return ts.token();
77.292 - }
77.293 -
77.294 - public static Token<? extends PythonTokenId> findPreviousIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
77.295 - while (ts.movePrevious() && !includes.contains(ts.token().id())) {
77.296 - }
77.297 - return ts.token();
77.298 - }
77.299 -
77.300 - public static Token<? extends PythonTokenId> findPrevious(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
77.301 - if (ignores.contains(ts.token().id())) {
77.302 - while (ts.movePrevious() && ignores.contains(ts.token().id())) {
77.303 - }
77.304 - }
77.305 - return ts.token();
77.306 - }
77.307 -
77.308 - static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts) {
77.309 - return skipParenthesis(ts, false);
77.310 - }
77.311 -
77.312 - /**
77.313 - * Tries to skip parenthesis
77.314 - */
77.315 - public static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts, boolean back) {
77.316 - int balance = 0;
77.317 -
77.318 - Token<? extends PythonTokenId> token = ts.token();
77.319 - if (token == null) {
77.320 - return false;
77.321 - }
77.322 -
77.323 - TokenId id = token.id();
77.324 -
77.325 - if (id == PythonTokenId.WHITESPACE || id == PythonTokenId.NEWLINE) {
77.326 - while ((back ? ts.movePrevious() : ts.moveNext()) && (ts.token().id() == PythonTokenId.WHITESPACE || ts.token().id() == PythonTokenId.NEWLINE)) {
77.327 - }
77.328 - }
77.329 -
77.330 - // if current token is not left parenthesis
77.331 - if (ts.token().id() != (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
77.332 - return false;
77.333 - }
77.334 -
77.335 - do {
77.336 - token = ts.token();
77.337 - id = token.id();
77.338 -
77.339 - if (id == (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
77.340 - balance++;
77.341 - } else if (id == (back ? PythonTokenId.LPAREN : PythonTokenId.RPAREN)) {
77.342 - if (balance == 0) {
77.343 - return false;
77.344 - } else if (balance == 1) {
77.345 - //int length = ts.offset() + token.length();
77.346 - if (back) {
77.347 - ts.movePrevious();
77.348 - } else {
77.349 - ts.moveNext();
77.350 - }
77.351 - return true;
77.352 - }
77.353 -
77.354 - balance--;
77.355 - }
77.356 - } while (back ? ts.movePrevious() : ts.moveNext());
77.357 -
77.358 - return false;
77.359 - }
77.360 -
77.361 - /** Search forwards in the token sequence until a token of type <code>down</code> is found */
77.362 - public static OffsetRange findFwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
77.363 - TokenId down) {
77.364 - int balance = 0;
77.365 -
77.366 - while (ts.moveNext()) {
77.367 - Token<? extends PythonTokenId> token = ts.token();
77.368 - TokenId id = token.id();
77.369 -
77.370 - if (id == up) {
77.371 - balance++;
77.372 - } else if (id == down) {
77.373 - if (balance == 0) {
77.374 - return new OffsetRange(ts.offset(), ts.offset() + token.length());
77.375 - }
77.376 -
77.377 - balance--;
77.378 - }
77.379 - }
77.380 -
77.381 - return OffsetRange.NONE;
77.382 - }
77.383 -
77.384 - /** Search backwards in the token sequence until a token of type <code>up</code> is found */
77.385 - public static OffsetRange findBwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
77.386 - TokenId down) {
77.387 - int balance = 0;
77.388 -
77.389 - while (ts.movePrevious()) {
77.390 - Token<? extends PythonTokenId> token = ts.token();
77.391 - TokenId id = token.id();
77.392 -
77.393 - if (id == up) {
77.394 - if (balance == 0) {
77.395 - return new OffsetRange(ts.offset(), ts.offset() + token.length());
77.396 - }
77.397 -
77.398 - balance++;
77.399 - } else if (id == down) {
77.400 - balance--;
77.401 - }
77.402 - }
77.403 -
77.404 - return OffsetRange.NONE;
77.405 - }
77.406 -
77.407 - /** Compute the balance of begin/end tokens on the line */
77.408 - public static int getLineBalance(BaseDocument doc, int offset, TokenId up, TokenId down) {
77.409 - try {
77.410 - int begin = Utilities.getRowStart(doc, offset);
77.411 - int end = Utilities.getRowEnd(doc, offset);
77.412 -
77.413 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, begin);
77.414 - if (ts == null) {
77.415 - return 0;
77.416 - }
77.417 -
77.418 - ts.move(begin);
77.419 -
77.420 - if (!ts.moveNext()) {
77.421 - return 0;
77.422 - }
77.423 -
77.424 - int balance = 0;
77.425 -
77.426 - do {
77.427 - Token<? extends PythonTokenId> token = ts.token();
77.428 - TokenId id = token.id();
77.429 -
77.430 - if (id == up) {
77.431 - balance++;
77.432 - } else if (id == down) {
77.433 - balance--;
77.434 - }
77.435 - } while (ts.moveNext() && (ts.offset() <= end));
77.436 -
77.437 - return balance;
77.438 - } catch (BadLocationException ble) {
77.439 - Exceptions.printStackTrace(ble);
77.440 -
77.441 - return 0;
77.442 - }
77.443 - }
77.444 -
77.445 - /**
77.446 - * The same as braceBalance but generalized to any pair of matching
77.447 - * tokens.
77.448 - * @param open the token that increses the count
77.449 - * @param close the token that decreses the count
77.450 - */
77.451 - public static int getTokenBalance(BaseDocument doc, TokenId open, TokenId close, int offset)
77.452 - throws BadLocationException {
77.453 - TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, 0);
77.454 - if (ts == null) {
77.455 - return 0;
77.456 - }
77.457 -
77.458 - // XXX Why 0? Why not offset?
77.459 - ts.moveIndex(0);
77.460 -
77.461 - if (!ts.moveNext()) {
77.462 - return 0;
77.463 - }
77.464 -
77.465 - int balance = 0;
77.466 -
77.467 - do {
77.468 - Token t = ts.token();
77.469 -
77.470 - if (t.id() == open) {
77.471 - balance++;
77.472 - } else if (t.id() == close) {
77.473 - balance--;
77.474 - }
77.475 - } while (ts.moveNext());
77.476 -
77.477 - return balance;
77.478 - }
77.479 -
77.480 - /**
77.481 - * Return true iff the line for the given offset is a JavaScript comment line.
77.482 - * This will return false for lines that contain comments (even when the
77.483 - * offset is within the comment portion) but also contain code.
77.484 - */
77.485 - public static boolean isCommentOnlyLine(BaseDocument doc, int offset)
77.486 - throws BadLocationException {
77.487 - int begin = Utilities.getRowFirstNonWhite(doc, offset);
77.488 -
77.489 - if (begin == -1) {
77.490 - return false; // whitespace only
77.491 - }
77.492 -
77.493 - Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, begin);
77.494 - if (token != null) {
77.495 - return token.id() == PythonTokenId.COMMENT;
77.496 - }
77.497 -
77.498 - return false;
77.499 - }
77.500 -
77.501 - /**
77.502 - * Back up to the first space character prior to the given offset - as long as
77.503 - * it's on the same line! If there's only leading whitespace on the line up
77.504 - * to the lex offset, return the offset itself
77.505 - * @todo Rewrite this now that I have a separate newline token, EOL, that I can
77.506 - * break on - no need to call Utilities.getRowStart.
77.507 - */
77.508 - public static int findSpaceBegin(BaseDocument doc, int lexOffset) {
77.509 - TokenSequence ts = getPythonSequence(doc, lexOffset);
77.510 - if (ts == null) {
77.511 - return lexOffset;
77.512 - }
77.513 - boolean allowPrevLine = false;
77.514 - int lineStart;
77.515 - try {
77.516 - lineStart = Utilities.getRowStart(doc, Math.min(lexOffset, doc.getLength()));
77.517 - int prevLast = lineStart - 1;
77.518 - if (lineStart > 0) {
77.519 - prevLast = Utilities.getRowLastNonWhite(doc, lineStart - 1);
77.520 - if (prevLast != -1) {
77.521 - char c = doc.getText(prevLast, 1).charAt(0);
77.522 - if (c == ',') {
77.523 - // Arglist continuation? // TODO : check lexing
77.524 - allowPrevLine = true;
77.525 - }
77.526 - }
77.527 - }
77.528 - if (!allowPrevLine) {
77.529 - int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
77.530 - if (lexOffset <= firstNonWhite || firstNonWhite == -1) {
77.531 - return lexOffset;
77.532 - }
77.533 - } else {
77.534 - // Make lineStart so small that Math.max won't cause any problems
77.535 - int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
77.536 - if (prevLast >= 0 && (lexOffset <= firstNonWhite || firstNonWhite == -1)) {
77.537 - return prevLast + 1;
77.538 - }
77.539 - lineStart = 0;
77.540 - }
77.541 - } catch (BadLocationException ble) {
77.542 - Exceptions.printStackTrace(ble);
77.543 - return lexOffset;
77.544 - }
77.545 - ts.move(lexOffset);
77.546 - if (ts.moveNext()) {
77.547 - if (lexOffset > ts.offset()) {
77.548 - // We're in the middle of a token
77.549 - return Math.max((ts.token().id() == PythonTokenId.WHITESPACE) ? ts.offset() : lexOffset, lineStart);
77.550 - }
77.551 - while (ts.movePrevious()) {
77.552 - Token token = ts.token();
77.553 - if (token.id() != PythonTokenId.WHITESPACE) {
77.554 - return Math.max(ts.offset() + token.length(), lineStart);
77.555 - }
77.556 - }
77.557 - }
77.558 -
77.559 - return lexOffset;
77.560 - }
77.561 -}
78.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonStringLexer.java Mon Aug 31 12:40:19 2015 +0200
78.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
78.3 @@ -1,292 +0,0 @@
78.4 -/*
78.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
78.6 - *
78.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
78.8 - *
78.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
78.10 - * Other names may be trademarks of their respective owners.
78.11 - *
78.12 - * The contents of this file are subject to the terms of either the GNU
78.13 - * General Public License Version 2 only ("GPL") or the Common
78.14 - * Development and Distribution License("CDDL") (collectively, the
78.15 - * "License"). You may not use this file except in compliance with the
78.16 - * License. You can obtain a copy of the License at
78.17 - * http://www.netbeans.org/cddl-gplv2.html
78.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
78.19 - * specific language governing permissions and limitations under the
78.20 - * License. When distributing the software, include this License Header
78.21 - * Notice in each file and include the License file at
78.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
78.23 - * particular file as subject to the "Classpath" exception as provided
78.24 - * by Oracle in the GPL Version 2 section of the License file that
78.25 - * accompanied this code. If applicable, add the following below the
78.26 - * License Header, with the fields enclosed by brackets [] replaced by
78.27 - * your own identifying information:
78.28 - * "Portions Copyrighted [year] [name of copyright owner]"
78.29 - *
78.30 - * Contributor(s):
78.31 - *
78.32 - * The Original Software is NetBeans. The Initial Developer of the Original
78.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
78.34 - * Microsystems, Inc. All Rights Reserved.
78.35 - *
78.36 - * If you wish your version of this file to be governed by only the CDDL
78.37 - * or only the GPL Version 2, indicate your decision by adding
78.38 - * "[Contributor] elects to include this software in this distribution
78.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
78.40 - * single choice of license, a recipient has the option to distribute
78.41 - * your version of this file under either the CDDL, the GPL Version 2 or
78.42 - * to extend the choice of license to its licensees as provided above.
78.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
78.44 - * Version 2 license, then the option applies only if the new code is
78.45 - * made subject to such option by the copyright holder.
78.46 - */
78.47 -package org.netbeans.modules.python.editor.lexer;
78.48 -
78.49 -import org.netbeans.api.lexer.Token;
78.50 -import org.netbeans.spi.lexer.Lexer;
78.51 -import org.netbeans.spi.lexer.LexerInput;
78.52 -import org.netbeans.spi.lexer.LexerRestartInfo;
78.53 -import org.netbeans.spi.lexer.TokenFactory;
78.54 -
78.55 -/**
78.56 - * A lexer for python strings. Highlights escape sequences, and recognizes
78.57 - * doctest sections and highlights these as well.
78.58 - * http://docs.python.org/lib/module-doctest.html
78.59 - *
78.60 - * @todo Track whether strings are raw or not, and don't do escape sequence
78.61 - * highlighting in raw strings
78.62 - *
78.63 - * @author Tor Norbye
78.64 - */
78.65 -public class PythonStringLexer implements Lexer<PythonStringTokenId> {
78.66 - private static final int EOF = LexerInput.EOF;
78.67 - private final LexerInput input;
78.68 - private final TokenFactory<PythonStringTokenId> tokenFactory;
78.69 - private final boolean substituting;
78.70 -
78.71 - /**
78.72 - * A Lexer for Python strings
78.73 - * @param substituting If true, handle substitution rules for double quoted strings, otherwise
78.74 - * single quoted strings.
78.75 - */
78.76 - public PythonStringLexer(LexerRestartInfo<PythonStringTokenId> info, boolean substituting) {
78.77 - this.input = info.input();
78.78 - this.tokenFactory = info.tokenFactory();
78.79 - this.substituting = substituting;
78.80 - assert (info.state() == null); // passed argument always null
78.81 - }
78.82 -
78.83 - @Override
78.84 - public Object state() {
78.85 - return null;
78.86 - }
78.87 -
78.88 - @Override
78.89 - public Token<PythonStringTokenId> nextToken() {
78.90 - boolean inWord = false;
78.91 - while (true) {
78.92 - int ch = input.read();
78.93 -
78.94 - switch (ch) {
78.95 - case EOF:
78.96 -
78.97 - if (input.readLength() > 0) {
78.98 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
78.99 - input.readLength());
78.100 - } else {
78.101 - return null;
78.102 - }
78.103 -
78.104 - case '>':
78.105 - // Look for doctest: \n, whitespace, >>>{embedded python}\n
78.106 - int initialReadLength = input.readLength();
78.107 - input.read();
78.108 - if (ch == '>') {
78.109 - ch = input.read();
78.110 - if (ch == '>') {
78.111 - if (input.readLength() > 3) {
78.112 - input.backup(3);
78.113 - // Finish this token such that we can do a dedicated token for the ">>>" line.
78.114 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
78.115 - input.readLength());
78.116 - }
78.117 - // Find end...
78.118 - boolean nonempty = false;
78.119 - while (true) {
78.120 - ch = input.read();
78.121 - if (ch == EOF) {
78.122 - break;
78.123 - } else if (ch == '\n') {
78.124 - if (nonempty) {
78.125 - input.backup(1); // Don't include the \n
78.126 - return tokenFactory.createToken(PythonStringTokenId.EMBEDDED_PYTHON,
78.127 - input.readLength());
78.128 -
78.129 - }
78.130 - break;
78.131 - } else if (!Character.isWhitespace(ch)) {
78.132 - nonempty = true;
78.133 - }
78.134 - }
78.135 - }
78.136 - }
78.137 - if (input.readLength() > initialReadLength) {
78.138 - input.backup(input.readLength() - initialReadLength);
78.139 - } else {
78.140 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
78.141 - input.readLength());
78.142 - }
78.143 - break;
78.144 -
78.145 - case '\\':
78.146 -
78.147 - if (input.readLength() > 1) { // already read some text
78.148 - input.backup(1);
78.149 -
78.150 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
78.151 - input.readLength());
78.152 - }
78.153 -
78.154 - ch = input.read();
78.155 - if (ch == EOF) {
78.156 - return tokenFactory.createToken(PythonStringTokenId.STRING_INVALID,
78.157 - input.readLength());
78.158 - } else {
78.159 - return tokenFactory.createToken(PythonStringTokenId.STRING_ESCAPE,
78.160 - input.readLength());
78.161 - }
78.162 -
78.163 - case 'f': // ftp:
78.164 - case 'm': // mailto:
78.165 - case 'w': // www.
78.166 - case 'h': { // http links. TODO: link:, ftp:, mailto:, and www.
78.167 -
78.168 - if (inWord) {
78.169 - break;
78.170 - }
78.171 -
78.172 - int originalLength = input.readLength();
78.173 - boolean foundLinkBegin = false;
78.174 -
78.175 - if (ch == 'h') { // http:
78.176 -
78.177 - if (input.read() == 't') {
78.178 - if (input.read() == 't') {
78.179 - if (input.read() == 'p') {
78.180 - int r = input.read();
78.181 - if (r == ':') {
78.182 - foundLinkBegin = true;
78.183 - } else if (r == 's') {
78.184 - if (input.read() == ':') {
78.185 - foundLinkBegin = true;
78.186 - } else {
78.187 - input.backup(5);
78.188 - }
78.189 - } else {
78.190 - input.backup(4);
78.191 - }
78.192 - } else {
78.193 - input.backup(3);
78.194 - }
78.195 - } else {
78.196 - input.backup(2);
78.197 - }
78.198 - } else {
78.199 - input.backup(1);
78.200 - }
78.201 - } else if (ch == 'f') { // ftp:
78.202 -
78.203 - if (input.read() == 't') {
78.204 - if (input.read() == 'p') {
78.205 - if (input.read() == ':') {
78.206 - foundLinkBegin = true;
78.207 - } else {
78.208 - input.backup(3);
78.209 - }
78.210 - } else {
78.211 - input.backup(2);
78.212 - }
78.213 - } else {
78.214 - input.backup(1);
78.215 - }
78.216 - } else if (ch == 'm') { // mailto:
78.217 -
78.218 - if (input.read() == 'a') {
78.219 - if (input.read() == 'i') {
78.220 - if (input.read() == 'l') {
78.221 - if (input.read() == 't') {
78.222 - if (input.read() == 'o') {
78.223 - if (input.read() == ':') {
78.224 - foundLinkBegin = true;
78.225 - } else {
78.226 - input.backup(6);
78.227 - }
78.228 - } else {
78.229 - input.backup(5);
78.230 - }
78.231 - } else {
78.232 - input.backup(4);
78.233 - }
78.234 - } else {
78.235 - input.backup(3);
78.236 - }
78.237 - } else {
78.238 - input.backup(2);
78.239 - }
78.240 - } else {
78.241 - input.backup(1);
78.242 - }
78.243 - } else if (ch == 'w') { // www.
78.244 -
78.245 - if (input.read() == 'w') {
78.246 - if (input.read() == 'w') {
78.247 - if (input.read() == '.') {
78.248 - foundLinkBegin = true;
78.249 - } else {
78.250 - input.backup(3);
78.251 - }
78.252 - } else {
78.253 - input.backup(2);
78.254 - }
78.255 - } else {
78.256 - input.backup(1);
78.257 - }
78.258 - }
78.259 -
78.260 - if (foundLinkBegin) {
78.261 - while (ch != EOF) {
78.262 - ch = input.read();
78.263 -
78.264 - if ((ch == ']') || (ch == ')') || Character.isWhitespace(ch) ||
78.265 - (ch == '\'') || (ch == '"')) {
78.266 - input.backup(1);
78.267 -
78.268 - break;
78.269 - }
78.270 - }
78.271 -
78.272 - if (originalLength > 1) {
78.273 - input.backup(input.readLengthEOF() - originalLength + 1);
78.274 -
78.275 - return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
78.276 - input.readLength());
78.277 - }
78.278 -
78.279 - if (input.readLength() > 2) {
78.280 - return tokenFactory.createToken(PythonStringTokenId.URL,
78.281 - input.readLength());
78.282 - }
78.283 - }
78.284 - break;
78.285 - }
78.286 - }
78.287 -
78.288 - inWord = Character.isJavaIdentifierPart(ch);
78.289 - }
78.290 - }
78.291 -
78.292 - @Override
78.293 - public void release() {
78.294 - }
78.295 -}
79.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonStringTokenId.java Mon Aug 31 12:40:19 2015 +0200
79.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
79.3 @@ -1,125 +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 java.util.Collection;
79.50 -import java.util.EnumSet;
79.51 -import java.util.Map;
79.52 -
79.53 -import org.netbeans.api.lexer.InputAttributes;
79.54 -import org.netbeans.api.lexer.Language;
79.55 -import org.netbeans.api.lexer.LanguagePath;
79.56 -import org.netbeans.api.lexer.Token;
79.57 -import org.netbeans.api.lexer.TokenId;
79.58 -import org.netbeans.api.lexer.TokenUtilities;
79.59 -import org.netbeans.spi.lexer.LanguageEmbedding;
79.60 -import org.netbeans.spi.lexer.LanguageHierarchy;
79.61 -import org.netbeans.spi.lexer.Lexer;
79.62 -import org.netbeans.spi.lexer.LexerRestartInfo;
79.63 -
79.64 -/**
79.65 - *
79.66 - * @author Tor Norbye
79.67 - */
79.68 -public enum PythonStringTokenId implements TokenId {
79.69 - STRING_TEXT("string"),
79.70 - STRING_ESCAPE("string-escape"),
79.71 - STRING_INVALID("string-escape-invalid"),
79.72 - URL("url"),
79.73 - EMBEDDED_PYTHON("string");
79.74 - private final String primaryCategory;
79.75 -
79.76 - PythonStringTokenId() {
79.77 - this(null);
79.78 - }
79.79 -
79.80 - PythonStringTokenId(String primaryCategory) {
79.81 - this.primaryCategory = primaryCategory;
79.82 - }
79.83 -
79.84 - @Override
79.85 - public String primaryCategory() {
79.86 - return primaryCategory;
79.87 - }
79.88 - public static final Language<PythonStringTokenId> language =
79.89 - new LanguageHierarchy<PythonStringTokenId>() {
79.90 - @Override
79.91 - protected Collection<PythonStringTokenId> createTokenIds() {
79.92 - return EnumSet.allOf(PythonStringTokenId.class);
79.93 - }
79.94 -
79.95 - @Override
79.96 - protected Map<String, Collection<PythonStringTokenId>> createTokenCategories() {
79.97 - return null; // no extra categories
79.98 - }
79.99 -
79.100 - @Override
79.101 - protected Lexer<PythonStringTokenId> createLexer(
79.102 - LexerRestartInfo<PythonStringTokenId> info) {
79.103 - return new PythonStringLexer(info, true);
79.104 - }
79.105 -
79.106 - @Override
79.107 - protected LanguageEmbedding<?> embedding(
79.108 - Token<PythonStringTokenId> token, LanguagePath languagePath,
79.109 - InputAttributes inputAttributes) {
79.110 - PythonStringTokenId id = token.id();
79.111 -
79.112 - if (id == EMBEDDED_PYTHON && token.text() != null) {
79.113 - return LanguageEmbedding.create(PythonTokenId.language(), 3, 0); // 3: Exlude ">>>" prefix
79.114 - }
79.115 -
79.116 - return null; // No embedding
79.117 - }
79.118 -
79.119 - @Override
79.120 - public String mimeType() {
79.121 - return "text/x-python-string"; // NOI18N
79.122 - }
79.123 - }.language();
79.124 -
79.125 - public static Language<PythonStringTokenId> language() {
79.126 - return language;
79.127 - }
79.128 -}
80.1 --- a/python.editor/src/org/netbeans/modules/python/editor/lexer/PythonTokenId.java Mon Aug 31 12:40:19 2015 +0200
80.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
80.3 @@ -1,206 +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.HashMap;
80.52 -import java.util.Map;
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.modules.python.api.PythonMIMEResolver;
80.59 -import org.netbeans.modules.python.editor.PythonUtils;
80.60 -import org.netbeans.spi.lexer.LanguageEmbedding;
80.61 -import org.netbeans.spi.lexer.LanguageHierarchy;
80.62 -import org.netbeans.spi.lexer.Lexer;
80.63 -import org.netbeans.spi.lexer.LexerInput;
80.64 -import org.netbeans.spi.lexer.LexerRestartInfo;
80.65 -
80.66 -import org.netbeans.spi.lexer.TokenFactory;
80.67 -import org.openide.filesystems.FileObject;
80.68 -import static org.netbeans.modules.python.editor.lexer.PythonLexer.*;
80.69 -
80.70 -/**
80.71 - * @todo add the rest of the tokens
80.72 - *
80.73 - * @author Martin Adamek
80.74 - * @author alley
80.75 - */
80.76 -public enum PythonTokenId implements TokenId {
80.77 - ERROR(null, ERROR_CAT),
80.78 - IDENTIFIER(null, IDENTIFIER_CAT),
80.79 - INT_LITERAL(null, NUMBER_CAT),
80.80 - FLOAT_LITERAL(null, NUMBER_CAT),
80.81 - STRING_LITERAL(null, STRING_CAT),
80.82 - WHITESPACE(null, WHITESPACE_CAT),
80.83 - NEWLINE(null, WHITESPACE_CAT),
80.84 - DECORATOR(null, OPERATOR_CAT), // NOI18N
80.85 - // CONTINUED_LINE(null, WHITESPACE_CAT), // NOI18N
80.86 - COMMENT(null, COMMENT_CAT),
80.87 - STD_SYMBOLS(null, KEYWORD_CAT), // NOI18N
80.88 - LPAREN("(", SEPARATOR_CAT), // NOI18N
80.89 - RPAREN(")", SEPARATOR_CAT), // NOI18N
80.90 - LBRACE("{", SEPARATOR_CAT), // NOI18N
80.91 - RBRACE("}", SEPARATOR_CAT), // NOI18N
80.92 - LBRACKET("[", SEPARATOR_CAT), // NOI18N
80.93 - RBRACKET("]", SEPARATOR_CAT), // NOI18N
80.94 - STRING_BEGIN(null, STRING_CAT),
80.95 - STRING_END(null, STRING_CAT),
80.96 - // Cheating: out of laziness just map all keywords returning from Jython
80.97 - // into a single KEYWORD token; eventually we will have separate tokens
80.98 - // for each here such that the various helper methods for formatting,
80.99 - // smart indent, brace matching etc. can refer to specific keywords
80.100 - ANY_KEYWORD(null, KEYWORD_CAT),
80.101 - ANY_OPERATOR(null, OPERATOR_CAT),
80.102 - DEF("def", KEYWORD_CAT), // NOI18N
80.103 - CLASS("class", KEYWORD_CAT), // NOI18N
80.104 - IF("if", KEYWORD_CAT), // NOI18N
80.105 - ELSE("else", KEYWORD_CAT), // NOI18N
80.106 - ELIF("elif", KEYWORD_CAT), // NOI18N
80.107 - RAISE("raise", KEYWORD_CAT), // NOI18N
80.108 - PASS("pass", KEYWORD_CAT), // NOI18N
80.109 - RETURN("return", KEYWORD_CAT), // NOI18N
80.110 - EXCEPT("except", KEYWORD_CAT), // NOI18N
80.111 - FINALLY("finally", KEYWORD_CAT), // NOI18N
80.112 - IMPORT("import", KEYWORD_CAT), // NOI18N
80.113 - FROM("from", KEYWORD_CAT), // NOI18N
80.114 - TRUE("True", KEYWORD_CAT), // NOI18N
80.115 - FALSE("False", KEYWORD_CAT), // NOI18N
80.116 - NONE("None", KEYWORD_CAT), // NOI18N
80.117 - TRY("try", KEYWORD_CAT), // NOI18N
80.118 - DOT(".", OPERATOR_CAT), // NOI18N
80.119 - COMMA(",", OPERATOR_CAT), // NOI18N
80.120 - COLON(":", OPERATOR_CAT), // NOI18N
80.121 - ESC("\\", OPERATOR_CAT), // NOI18N
80.122 -
80.123 - // Non-unary operators which indicate a line continuation if used at the end of a line
80.124 - NONUNARY_OP(null, OPERATOR_CAT);
80.125 - private final String fixedText;
80.126 - private final String primaryCategory;
80.127 -
80.128 - PythonTokenId(String fixedText, String primaryCategory) {
80.129 - this.fixedText = fixedText;
80.130 - this.primaryCategory = primaryCategory;
80.131 - }
80.132 -
80.133 - @Override
80.134 - public String primaryCategory() {
80.135 - return primaryCategory;
80.136 - }
80.137 -
80.138 - public String fixedText() {
80.139 - return fixedText;
80.140 - }
80.141 - private static final Language<PythonTokenId> language =
80.142 - new LanguageHierarchy<PythonTokenId>() {
80.143 - @Override
80.144 - protected String mimeType() {
80.145 - return PythonMIMEResolver.PYTHON_MIME_TYPE;
80.146 - }
80.147 -
80.148 - @Override
80.149 - protected Collection<PythonTokenId> createTokenIds() {
80.150 - return EnumSet.allOf(PythonTokenId.class);
80.151 - }
80.152 -
80.153 - @Override
80.154 - protected Map<String, Collection<PythonTokenId>> createTokenCategories() {
80.155 - Map<String, Collection<PythonTokenId>> cats =
80.156 - new HashMap<>();
80.157 - return cats;
80.158 - }
80.159 -
80.160 - @Override
80.161 - protected Lexer<PythonTokenId> createLexer(LexerRestartInfo<PythonTokenId> info) {
80.162 - FileObject fileObject = (FileObject)info.getAttributeValue(FileObject.class);
80.163 - final TokenFactory<PythonTokenId> tokenFactory = info.tokenFactory();
80.164 - final LexerInput input = info.input();
80.165 - // Lex .rst files just as literal strings
80.166 - if (fileObject != null && PythonUtils.isRstFile(fileObject)) {
80.167 - return new Lexer<PythonTokenId>() {
80.168 - @Override
80.169 - public Token<PythonTokenId> nextToken() {
80.170 - if (input.read() == LexerInput.EOF) {
80.171 - return null;
80.172 - }
80.173 - while (input.read() != LexerInput.EOF) {
80.174 - ;
80.175 - }
80.176 - return tokenFactory.createToken(PythonTokenId.STRING_LITERAL, input.readLength());
80.177 - }
80.178 -
80.179 - @Override
80.180 - public Object state() {
80.181 - return null;
80.182 - }
80.183 -
80.184 - @Override
80.185 - public void release() {
80.186 - }
80.187 - };
80.188 - }
80.189 - return new PythonLexer(info);
80.190 - }
80.191 -
80.192 - @Override
80.193 - protected LanguageEmbedding<?> embedding(Token<PythonTokenId> token,
80.194 - LanguagePath languagePath, InputAttributes inputAttributes) {
80.195 - PythonTokenId id = token.id();
80.196 - if (id == STRING_LITERAL) {
80.197 - return LanguageEmbedding.create(PythonStringTokenId.language, 0, 0);
80.198 - } else if (id == COMMENT) {
80.199 - return LanguageEmbedding.create(PythonCommentTokenId.language(), 1, 0);
80.200 - }
80.201 -
80.202 - return null; // No embedding
80.203 - }
80.204 - }.language();
80.205 -
80.206 - public static Language<PythonTokenId> language() {
80.207 - return language;
80.208 - }
80.209 -}
81.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/Bundle.properties Mon Aug 31 12:40:19 2015 +0200
81.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
81.3 @@ -1,284 +0,0 @@
81.4 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
81.5 -#
81.6 -# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
81.7 -#
81.8 -# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
81.9 -# Other names may be trademarks of their respective owners.
81.10 -#
81.11 -# The contents of this file are subject to the terms of either the GNU
81.12 -# General Public License Version 2 only ("GPL") or the Common
81.13 -# Development and Distribution License("CDDL") (collectively, the
81.14 -# "License"). You may not use this file except in compliance with the
81.15 -# License. You can obtain a copy of the License at
81.16 -# http://www.netbeans.org/cddl-gplv2.html
81.17 -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
81.18 -# specific language governing permissions and limitations under the
81.19 -# License. When distributing the software, include this License Header
81.20 -# Notice in each file and include the License file at
81.21 -# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
81.22 -# particular file as subject to the "Classpath" exception as provided
81.23 -# by Oracle in the GPL Version 2 section of the License file that
81.24 -# accompanied this code. If applicable, add the following below the
81.25 -# License Header, with the fields enclosed by brackets [] replaced by
81.26 -# your own identifying information:
81.27 -# "Portions Copyrighted [year] [name of copyright owner]"
81.28 -#
81.29 -# Contributor(s):
81.30 -#
81.31 -# The Original Software is NetBeans. The Initial Developer of the Original
81.32 -# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
81.33 -# Microsystems, Inc. All Rights Reserved.
81.34 -#
81.35 -# If you wish your version of this file to be governed by only the CDDL
81.36 -# or only the GPL Version 2, indicate your decision by adding
81.37 -# "[Contributor] elects to include this software in this distribution
81.38 -# under the [CDDL or GPL Version 2] license." If you do not indicate a
81.39 -# single choice of license, a recipient has the option to distribute
81.40 -# your version of this file under either the CDDL, the GPL Version 2 or
81.41 -# to extend the choice of license to its licensees as provided above.
81.42 -# However, if you add GPL Version 2 code and therefore, elected the GPL
81.43 -# Version 2 license, then the option applies only if the new code is
81.44 -# made subject to such option by the copyright holder.
81.45 -
81.46 -# Formating options
81.47 -
81.48 -LBL_TabsAndIndents=Tabs and Indents
81.49 -LBL_CodeGeneration=Code Generation
81.50 -LBL_Alignment=Alignment
81.51 -LBL_Wrapping=Wrapping
81.52 -LBL_BlankLines=Blank Lines
81.53 -LBL_Spaces=Spaces
81.54 -LBL_Imports=Imports
81.55 -
81.56 -LBL_bp_SAME_LINE=Same Line
81.57 -LBL_bp_NEW_LINE=New Line
81.58 -LBL_bp_NEW_LINE_HALF_INDENTED=New Line Half Indented
81.59 -LBL_bp_NEW_LINE_INDENTED= New Line Indented
81.60 -
81.61 -LBL_bg_GENERATE=Generate
81.62 -LBL_bg_LEAVE_ALONE=Leave Alone
81.63 -LBL_bg_ELIMINATE=Eliminate
81.64 -
81.65 -LBL_wrp_WRAP_ALWAYS=Always
81.66 -LBL_wrp_WRAP_IF_LONG=If Long
81.67 -LBL_wrp_WRAP_NEVER=Never
81.68 -
81.69 -LBL_imp_COMMENT_OUT=Comment Out
81.70 -LBL_imp_LEAVE_ALONE=Leave Alone
81.71 -LBL_imp_DELETE=Delete
81.72 -
81.73 -LBL_ExpandTabToSpaces=&Expand Tab to Spaces
81.74 -LBL_TabSize=&Tab Size:
81.75 -LBL_IndentSize=&Indentation Size:
81.76 -LBL_ContinuationIndentSize=&Continuation Indentation Size:
81.77 -LBL_LabelIndent=&Label Indentation\:
81.78 -LBL_AbsoluteLabelIndent=&Absolute Label Indentation
81.79 -LBL_IndentTopLevelClassMemberts=Indent Top Level Class &Members
81.80 -LBL_AddLeadingStarInComment=Add Leading Star In Comment
81.81 -LBL_RightMargin=&Right Margin:
81.82 -
81.83 -LBL_Naming=Naming\:
81.84 -LBL_PreferLongerNames=Prefer Longer Names
81.85 -LBL_Prefix=Prefix
81.86 -LBL_Suffix=Suffix
81.87 -LBL_Field=Field\:
81.88 -LBL_StaticField=Static Field\:
81.89 -LBL_Parameter=Parameter\:
81.90 -LBL_LocalVariable=Local Variable\:
81.91 -LBL_Misc=Misc\:
81.92 -LBL_QualifyFieldAccess=Qualify Field Access
81.93 -LBL_UseIsForBooleanGetters=Use Is For Boolean Getters
81.94 -LBL_AddOverrideAnnotation=Add Override Annotation
81.95 -LBL_FinalMofier=Final Modifier\:
81.96 -LBL_ParametersFinal=Make Generated Parameters Final
81.97 -LBL_LocalVariablesFinal=Make Generated Local variables Final
81.98 -LBL_ImportOredering=Import Ordering\:
81.99 -LBL_ImportUp=Move Up
81.100 -LBL_ImportDown=Move Down
81.101 -LBL_blBeforePackage=Before &Package\:
81.102 -LBL_blAfterPackage=After P&ackage\:
81.103 -LBL_blBeforeImports=Before &Imports\:
81.104 -LBL_blAfterImports=After I&mports\:
81.105 -LBL_blBeforeClass=Before &Class\:
81.106 -LBL_blAfterClass=After C&lass\:
81.107 -LBL_blAfterClassHeader=After Class &Header\:
81.108 -LBL_blBeforeFields=Before &Field\:
81.109 -LBL_blAfterFields=After Fi&eld\:
81.110 -LBL_blBeforeMethods=Before &Method\:
81.111 -LBL_blAfterMethods=After Me&thod\:
81.112 -
81.113 -LBL_BeforeKeywords=Before Keywords
81.114 -LBL_spaceBeforeWhile="while"
81.115 -LBL_spaceBeforeElse="else"
81.116 -LBL_spaceBeforeCatch="catch"
81.117 -LBL_spaceBeforeFinally="finally"
81.118 -
81.119 -LBL_BeforeParentheses=Before Parentheses
81.120 -LBL_spaceBeforeMethodDeclParen=Method Declaration
81.121 -LBL_spaceBeforeMethodCallParen=Method Call
81.122 -LBL_spaceBeforeIfParen="if"
81.123 -LBL_spaceBeforeForParen="for"
81.124 -LBL_spaceBeforeWhileParen="while"
81.125 -LBL_spaceBeforeCatchParen="catch"
81.126 -LBL_spaceBeforeSwitchParen="switch"
81.127 -LBL_spaceBeforeSynchronizedParen="synchronized"
81.128 -LBL_spaceBeforeAnnotationParen=Annotation Parameters
81.129 -
81.130 -LBL_AroundOperators=Around Operators
81.131 -LBL_spaceAroundUnaryOps=Unary Operators
81.132 -LBL_spaceAroundBinaryOps=Binary Operators
81.133 -LBL_spaceAroundTernaryOps=Ternary Operators
81.134 -LBL_spaceAroundAssignOps=Assignment Operators
81.135 -
81.136 -LBL_BeforeLeftBraces=Before Left Braces
81.137 -LBL_spaceBeforeClassDeclLeftBrace=Class Declaration
81.138 -LBL_spaceBeforeMethodDeclLeftBrace=Method Declaration
81.139 -LBL_spaceBeforeIfLeftBrace="if"
81.140 -LBL_spaceBeforeElseLeftBrace="else"
81.141 -LBL_spaceBeforeWhileLeftBrace="while"
81.142 -LBL_spaceBeforeForLeftBrace="for"
81.143 -LBL_spaceBeforeDoLeftBrace="do"
81.144 -LBL_spaceBeforeSwitchLeftBrace="switch"
81.145 -LBL_spaceBeforeTryLeftBrace="try"
81.146 -LBL_spaceBeforeCatchLeftBrace="catch"
81.147 -LBL_spaceBeforeFinallyLeftBrace="finally"
81.148 -LBL_spaceBeforeSynchronizedLeftBrace="synchronized"
81.149 -LBL_spaceBeforeStaticInitLeftBrace=Static Initializer
81.150 -LBL_spaceBeforeArrayInitLeftBrace=Array Initializer
81.151 -
81.152 -LBL_WithinParentheses=Within Parentheses
81.153 -LBL_spaceWithinParens=Parentheses
81.154 -LBL_spaceWithinMethodDeclParens=Method Declaration
81.155 -LBL_spaceWithinMethodCallParens=Method Call
81.156 -LBL_spaceWithinIfParens="if"
81.157 -LBL_spaceWithinForParens="for"
81.158 -LBL_spaceWithinWhileParens="while"
81.159 -LBL_spaceWithinSwitchParens="switch"
81.160 -LBL_spaceWithinCatchParens="catch"
81.161 -LBL_spaceWithinSynchronizedParens="synchronized"
81.162 -LBL_spaceWithinTypeCastParens=Type Cast
81.163 -LBL_spaceWithinAnnotationParens=Annotation
81.164 -LBL_spaceWithinBraces=Braces
81.165 -LBL_spaceWithinArrayInitBrackets=Array Initializer Brackets
81.166 -
81.167 -LBL_Other=Other
81.168 -LBL_spaceBeforeComma=Before Comma
81.169 -LBL_spaceAfterComma=After Comma
81.170 -LBL_spaceBeforeSemi=Before Semicolon
81.171 -LBL_spaceAfterSemi=After Semicolon
81.172 -LBL_spaceBeforeColon=Before Colon
81.173 -LBL_spaceAfterColon=After Colon
81.174 -LBL_spaceAfterTypeCast=After Type Cast
81.175 -LBL_wrp_extendsImplementsKeyword=&Extends/Implements Keyword\:
81.176 -LBL_wrp_extendsImplementsList=E&xtends/Implements List\:
81.177 -LBL_wrp_methodParameters=Method &Parameters\:
81.178 -LBL_wrp_throwsKeyword=&Throws Keyword\:
81.179 -LBL_wrp_throwsList=Th&rows List\:
81.180 -LBL_wrp_methodCallArgs=Method Call &Arguments\:
81.181 -LBL_wrp_annotationArgs=Annotation Arg&uments\:
81.182 -LBL_wrp_chainedMethodCalls=C&hained Method Calls\:
81.183 -LBL_wrp_arrayInit=Array Initiali&zer\:
81.184 -LBL_wrp_for=&For\:
81.185 -LBL_wrp_forStatement=F&or Statement\:
81.186 -LBL_wrp_ifStatement=&If Statement\:
81.187 -LBL_wrp_whileStatement=&While Statement\:
81.188 -LBL_wrp_doWhileStatement=&Do ... While Statement
81.189 -LBL_wrp_assert=&Assert\:
81.190 -LBL_wrp_enumConstants=Enum &Constants\:
81.191 -LBL_wrp_annotations=A&nnotations\:
81.192 -LBL_wrp_binaryOps=&Binary Operators\:
81.193 -LBL_wrp_ternaryOps=Ternar&y Operators\:
81.194 -LBL_wrp_assignOps=Assi&gnment Operators\:
81.195 -
81.196 -LBL_br_bracesPlacement=Braces Placement
81.197 -LBL_br_bracesGeneration=Braces Generation
81.198 -LBL_al_newLines=New Lines
81.199 -LBL_al_multilineAlignment=Multiline Alignment
81.200 -LBL_nl_Else="&else"
81.201 -LBL_nl_While="w&hile"
81.202 -LBL_nl_Catch="c&atch"
81.203 -LBL_nl_Finally="finall&y"
81.204 -LBL_nl_Modifiers=after modifie&rs
81.205 -LBL_am_MethodParams=Method &Parameters
81.206 -LBL_am_CallArgs=Method Call Arg&uments
81.207 -LBL_am_AnnotationArgs=&Annotation Arguments
81.208 -LBL_an_Implements=I&mplements List
81.209 -LBL_am_Throws=&Throws List
81.210 -LBL_am_Paren=Parenthesize&d
81.211 -LBL_am_BinaryOp=&Binary Operators
81.212 -LBL_am_TernaryOp=Ter&nary Operators
81.213 -LBL_am_Assign=Assi&gnment
81.214 -LBL_am_For=&For
81.215 -LBL_am_ArrayInit=Array Initiali&zer
81.216 -
81.217 -LBL_IndentCasesFromSwitch=Indent Case Statements In &Switch
81.218 -
81.219 -# Following entries (marked) as samples are used as examples in the formating
81.220 -# options. It is highly discourage to localize them unless absolutely necessary.
81.221 -
81.222 -SAMPLE_Default=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC
81.223 -SAMPLE_TabsIndents=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC {
81.224 -SAMPLE_AlignBraces=@Anno(paramA="a Value", paramB="bValue")\n
81.225 -SAMPLE_Wrapping=@Anno(paramA="a Value", paramB="bValue")
81.226 -SAMPLE_BlankLines=package org.netbeans.samples;
81.227 -
81.228 -SAMPLE_Imports=\
81.229 -# Copyright 2008\n\
81.230 -"""My Module"""\n\
81.231 -\n\
81.232 -import sys\n\
81.233 -import wsgiref.handlers\n\
81.234 -from google.appengine.ext.webapp.util import run_wsgi_app\n\
81.235 -from google.appengine.ext import webapp\n\
81.236 -from google.appengine.ext import db\n\
81.237 -import os\n\
81.238 -\n\
81.239 -\n\
81.240 -from google.appengine.api import users\n\
81.241 -import google.appengine.api.test\n\
81.242 -from google.appengine.api import users\n\
81.243 -\n\
81.244 -from google.appengine.api import users\n\
81.245 -from google.appengine.api import users\n\
81.246 -import string\n\
81.247 -from google.appengine.ext.webapp import template as FooBar\n\
81.248 -from google.appengine.ext.webapp.util import login_required\n\
81.249 -import random\n\
81.250 -import datetime\n
81.251 -
81.252 -#\n\
81.253 -#new_str = swapcase("foo")
81.254 -
81.255 -
81.256 -# Newlines on the following line since space prefixes are ignored by the .properties loader
81.257 -SAMPLE_Spaces=\
81.258 -def func( arg1 ,arg2 ,\
81.259 -\n arg3 = 3, arg = 4):\
81.260 -\n\
81.261 -\n if pos!=-1 and optval[ pos-1 ].isspace():\
81.262 -\n x=5+2\
81.263 -\n\
81.264 -\nmodeDict = { 'r':'rb','w':'wb', \\\
81.265 -\n 'a' : 'r+b' }\
81.266 -\nx = 2; y=3 ; z = 5\n
81.267 -
81.268 -
81.269 -nlFinallyCheckBox1.text="finall&y"
81.270 -
81.271 -
81.272 -AN_Preview=Preview
81.273 -AD_Preview=Preview
81.274 -FmtImports.formatImportsCb.text=Organize Imports during formatting
81.275 -FmtImports.removeDuplicateCb.text=Remove Duplicate Imports
81.276 -FmtImports.systemLibsCb.text=Separate out system libraries
81.277 -FmtImports.onePerLineCb.text=Prefer one import per line
81.278 -FmtImports.cleanupLabel.text=Unused imports:
81.279 -FmtImports.preferSymbols.text=Prefer symbol imports
81.280 -FmtImports.sortImportsCb.text=Sort Alphabetically
81.281 -FmtSpaces.addAroundOp.text=Add spaces around operators
81.282 -FmtSpaces.removeInParam.text=But remove in parameter assignments
81.283 -FmtSpaces.removeInParen.text=Remove spaces inside ( ), { }, and [ ]
81.284 -FmtSpaces.addAfterComma.text=Add spaces after commas
81.285 -FmtSpaces.removeBeforeSep.text=Remove spaces before separators ( : , ; )
81.286 -FmtSpaces.collapseSpacesCb.text=Collapse multiple spaces
81.287 -FmtImports.sepFromImpCb.text=Separate "from" and "import" statements
82.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/CodeStyle.java Mon Aug 31 12:40:19 2015 +0200
82.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
82.3 @@ -1,737 +0,0 @@
82.4 -/*
82.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
82.6 - *
82.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
82.8 - *
82.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
82.10 - * Other names may be trademarks of their respective owners.
82.11 - *
82.12 - * The contents of this file are subject to the terms of either the GNU
82.13 - * General Public License Version 2 only ("GPL") or the Common
82.14 - * Development and Distribution License("CDDL") (collectively, the
82.15 - * "License"). You may not use this file except in compliance with the
82.16 - * License. You can obtain a copy of the License at
82.17 - * http://www.netbeans.org/cddl-gplv2.html
82.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
82.19 - * specific language governing permissions and limitations under the
82.20 - * License. When distributing the software, include this License Header
82.21 - * Notice in each file and include the License file at
82.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
82.23 - * particular file as subject to the "Classpath" exception as provided
82.24 - * by Oracle in the GPL Version 2 section of the License file that
82.25 - * accompanied this code. If applicable, add the following below the
82.26 - * License Header, with the fields enclosed by brackets [] replaced by
82.27 - * your own identifying information:
82.28 - * "Portions Copyrighted [year] [name of copyright owner]"
82.29 - *
82.30 - * Contributor(s):
82.31 - *
82.32 - * The Original Software is NetBeans. The Initial Developer of the Original
82.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
82.34 - * Microsystems, Inc. All Rights Reserved.
82.35 - *
82.36 - * If you wish your version of this file to be governed by only the CDDL
82.37 - * or only the GPL Version 2, indicate your decision by adding
82.38 - * "[Contributor] elects to include this software in this distribution
82.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
82.40 - * single choice of license, a recipient has the option to distribute
82.41 - * your version of this file under either the CDDL, the GPL Version 2 or
82.42 - * to extend the choice of license to its licensees as provided above.
82.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
82.44 - * Version 2 license, then the option applies only if the new code is
82.45 - * made subject to such option by the copyright holder.
82.46 - */
82.47 -package org.netbeans.modules.python.editor.options;
82.48 -
82.49 -import java.util.prefs.Preferences;
82.50 -import javax.swing.text.Document;
82.51 -import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
82.52 -
82.53 -import org.openide.filesystems.FileObject;
82.54 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
82.55 -
82.56 -/**
82.57 - * XXX make sure the getters get the defaults from somewhere
82.58 - * XXX add support for profiles
82.59 - * XXX get the preferences node from somewhere else in odrer to be able not to
82.60 - * use the getters and to be able to write to it.
82.61 - *
82.62 - * @author Dusan Balek
82.63 - */
82.64 -public final class CodeStyle {
82.65 - static {
82.66 - FmtOptions.codeStyleProducer = new Producer();
82.67 - }
82.68 - private Preferences preferences;
82.69 -
82.70 - private CodeStyle(Preferences preferences) {
82.71 - this.preferences = preferences;
82.72 - }
82.73 -
82.74 -// /**
82.75 -// * Gets <code>CodeStyle</code> for files in the given project.
82.76 -// *
82.77 -// * <p>Please see the other two <code>getDefault</code> methods as they are
82.78 -// * the preferred way of getting <code>CodeStyle</code>.
82.79 -// *
82.80 -// * @param project The project to get the <code>CodeStyle</code> for.
82.81 -// * @return The current code style that would be used by documents opened
82.82 -// * from files belonging to the <code>project</code>.
82.83 -// *
82.84 -// * @deprecated Please use {@link #getDefault(javax.swing.text.Document)}
82.85 -// * or {@link #getDefault(org.openide.filesystems.FileObject)} respectively.
82.86 -// */
82.87 -// @Deprecated
82.88 -// public static CodeStyle getDefault(Project project) {
82.89 -// return getDefault(project.getProjectDirectory());
82.90 -// }
82.91 - /**
82.92 - * Gets <code>CodeStyle</code> for the given file. If you have a document
82.93 - * instance you should use the {@link #getDefault(javax.swing.text.Document)}
82.94 - * method.
82.95 - *
82.96 - * @param file The file to get the <code>CodeStyle</code> for.
82.97 - * @return The current code style that would be used by a document if the
82.98 - * <code>file</code> were opened in the editor.
82.99 - *
82.100 - * @since 0.39
82.101 - */
82.102 - public synchronized static CodeStyle getDefault(FileObject file) {
82.103 - Preferences prefs = CodeStylePreferences.get(file).getPreferences();
82.104 - return FmtOptions.codeStyleProducer.create(prefs);
82.105 - }
82.106 -
82.107 - /**
82.108 - * Gets <code>CodeStyle</code> for the given document. This is the preferred
82.109 - * method of getting <code>CodeStyle</code>. If you don't have a document
82.110 - * you can use {@link #getDefault(org.openide.filesystems.FileObject)} method instead.
82.111 - *
82.112 - * @param doc The document to get the <code>CodeStyle</code> for.
82.113 - * @return The current code style used by a document. This is the code style that
82.114 - * will be used when formatting the document or generating new code.
82.115 - *
82.116 - * @since 0.39
82.117 - */
82.118 - public synchronized static CodeStyle getDefault(Document doc) {
82.119 - Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
82.120 - return FmtOptions.codeStyleProducer.create(prefs);
82.121 - }
82.122 -
82.123 - // General tabs and indents ------------------------------------------------
82.124 - public boolean expandTabToSpaces() {
82.125 -// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
82.126 - return preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
82.127 - }
82.128 -
82.129 - public int getTabSize() {
82.130 -// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
82.131 - return preferences.getInt(tabSize, getDefaultAsInt(tabSize));
82.132 - }
82.133 -
82.134 - public int getIndentSize() {
82.135 -// System.out.println("~~~ indent-shift-width=" + preferences.get(SimpleValueNames.INDENT_SHIFT_WIDTH, null));
82.136 - int indentLevel = preferences.getInt(indentSize, getDefaultAsInt(indentSize));
82.137 -
82.138 - if (indentLevel <= 0) {
82.139 -// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
82.140 - boolean expandTabs = preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
82.141 - if (expandTabs) {
82.142 -// System.out.println("~~~ spaces-per-tab=" + preferences.get(SimpleValueNames.SPACES_PER_TAB, null));
82.143 - indentLevel = preferences.getInt(spacesPerTab, getDefaultAsInt(spacesPerTab));
82.144 - } else {
82.145 -// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
82.146 - indentLevel = preferences.getInt(tabSize, getDefaultAsInt(tabSize));
82.147 - }
82.148 - }
82.149 -
82.150 - return indentLevel;
82.151 - }
82.152 -
82.153 - public int getContinuationIndentSize() {
82.154 - return preferences.getInt(continuationIndentSize, getDefaultAsInt(continuationIndentSize));
82.155 - }
82.156 -
82.157 - public int getLabelIndent() {
82.158 - return preferences.getInt(labelIndent, getDefaultAsInt(labelIndent));
82.159 - }
82.160 -
82.161 - public boolean absoluteLabelIndent() {
82.162 - return preferences.getBoolean(absoluteLabelIndent, getDefaultAsBoolean(absoluteLabelIndent));
82.163 - }
82.164 -
82.165 - public boolean indentTopLevelClassMembers() {
82.166 - return preferences.getBoolean(indentTopLevelClassMembers, getDefaultAsBoolean(indentTopLevelClassMembers));
82.167 - }
82.168 -
82.169 - public boolean indentCasesFromSwitch() {
82.170 - return preferences.getBoolean(indentCasesFromSwitch, getDefaultAsBoolean(indentCasesFromSwitch));
82.171 - }
82.172 -
82.173 - public int getRightMargin() {
82.174 - return preferences.getInt(rightMargin, getDefaultAsInt(rightMargin));
82.175 - }
82.176 -
82.177 - /*
82.178 - public boolean addLeadingStarInComment() {
82.179 - return preferences.getBoolean(addLeadingStarInComment, getDefaultAsBoolean(addLeadingStarInComment));
82.180 - }
82.181 -
82.182 - // Code generation ---------------------------------------------------------
82.183 -
82.184 - public boolean preferLongerNames() {
82.185 - return preferences.getBoolean(preferLongerNames, getDefaultAsBoolean(preferLongerNames));
82.186 - }
82.187 -
82.188 - public String getFieldNamePrefix() {
82.189 - return preferences.get(fieldNamePrefix, getDefaultAsString(fieldNamePrefix));
82.190 - }
82.191 -
82.192 - public String getFieldNameSuffix() {
82.193 - return preferences.get(fieldNameSuffix, getDefaultAsString(fieldNameSuffix));
82.194 - }
82.195 -
82.196 - public String getStaticFieldNamePrefix() {
82.197 - return preferences.get(staticFieldNamePrefix, getDefaultAsString(staticFieldNamePrefix));
82.198 - }
82.199 -
82.200 - public String getStaticFieldNameSuffix() {
82.201 - return preferences.get(staticFieldNameSuffix, getDefaultAsString(staticFieldNameSuffix));
82.202 - }
82.203 -
82.204 - public String getParameterNamePrefix() {
82.205 - return preferences.get(parameterNamePrefix, getDefaultAsString(parameterNamePrefix));
82.206 - }
82.207 -
82.208 - public String getParameterNameSuffix() {
82.209 - return preferences.get(parameterNameSuffix, getDefaultAsString(parameterNameSuffix));
82.210 - }
82.211 -
82.212 - public String getLocalVarNamePrefix() {
82.213 - return preferences.get(localVarNamePrefix, getDefaultAsString(localVarNamePrefix));
82.214 - }
82.215 -
82.216 - public String getLocalVarNameSuffix() {
82.217 - return preferences.get(localVarNameSuffix, getDefaultAsString(localVarNameSuffix));
82.218 - }
82.219 -
82.220 - public boolean qualifyFieldAccess() {
82.221 - return preferences.getBoolean(qualifyFieldAccess, getDefaultAsBoolean(qualifyFieldAccess));
82.222 - }
82.223 -
82.224 - public boolean useIsForBooleanGetters() {
82.225 - return preferences.getBoolean(useIsForBooleanGetters, getDefaultAsBoolean(useIsForBooleanGetters));
82.226 - }
82.227 -
82.228 - public boolean addOverrideAnnotation() {
82.229 - return preferences.getBoolean(addOverrideAnnotation, getDefaultAsBoolean(addOverrideAnnotation));
82.230 - }
82.231 -
82.232 - public boolean makeLocalVarsFinal() {
82.233 - return preferences.getBoolean(makeLocalVarsFinal, getDefaultAsBoolean(makeLocalVarsFinal));
82.234 - }
82.235 -
82.236 - // Alignment ----------------------------------------------------
82.237 -
82.238 - public boolean alignMultilineMethodParams() {
82.239 - return preferences.getBoolean(alignMultilineMethodParams, getDefaultAsBoolean(alignMultilineMethodParams));
82.240 - }
82.241 -
82.242 - public boolean alignMultilineCallArgs() {
82.243 - return preferences.getBoolean(alignMultilineCallArgs, getDefaultAsBoolean(alignMultilineCallArgs));
82.244 - }
82.245 -
82.246 - public boolean alignMultilineAnnotationArgs() {
82.247 - return preferences.getBoolean(alignMultilineAnnotationArgs, getDefaultAsBoolean(alignMultilineAnnotationArgs));
82.248 - }
82.249 -
82.250 - public boolean alignMultilineImplements() {
82.251 - return preferences.getBoolean(alignMultilineImplements, getDefaultAsBoolean(alignMultilineImplements));
82.252 - }
82.253 -
82.254 - public boolean alignMultilineThrows() {
82.255 - return preferences.getBoolean(alignMultilineThrows, getDefaultAsBoolean(alignMultilineThrows));
82.256 - }
82.257 -
82.258 - public boolean alignMultilineParenthesized() {
82.259 - return preferences.getBoolean(alignMultilineParenthesized, getDefaultAsBoolean(alignMultilineParenthesized));
82.260 - }
82.261 -
82.262 - public boolean alignMultilineBinaryOp() {
82.263 - return preferences.getBoolean(alignMultilineBinaryOp, getDefaultAsBoolean(alignMultilineBinaryOp));
82.264 - }
82.265 -
82.266 - public boolean alignMultilineTernaryOp() {
82.267 - return preferences.getBoolean(alignMultilineTernaryOp, getDefaultAsBoolean(alignMultilineTernaryOp));
82.268 - }
82.269 -
82.270 - public boolean alignMultilineAssignment() {
82.271 - return preferences.getBoolean(alignMultilineAssignment, getDefaultAsBoolean(alignMultilineAssignment));
82.272 - }
82.273 -
82.274 - public boolean alignMultilineFor() {
82.275 - return preferences.getBoolean(alignMultilineFor, getDefaultAsBoolean(alignMultilineFor));
82.276 - }
82.277 -
82.278 - public boolean alignMultilineArrayInit() {
82.279 - return preferences.getBoolean(alignMultilineArrayInit, getDefaultAsBoolean(alignMultilineArrayInit));
82.280 - }
82.281 -
82.282 - public boolean placeElseOnNewLine() {
82.283 - return preferences.getBoolean(placeElseOnNewLine, getDefaultAsBoolean(placeElseOnNewLine));
82.284 - }
82.285 -
82.286 - public boolean placeWhileOnNewLine() {
82.287 - return preferences.getBoolean(placeWhileOnNewLine, getDefaultAsBoolean(placeWhileOnNewLine));
82.288 - }
82.289 -
82.290 - public boolean placeCatchOnNewLine() {
82.291 - return preferences.getBoolean(placeCatchOnNewLine, getDefaultAsBoolean(placeCatchOnNewLine));
82.292 - }
82.293 -
82.294 - public boolean placeFinallyOnNewLine() {
82.295 - return preferences.getBoolean(placeFinallyOnNewLine, getDefaultAsBoolean(placeFinallyOnNewLine));
82.296 - }
82.297 -
82.298 - public boolean placeNewLineAfterModifiers() {
82.299 - return preferences.getBoolean(placeNewLineAfterModifiers, getDefaultAsBoolean(placeNewLineAfterModifiers));
82.300 - }
82.301 -
82.302 - // Wrapping ----------------------------------------------------------------
82.303 -
82.304 - public WrapStyle wrapExtendsImplementsKeyword() {
82.305 - String wrap = preferences.get(wrapExtendsImplementsKeyword, getDefaultAsString(wrapExtendsImplementsKeyword));
82.306 - return WrapStyle.valueOf(wrap);
82.307 - }
82.308 -
82.309 - public WrapStyle wrapExtendsImplementsList() {
82.310 - String wrap = preferences.get(wrapExtendsImplementsList, getDefaultAsString(wrapExtendsImplementsList));
82.311 - return WrapStyle.valueOf(wrap);
82.312 - }
82.313 -
82.314 - public WrapStyle wrapMethodParams() {
82.315 - String wrap = preferences.get(wrapMethodParams, getDefaultAsString(wrapMethodParams));
82.316 - return WrapStyle.valueOf(wrap);
82.317 - }
82.318 -
82.319 - public WrapStyle wrapThrowsKeyword() {
82.320 - String wrap = preferences.get(wrapThrowsKeyword, getDefaultAsString(wrapThrowsKeyword));
82.321 - return WrapStyle.valueOf(wrap);
82.322 - }
82.323 -
82.324 - public WrapStyle wrapThrowsList() {
82.325 - String wrap = preferences.get(wrapThrowsList, getDefaultAsString(wrapThrowsList));
82.326 - return WrapStyle.valueOf(wrap);
82.327 - }
82.328 -
82.329 - public WrapStyle wrapMethodCallArgs() {
82.330 - String wrap = preferences.get(wrapMethodCallArgs, getDefaultAsString(wrapMethodCallArgs));
82.331 - return WrapStyle.valueOf(wrap);
82.332 - }
82.333 -
82.334 - public WrapStyle wrapAnnotationArgs() {
82.335 - String wrap = preferences.get(wrapAnnotationArgs, getDefaultAsString(wrapAnnotationArgs));
82.336 - return WrapStyle.valueOf(wrap);
82.337 - }
82.338 -
82.339 - public WrapStyle wrapChainedMethodCalls() {
82.340 - String wrap = preferences.get(wrapChainedMethodCalls, getDefaultAsString(wrapChainedMethodCalls));
82.341 - return WrapStyle.valueOf(wrap);
82.342 - }
82.343 -
82.344 - public WrapStyle wrapArrayInit() {
82.345 - String wrap = preferences.get(wrapArrayInit, getDefaultAsString(wrapArrayInit));
82.346 - return WrapStyle.valueOf(wrap);
82.347 - }
82.348 -
82.349 - public WrapStyle wrapFor() {
82.350 - String wrap = preferences.get(wrapFor, getDefaultAsString(wrapFor));
82.351 - return WrapStyle.valueOf(wrap);
82.352 - }
82.353 -
82.354 - public WrapStyle wrapForStatement() {
82.355 - String wrap = preferences.get(wrapForStatement, getDefaultAsString(wrapForStatement));
82.356 - return WrapStyle.valueOf(wrap);
82.357 - }
82.358 -
82.359 - public WrapStyle wrapIfStatement() {
82.360 - String wrap = preferences.get(wrapIfStatement, getDefaultAsString(wrapIfStatement));
82.361 - return WrapStyle.valueOf(wrap);
82.362 - }
82.363 -
82.364 - public WrapStyle wrapWhileStatement() {
82.365 - String wrap = preferences.get(wrapWhileStatement, getDefaultAsString(wrapWhileStatement));
82.366 - return WrapStyle.valueOf(wrap);
82.367 - }
82.368 -
82.369 - public WrapStyle wrapDoWhileStatement() {
82.370 - String wrap = preferences.get(wrapDoWhileStatement, getDefaultAsString(wrapDoWhileStatement));
82.371 - return WrapStyle.valueOf(wrap);
82.372 - }
82.373 -
82.374 - public WrapStyle wrapAssert() {
82.375 - String wrap = preferences.get(wrapAssert, getDefaultAsString(wrapAssert));
82.376 - return WrapStyle.valueOf(wrap);
82.377 - }
82.378 -
82.379 - public WrapStyle wrapEnumConstants() {
82.380 - String wrap = preferences.get(wrapEnumConstants, getDefaultAsString(wrapEnumConstants));
82.381 - return WrapStyle.valueOf(wrap);
82.382 - }
82.383 -
82.384 - public WrapStyle wrapAnnotations() {
82.385 - String wrap = preferences.get(wrapAnnotations, getDefaultAsString(wrapAnnotations));
82.386 - return WrapStyle.valueOf(wrap);
82.387 - }
82.388 -
82.389 - public WrapStyle wrapBinaryOps() {
82.390 - String wrap = preferences.get(wrapBinaryOps, getDefaultAsString(wrapBinaryOps));
82.391 - return WrapStyle.valueOf(wrap);
82.392 - }
82.393 -
82.394 - public WrapStyle wrapTernaryOps() {
82.395 - String wrap = preferences.get(wrapTernaryOps, getDefaultAsString(wrapTernaryOps));
82.396 - return WrapStyle.valueOf(wrap);
82.397 - }
82.398 -
82.399 - public WrapStyle wrapAssignOps() {
82.400 - String wrap = preferences.get(wrapAssignOps, getDefaultAsString(wrapAssignOps));
82.401 - return WrapStyle.valueOf(wrap);
82.402 - }
82.403 -
82.404 - // Blank lines -------------------------------------------------------------
82.405 -
82.406 - public int getBlankLinesBeforePackage() {
82.407 - return preferences.getInt(blankLinesBeforePackage, getDefaultAsInt(blankLinesBeforePackage));
82.408 - }
82.409 -
82.410 - public int getBlankLinesAfterPackage() {
82.411 - return preferences.getInt(blankLinesAfterPackage, getDefaultAsInt(blankLinesAfterPackage));
82.412 - }
82.413 -
82.414 - public int getBlankLinesBeforeImports() {
82.415 - return preferences.getInt(blankLinesBeforeImports, getDefaultAsInt(blankLinesBeforeImports));
82.416 - }
82.417 -
82.418 - public int getBlankLinesAfterImports() {
82.419 - return preferences.getInt(blankLinesAfterImports, getDefaultAsInt(blankLinesAfterImports));
82.420 - }
82.421 -
82.422 - public int getBlankLinesBeforeClass() {
82.423 - return preferences.getInt(blankLinesBeforeClass, getDefaultAsInt(blankLinesBeforeClass));
82.424 - }
82.425 -
82.426 - public int getBlankLinesAfterClass() {
82.427 - return preferences.getInt(blankLinesAfterClass, getDefaultAsInt(blankLinesAfterClass));
82.428 - }
82.429 -
82.430 - public int getBlankLinesAfterClassHeader() {
82.431 - return preferences.getInt(blankLinesAfterClassHeader, getDefaultAsInt(blankLinesAfterClassHeader));
82.432 - }
82.433 -
82.434 - public int getBlankLinesBeforeFields() {
82.435 - return preferences.getInt(blankLinesBeforeFields, getDefaultAsInt(blankLinesBeforeFields));
82.436 - }
82.437 -
82.438 - public int getBlankLinesAfterFields() {
82.439 - return preferences.getInt(blankLinesAfterFields, getDefaultAsInt(blankLinesAfterFields));
82.440 - }
82.441 -
82.442 - public int getBlankLinesBeforeMethods() {
82.443 - return preferences.getInt(blankLinesBeforeMethods, getDefaultAsInt(blankLinesBeforeMethods));
82.444 - }
82.445 -
82.446 - public int getBlankLinesAfterMethods() {
82.447 - return preferences.getInt(blankLinesAfterMethods, getDefaultAsInt(blankLinesAfterMethods));
82.448 - }
82.449 -
82.450 - // Spaces ------------------------------------------------------------------
82.451 -
82.452 - public boolean spaceBeforeWhile() {
82.453 - return preferences.getBoolean(spaceBeforeWhile, getDefaultAsBoolean(spaceBeforeWhile));
82.454 - }
82.455 -
82.456 - public boolean spaceBeforeElse() {
82.457 - return preferences.getBoolean(spaceBeforeElse, getDefaultAsBoolean(spaceBeforeElse));
82.458 - }
82.459 -
82.460 - public boolean spaceBeforeCatch() {
82.461 - return preferences.getBoolean(spaceBeforeCatch, getDefaultAsBoolean(spaceBeforeCatch));
82.462 - }
82.463 -
82.464 - public boolean spaceBeforeFinally() {
82.465 - return preferences.getBoolean(spaceBeforeFinally, getDefaultAsBoolean(spaceBeforeFinally));
82.466 - }
82.467 -
82.468 - public boolean spaceBeforeMethodDeclParen() {
82.469 - return preferences.getBoolean(spaceBeforeMethodDeclParen, getDefaultAsBoolean(spaceBeforeMethodDeclParen));
82.470 - }
82.471 -
82.472 - public boolean spaceBeforeMethodCallParen() {
82.473 - return preferences.getBoolean(spaceBeforeMethodCallParen, getDefaultAsBoolean(spaceBeforeMethodCallParen));
82.474 - }
82.475 -
82.476 - public boolean spaceBeforeIfParen() {
82.477 - return preferences.getBoolean(spaceBeforeIfParen, getDefaultAsBoolean(spaceBeforeIfParen));
82.478 - }
82.479 -
82.480 - public boolean spaceBeforeForParen() {
82.481 - return preferences.getBoolean(spaceBeforeForParen, getDefaultAsBoolean(spaceBeforeForParen));
82.482 - }
82.483 -
82.484 - public boolean spaceBeforeWhileParen() {
82.485 - return preferences.getBoolean(spaceBeforeWhileParen, getDefaultAsBoolean(spaceBeforeWhileParen));
82.486 - }
82.487 -
82.488 - public boolean spaceBeforeCatchParen() {
82.489 - return preferences.getBoolean(spaceBeforeCatchParen, getDefaultAsBoolean(spaceBeforeCatchParen));
82.490 - }
82.491 -
82.492 - public boolean spaceBeforeSwitchParen() {
82.493 - return preferences.getBoolean(spaceBeforeSwitchParen, getDefaultAsBoolean(spaceBeforeSwitchParen));
82.494 - }
82.495 -
82.496 - public boolean spaceBeforeSynchronizedParen() {
82.497 - return preferences.getBoolean(spaceBeforeSynchronizedParen, getDefaultAsBoolean(spaceBeforeSynchronizedParen));
82.498 - }
82.499 -
82.500 - public boolean spaceBeforeAnnotationParen() {
82.501 - return preferences.getBoolean(spaceBeforeAnnotationParen, getDefaultAsBoolean(spaceBeforeAnnotationParen));
82.502 - }
82.503 -
82.504 - public boolean spaceAroundUnaryOps() {
82.505 - return preferences.getBoolean(spaceAroundUnaryOps, getDefaultAsBoolean(spaceAroundUnaryOps));
82.506 - }
82.507 -
82.508 - public boolean spaceAroundBinaryOps() {
82.509 - return preferences.getBoolean(spaceAroundBinaryOps, getDefaultAsBoolean(spaceAroundBinaryOps));
82.510 - }
82.511 -
82.512 - public boolean spaceAroundTernaryOps() {
82.513 - return preferences.getBoolean(spaceAroundTernaryOps, getDefaultAsBoolean(spaceAroundTernaryOps));
82.514 - }
82.515 -
82.516 - public boolean spaceAroundAssignOps() {
82.517 - return preferences.getBoolean(spaceAroundAssignOps, getDefaultAsBoolean(spaceAroundAssignOps));
82.518 - }
82.519 -
82.520 - public boolean spaceBeforeClassDeclLeftBrace() {
82.521 - return preferences.getBoolean(spaceBeforeClassDeclLeftBrace, getDefaultAsBoolean(spaceBeforeClassDeclLeftBrace));
82.522 - }
82.523 -
82.524 - public boolean spaceBeforeMethodDeclLeftBrace() {
82.525 - return preferences.getBoolean(spaceBeforeMethodDeclLeftBrace, getDefaultAsBoolean(spaceBeforeMethodDeclLeftBrace));
82.526 - }
82.527 -
82.528 - public boolean spaceBeforeIfLeftBrace() {
82.529 - return preferences.getBoolean(spaceBeforeIfLeftBrace, getDefaultAsBoolean(spaceBeforeIfLeftBrace));
82.530 - }
82.531 -
82.532 - public boolean spaceBeforeElseLeftBrace() {
82.533 - return preferences.getBoolean(spaceBeforeElseLeftBrace, getDefaultAsBoolean(spaceBeforeElseLeftBrace));
82.534 - }
82.535 -
82.536 - public boolean spaceBeforeWhileLeftBrace() {
82.537 - return preferences.getBoolean(spaceBeforeWhileLeftBrace, getDefaultAsBoolean(spaceBeforeWhileLeftBrace));
82.538 - }
82.539 -
82.540 - public boolean spaceBeforeForLeftBrace() {
82.541 - return preferences.getBoolean(spaceBeforeForLeftBrace, getDefaultAsBoolean(spaceBeforeForLeftBrace));
82.542 - }
82.543 -
82.544 - public boolean spaceBeforeDoLeftBrace() {
82.545 - return preferences.getBoolean(spaceBeforeDoLeftBrace, getDefaultAsBoolean(spaceBeforeDoLeftBrace));
82.546 - }
82.547 -
82.548 - public boolean spaceBeforeSwitchLeftBrace() {
82.549 - return preferences.getBoolean(spaceBeforeSwitchLeftBrace, getDefaultAsBoolean(spaceBeforeSwitchLeftBrace));
82.550 - }
82.551 -
82.552 - public boolean spaceBeforeTryLeftBrace() {
82.553 - return preferences.getBoolean(spaceBeforeTryLeftBrace, getDefaultAsBoolean(spaceBeforeTryLeftBrace));
82.554 - }
82.555 -
82.556 - public boolean spaceBeforeCatchLeftBrace() {
82.557 - return preferences.getBoolean(spaceBeforeCatchLeftBrace, getDefaultAsBoolean(spaceBeforeCatchLeftBrace));
82.558 - }
82.559 -
82.560 - public boolean spaceBeforeFinallyLeftBrace() {
82.561 - return preferences.getBoolean(spaceBeforeFinallyLeftBrace, getDefaultAsBoolean(spaceBeforeFinallyLeftBrace));
82.562 - }
82.563 -
82.564 - public boolean spaceBeforeSynchronizedLeftBrace() {
82.565 - return preferences.getBoolean(spaceBeforeSynchronizedLeftBrace, getDefaultAsBoolean(spaceBeforeSynchronizedLeftBrace));
82.566 - }
82.567 -
82.568 - public boolean spaceBeforeStaticInitLeftBrace() {
82.569 - return preferences.getBoolean(spaceBeforeStaticInitLeftBrace, getDefaultAsBoolean(spaceBeforeStaticInitLeftBrace));
82.570 - }
82.571 -
82.572 - public boolean spaceBeforeArrayInitLeftBrace() {
82.573 - return preferences.getBoolean(spaceBeforeArrayInitLeftBrace, getDefaultAsBoolean(spaceBeforeArrayInitLeftBrace));
82.574 - }
82.575 -
82.576 - public boolean spaceWithinParens() {
82.577 - return preferences.getBoolean(spaceWithinParens, getDefaultAsBoolean(spaceWithinParens));
82.578 - }
82.579 -
82.580 - public boolean spaceWithinMethodDeclParens() {
82.581 - return preferences.getBoolean(spaceWithinMethodDeclParens, getDefaultAsBoolean(spaceWithinMethodDeclParens));
82.582 - }
82.583 -
82.584 - public boolean spaceWithinMethodCallParens() {
82.585 - return preferences.getBoolean(spaceWithinMethodCallParens, getDefaultAsBoolean(spaceWithinMethodCallParens));
82.586 - }
82.587 -
82.588 - public boolean spaceWithinIfParens() {
82.589 - return preferences.getBoolean(spaceWithinIfParens, getDefaultAsBoolean(spaceWithinIfParens));
82.590 - }
82.591 -
82.592 - public boolean spaceWithinForParens() {
82.593 - return preferences.getBoolean(spaceWithinForParens, getDefaultAsBoolean(spaceWithinForParens));
82.594 - }
82.595 -
82.596 - public boolean spaceWithinWhileParens() {
82.597 - return preferences.getBoolean(spaceWithinWhileParens, getDefaultAsBoolean(spaceWithinWhileParens));
82.598 - }
82.599 -
82.600 - public boolean spaceWithinSwitchParens() {
82.601 - return preferences.getBoolean(spaceWithinSwitchParens, getDefaultAsBoolean(spaceWithinSwitchParens));
82.602 - }
82.603 -
82.604 - public boolean spaceWithinCatchParens() {
82.605 - return preferences.getBoolean(spaceWithinCatchParens, getDefaultAsBoolean(spaceWithinCatchParens));
82.606 - }
82.607 -
82.608 - public boolean spaceWithinSynchronizedParens() {
82.609 - return preferences.getBoolean(spaceWithinSynchronizedParens, getDefaultAsBoolean(spaceWithinSynchronizedParens));
82.610 - }
82.611 -
82.612 - public boolean spaceWithinTypeCastParens() {
82.613 - return preferences.getBoolean(spaceWithinTypeCastParens, getDefaultAsBoolean(spaceWithinTypeCastParens));
82.614 - }
82.615 -
82.616 - public boolean spaceWithinAnnotationParens() {
82.617 - return preferences.getBoolean(spaceWithinAnnotationParens, getDefaultAsBoolean(spaceWithinAnnotationParens));
82.618 - }
82.619 -
82.620 - public boolean spaceWithinBraces() {
82.621 - return preferences.getBoolean(spaceWithinBraces, getDefaultAsBoolean(spaceWithinBraces));
82.622 - }
82.623 -
82.624 - public boolean spaceWithinArrayInitBrackets() {
82.625 - return preferences.getBoolean(spaceWithinArrayInitBrackets, getDefaultAsBoolean(spaceWithinArrayInitBrackets));
82.626 - }
82.627 -
82.628 - public boolean spaceBeforeComma() {
82.629 - return preferences.getBoolean(spaceBeforeComma, getDefaultAsBoolean(spaceBeforeComma));
82.630 - }
82.631 -
82.632 - public boolean spaceAfterComma() {
82.633 - return preferences.getBoolean(spaceAfterComma, getDefaultAsBoolean(spaceAfterComma));
82.634 - }
82.635 -
82.636 - public boolean spaceBeforeSemi() {
82.637 - return preferences.getBoolean(spaceBeforeSemi, getDefaultAsBoolean(spaceBeforeSemi));
82.638 - }
82.639 -
82.640 - public boolean spaceAfterSemi() {
82.641 - return preferences.getBoolean(spaceAfterSemi, getDefaultAsBoolean(spaceAfterSemi));
82.642 - }
82.643 -
82.644 - public boolean spaceBeforeColon() {
82.645 - return preferences.getBoolean(spaceBeforeColon, getDefaultAsBoolean(spaceBeforeColon));
82.646 - }
82.647 -
82.648 - public boolean spaceAfterColon() {
82.649 - return preferences.getBoolean(spaceAfterColon, getDefaultAsBoolean(spaceAfterColon));
82.650 - }
82.651 -
82.652 - public boolean spaceAfterTypeCast() {
82.653 - return preferences.getBoolean(spaceAfterTypeCast, getDefaultAsBoolean(spaceAfterTypeCast));
82.654 - }
82.655 -
82.656 - */
82.657 - // Spaces -----------------------------------------------------------------
82.658 - public boolean addSpaceAroundOperators() {
82.659 - return preferences.getBoolean(addSpaceAroundOperators, getDefaultAsBoolean(addSpaceAroundOperators));
82.660 - }
82.661 -
82.662 - public boolean removeSpaceInsideParens() {
82.663 - return preferences.getBoolean(removeSpaceInParens, getDefaultAsBoolean(removeSpaceInParens));
82.664 - }
82.665 -
82.666 - public boolean addSpaceAfterComma() {
82.667 - return preferences.getBoolean(addSpaceAfterComma, getDefaultAsBoolean(addSpaceAfterComma));
82.668 - }
82.669 -
82.670 - public boolean removeSpaceBeforeSep() {
82.671 - return preferences.getBoolean(removeSpaceBeforeSep, getDefaultAsBoolean(removeSpaceBeforeSep));
82.672 - }
82.673 -
82.674 - public boolean removeSpaceInParamAssign() {
82.675 - return preferences.getBoolean(removeSpaceInParamAssign, getDefaultAsBoolean(removeSpaceInParamAssign));
82.676 - }
82.677 -
82.678 - public boolean collapseSpaces() {
82.679 - return preferences.getBoolean(collapseSpaces, getDefaultAsBoolean(collapseSpaces));
82.680 - }
82.681 -
82.682 - // Imports -----------------------------------------------------------------
82.683 - public boolean formatImports() {
82.684 - return preferences.getBoolean(formatImports, getDefaultAsBoolean(formatImports));
82.685 - }
82.686 -
82.687 - public boolean oneImportPerLine() {
82.688 - return preferences.getBoolean(oneImportPerLine, getDefaultAsBoolean(oneImportPerLine));
82.689 - }
82.690 -
82.691 - public boolean removeDuplicates() {
82.692 - return preferences.getBoolean(removeDuplicates, getDefaultAsBoolean(removeDuplicates));
82.693 - }
82.694 -
82.695 - public boolean systemLibsFirst() {
82.696 - return preferences.getBoolean(systemLibsFirst, getDefaultAsBoolean(systemLibsFirst));
82.697 - }
82.698 -
82.699 - public boolean preferSymbolImports() {
82.700 - return preferences.getBoolean(preferSymbolImports, getDefaultAsBoolean(preferSymbolImports));
82.701 - }
82.702 -
82.703 - public boolean sortImports() {
82.704 - return preferences.getBoolean(sortImports, getDefaultAsBoolean(sortImports));
82.705 - }
82.706 -
82.707 - public boolean separateFromImps() {
82.708 - return preferences.getBoolean(separateFromImps, getDefaultAsBoolean(separateFromImps));
82.709 - }
82.710 -
82.711 - public ImportCleanupStyle cleanupImports() {
82.712 - String cleanup = preferences.get(cleanupUnusedImports, getDefaultAsString(cleanupUnusedImports));
82.713 - return ImportCleanupStyle.valueOf(cleanup);
82.714 - }
82.715 -
82.716 - public String[] getPackagesForStarImport() {
82.717 - return null;
82.718 - }
82.719 -
82.720 - // Nested classes ----------------------------------------------------------
82.721 - public enum WrapStyle {
82.722 - WRAP_ALWAYS,
82.723 - WRAP_IF_LONG,
82.724 - WRAP_NEVER
82.725 - }
82.726 -
82.727 - public enum ImportCleanupStyle {
82.728 - LEAVE_ALONE,
82.729 - COMMENT_OUT,
82.730 - DELETE
82.731 - }
82.732 -
82.733 - // Communication with non public packages ----------------------------------
82.734 - private static class Producer implements FmtOptions.CodeStyleProducer {
82.735 - @Override
82.736 - public CodeStyle create(Preferences preferences) {
82.737 - return new CodeStyle(preferences);
82.738 - }
82.739 - }
82.740 -}
83.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtAlignment.form Mon Aug 31 12:40:19 2015 +0200
83.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
83.3 @@ -1,350 +0,0 @@
83.4 -<?xml version="1.0" encoding="UTF-8" ?>
83.5 -
83.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
83.7 - <Properties>
83.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Alignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.10 - </Property>
83.11 - <Property name="opaque" type="boolean" value="false"/>
83.12 - </Properties>
83.13 - <AuxValues>
83.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
83.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
83.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
83.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
83.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
83.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
83.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
83.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
83.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
83.23 - </AuxValues>
83.24 -
83.25 - <Layout>
83.26 - <DimensionLayout dim="0">
83.27 - <Group type="103" groupAlignment="0" attributes="0">
83.28 - <Group type="102" attributes="0">
83.29 - <Group type="103" groupAlignment="0" attributes="0">
83.30 - <Group type="102" alignment="0" attributes="0">
83.31 - <EmptySpace min="-2" max="-2" attributes="0"/>
83.32 - <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
83.33 - </Group>
83.34 - <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
83.35 - <Group type="102" alignment="0" attributes="1">
83.36 - <Component id="newLinesLabel" min="-2" max="-2" attributes="0"/>
83.37 - <EmptySpace max="-2" attributes="0"/>
83.38 - <Component id="jSeparator1" max="32767" attributes="0"/>
83.39 - </Group>
83.40 - <Group type="102" alignment="0" attributes="1">
83.41 - <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
83.42 - <EmptySpace max="-2" attributes="0"/>
83.43 - <Component id="jSeparator2" max="32767" attributes="1"/>
83.44 - </Group>
83.45 - <Group type="102" alignment="0" attributes="0">
83.46 - <EmptySpace max="-2" attributes="0"/>
83.47 - <Group type="103" groupAlignment="0" attributes="0">
83.48 - <Component id="amThrowsCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
83.49 - <Component id="amBinaryOpCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
83.50 - <Component id="amAssignCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
83.51 - <Component id="amAnnotationArgsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
83.52 - <Component id="nlElseCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
83.53 - <Component id="nlWhileCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
83.54 - <Component id="nlCatchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
83.55 - <Component id="amMethodParamsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
83.56 - </Group>
83.57 - <EmptySpace min="-2" max="-2" attributes="0"/>
83.58 - <Group type="103" groupAlignment="0" attributes="0">
83.59 - <Component id="amCallArgsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
83.60 - <Component id="nlModifiersCheckBox" min="-2" max="-2" attributes="0"/>
83.61 - <Component id="nlFinallyCheckBox" min="-2" max="-2" attributes="0"/>
83.62 - <Component id="amImplementsCheckBox1" min="-2" max="-2" attributes="0"/>
83.63 - <Component id="amArrayInitCheckBox1" min="-2" max="-2" attributes="0"/>
83.64 - <Component id="amTernaryOpCheckBox1" min="-2" max="-2" attributes="0"/>
83.65 - <Component id="amForCheckBox1" min="-2" max="-2" attributes="0"/>
83.66 - </Group>
83.67 - </Group>
83.68 - </Group>
83.69 - </Group>
83.70 - <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
83.71 - </Group>
83.72 - </Group>
83.73 - </DimensionLayout>
83.74 - <DimensionLayout dim="1">
83.75 - <Group type="103" groupAlignment="0" attributes="0">
83.76 - <Group type="102" alignment="0" attributes="0">
83.77 - <Group type="103" groupAlignment="0" attributes="0">
83.78 - <Group type="102" attributes="0">
83.79 - <EmptySpace max="-2" attributes="0"/>
83.80 - <Component id="newLinesLabel" min="-2" max="-2" attributes="1"/>
83.81 - </Group>
83.82 - <Group type="102" attributes="0">
83.83 - <EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
83.84 - <Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
83.85 - </Group>
83.86 - </Group>
83.87 - <EmptySpace max="-2" attributes="0"/>
83.88 - <Group type="103" groupAlignment="3" attributes="0">
83.89 - <Component id="nlElseCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.90 - <Component id="nlFinallyCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.91 - </Group>
83.92 - <EmptySpace max="-2" attributes="0"/>
83.93 - <Group type="103" groupAlignment="3" attributes="0">
83.94 - <Component id="nlWhileCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.95 - <Component id="nlModifiersCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.96 - </Group>
83.97 - <Group type="103" groupAlignment="0" attributes="0">
83.98 - <Group type="102" attributes="0">
83.99 - <EmptySpace max="-2" attributes="0"/>
83.100 - <Component id="nlCatchCheckBox" min="-2" max="-2" attributes="0"/>
83.101 - <EmptySpace type="separate" max="-2" attributes="0"/>
83.102 - <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
83.103 - </Group>
83.104 - <Group type="102" attributes="0">
83.105 - <EmptySpace min="-2" pref="44" max="-2" attributes="0"/>
83.106 - <Component id="jSeparator2" min="-2" pref="10" max="-2" attributes="0"/>
83.107 - </Group>
83.108 - </Group>
83.109 - <EmptySpace min="-2" max="-2" attributes="0"/>
83.110 - <Group type="103" groupAlignment="3" attributes="0">
83.111 - <Component id="amMethodParamsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.112 - <Component id="amCallArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.113 - </Group>
83.114 - <EmptySpace min="-2" max="-2" attributes="0"/>
83.115 - <Group type="103" groupAlignment="3" attributes="0">
83.116 - <Component id="amAnnotationArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
83.117 - <Component id="amImplementsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.118 - </Group>
83.119 - <EmptySpace max="-2" attributes="0"/>
83.120 - <Group type="103" groupAlignment="3" attributes="0">
83.121 - <Component id="amThrowsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.122 - <Component id="amArrayInitCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.123 - </Group>
83.124 - <EmptySpace max="-2" attributes="0"/>
83.125 - <Group type="103" groupAlignment="3" attributes="0">
83.126 - <Component id="amBinaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.127 - <Component id="amTernaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.128 - </Group>
83.129 - <EmptySpace max="-2" attributes="0"/>
83.130 - <Group type="103" groupAlignment="3" attributes="0">
83.131 - <Component id="amAssignCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.132 - <Component id="amForCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
83.133 - </Group>
83.134 - <EmptySpace min="-2" max="-2" attributes="0"/>
83.135 - <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
83.136 - <EmptySpace max="32767" attributes="0"/>
83.137 - </Group>
83.138 - </Group>
83.139 - </DimensionLayout>
83.140 - </Layout>
83.141 - <SubComponents>
83.142 - <Component class="javax.swing.JLabel" name="newLinesLabel">
83.143 - <Properties>
83.144 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.145 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_newLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.146 - </Property>
83.147 - </Properties>
83.148 - </Component>
83.149 - <Component class="javax.swing.JCheckBox" name="nlElseCheckBox">
83.150 - <Properties>
83.151 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.152 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Else" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.153 - </Property>
83.154 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.155 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.156 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.157 - </Border>
83.158 - </Property>
83.159 - </Properties>
83.160 - </Component>
83.161 - <Component class="javax.swing.JCheckBox" name="nlWhileCheckBox">
83.162 - <Properties>
83.163 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.164 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_While" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.165 - </Property>
83.166 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.167 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.168 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.169 - </Border>
83.170 - </Property>
83.171 - </Properties>
83.172 - </Component>
83.173 - <Component class="javax.swing.JCheckBox" name="nlCatchCheckBox">
83.174 - <Properties>
83.175 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.176 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Catch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.177 - </Property>
83.178 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.179 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.180 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.181 - </Border>
83.182 - </Property>
83.183 - </Properties>
83.184 - </Component>
83.185 - <Component class="javax.swing.JCheckBox" name="nlFinallyCheckBox">
83.186 - <Properties>
83.187 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.188 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Finally" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.189 - </Property>
83.190 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.191 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.192 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.193 - </Border>
83.194 - </Property>
83.195 - </Properties>
83.196 - </Component>
83.197 - <Component class="javax.swing.JCheckBox" name="nlModifiersCheckBox">
83.198 - <Properties>
83.199 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.200 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Modifiers" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.201 - </Property>
83.202 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.203 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.204 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.205 - </Border>
83.206 - </Property>
83.207 - </Properties>
83.208 - </Component>
83.209 - <Component class="javax.swing.JLabel" name="multilineAlignmentLabel">
83.210 - <Properties>
83.211 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.212 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_multilineAlignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.213 - </Property>
83.214 - </Properties>
83.215 - </Component>
83.216 - <Component class="javax.swing.JCheckBox" name="amMethodParamsCheckBox">
83.217 - <Properties>
83.218 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.219 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_MethodParams" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.220 - </Property>
83.221 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.222 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.223 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.224 - </Border>
83.225 - </Property>
83.226 - </Properties>
83.227 - </Component>
83.228 - <Component class="javax.swing.JCheckBox" name="amCallArgsCheckBox">
83.229 - <Properties>
83.230 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.231 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_CallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.232 - </Property>
83.233 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.234 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.235 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.236 - </Border>
83.237 - </Property>
83.238 - </Properties>
83.239 - </Component>
83.240 - <Component class="javax.swing.JCheckBox" name="amAnnotationArgsCheckBox">
83.241 - <Properties>
83.242 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.243 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_AnnotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.244 - </Property>
83.245 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.246 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.247 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.248 - </Border>
83.249 - </Property>
83.250 - </Properties>
83.251 - </Component>
83.252 - <Component class="javax.swing.JCheckBox" name="amImplementsCheckBox1">
83.253 - <Properties>
83.254 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.255 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_an_Implements" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.256 - </Property>
83.257 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.258 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.259 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.260 - </Border>
83.261 - </Property>
83.262 - </Properties>
83.263 - </Component>
83.264 - <Component class="javax.swing.JCheckBox" name="amThrowsCheckBox1">
83.265 - <Properties>
83.266 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.267 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Throws" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.268 - </Property>
83.269 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.270 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.271 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.272 - </Border>
83.273 - </Property>
83.274 - </Properties>
83.275 - </Component>
83.276 - <Component class="javax.swing.JCheckBox" name="amArrayInitCheckBox1">
83.277 - <Properties>
83.278 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.279 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_ArrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.280 - </Property>
83.281 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.282 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.283 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.284 - </Border>
83.285 - </Property>
83.286 - </Properties>
83.287 - </Component>
83.288 - <Component class="javax.swing.JCheckBox" name="amBinaryOpCheckBox1">
83.289 - <Properties>
83.290 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.291 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_BinaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.292 - </Property>
83.293 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.294 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.295 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.296 - </Border>
83.297 - </Property>
83.298 - </Properties>
83.299 - </Component>
83.300 - <Component class="javax.swing.JCheckBox" name="amTernaryOpCheckBox1">
83.301 - <Properties>
83.302 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.303 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_TernaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.304 - </Property>
83.305 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.306 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.307 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.308 - </Border>
83.309 - </Property>
83.310 - </Properties>
83.311 - </Component>
83.312 - <Component class="javax.swing.JCheckBox" name="amAssignCheckBox1">
83.313 - <Properties>
83.314 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.315 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Assign" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.316 - </Property>
83.317 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.318 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.319 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.320 - </Border>
83.321 - </Property>
83.322 - </Properties>
83.323 - </Component>
83.324 - <Component class="javax.swing.JCheckBox" name="amForCheckBox1">
83.325 - <Properties>
83.326 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.327 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_For" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.328 - </Property>
83.329 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.330 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.331 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.332 - </Border>
83.333 - </Property>
83.334 - </Properties>
83.335 - </Component>
83.336 - <Component class="javax.swing.JCheckBox" name="amParenthesizedCheckBox1">
83.337 - <Properties>
83.338 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
83.339 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Paren" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
83.340 - </Property>
83.341 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
83.342 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
83.343 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
83.344 - </Border>
83.345 - </Property>
83.346 - </Properties>
83.347 - </Component>
83.348 - <Component class="javax.swing.JSeparator" name="jSeparator1">
83.349 - </Component>
83.350 - <Component class="javax.swing.JSeparator" name="jSeparator2">
83.351 - </Component>
83.352 - </SubComponents>
83.353 -</Form>
84.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtAlignment.java Mon Aug 31 12:40:19 2015 +0200
84.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
84.3 @@ -1,309 +0,0 @@
84.4 -/*
84.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
84.6 - *
84.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
84.8 - *
84.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
84.10 - * Other names may be trademarks of their respective owners.
84.11 - *
84.12 - * The contents of this file are subject to the terms of either the GNU
84.13 - * General Public License Version 2 only ("GPL") or the Common
84.14 - * Development and Distribution License("CDDL") (collectively, the
84.15 - * "License"). You may not use this file except in compliance with the
84.16 - * License. You can obtain a copy of the License at
84.17 - * http://www.netbeans.org/cddl-gplv2.html
84.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
84.19 - * specific language governing permissions and limitations under the
84.20 - * License. When distributing the software, include this License Header
84.21 - * Notice in each file and include the License file at
84.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
84.23 - * particular file as subject to the "Classpath" exception as provided
84.24 - * by Oracle in the GPL Version 2 section of the License file that
84.25 - * accompanied this code. If applicable, add the following below the
84.26 - * License Header, with the fields enclosed by brackets [] replaced by
84.27 - * your own identifying information:
84.28 - * "Portions Copyrighted [year] [name of copyright owner]"
84.29 - *
84.30 - * Contributor(s):
84.31 - *
84.32 - * The Original Software is NetBeans. The Initial Developer of the Original
84.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
84.34 - * Microsystems, Inc. All Rights Reserved.
84.35 - *
84.36 - * If you wish your version of this file to be governed by only the CDDL
84.37 - * or only the GPL Version 2, indicate your decision by adding
84.38 - * "[Contributor] elects to include this software in this distribution
84.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
84.40 - * single choice of license, a recipient has the option to distribute
84.41 - * your version of this file under either the CDDL, the GPL Version 2 or
84.42 - * to extend the choice of license to its licensees as provided above.
84.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
84.44 - * Version 2 license, then the option applies only if the new code is
84.45 - * made subject to such option by the copyright holder.
84.46 - */
84.47 -
84.48 -package org.netbeans.modules.python.editor.options;
84.49 -
84.50 -import org.netbeans.modules.python.editor.options.CodeStyle.WrapStyle;
84.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
84.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
84.53 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
84.54 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
84.55 -
84.56 -
84.57 -/**
84.58 - *
84.59 - * @author phrebejk
84.60 - */
84.61 -public class FmtAlignment extends javax.swing.JPanel {
84.62 -
84.63 - /** Creates new form FmtAlignment */
84.64 - public FmtAlignment() {
84.65 - initComponents();
84.66 -/*
84.67 - nlElseCheckBox.putClientProperty(OPTION_ID, placeElseOnNewLine);
84.68 - nlWhileCheckBox.putClientProperty(OPTION_ID, placeWhileOnNewLine);
84.69 - nlCatchCheckBox.putClientProperty(OPTION_ID, placeCatchOnNewLine);
84.70 - nlFinallyCheckBox.putClientProperty(OPTION_ID, placeFinallyOnNewLine);
84.71 - nlModifiersCheckBox.putClientProperty(OPTION_ID, placeNewLineAfterModifiers);
84.72 - amMethodParamsCheckBox.putClientProperty(OPTION_ID, alignMultilineMethodParams);
84.73 - amCallArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineCallArgs);
84.74 - amAnnotationArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineAnnotationArgs);
84.75 - amArrayInitCheckBox1.putClientProperty(OPTION_ID, alignMultilineArrayInit);
84.76 - amAssignCheckBox1.putClientProperty(OPTION_ID, alignMultilineAssignment);
84.77 - amBinaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineBinaryOp);
84.78 - amForCheckBox1.putClientProperty(OPTION_ID, alignMultilineFor);
84.79 - amImplementsCheckBox1.putClientProperty(OPTION_ID, alignMultilineImplements);
84.80 - amParenthesizedCheckBox1.putClientProperty(OPTION_ID, alignMultilineParenthesized);
84.81 - amTernaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineTernaryOp);
84.82 - amThrowsCheckBox1.putClientProperty(OPTION_ID, alignMultilineThrows);
84.83 - }
84.84 -
84.85 - public static PreferencesCustomizer.Factory getController() {
84.86 - return new CategorySupport.Factory("alignment", FmtAlignment.class, //NOI18N
84.87 - org.openide.util.NbBundle.getMessage(FmtAlignment.class, "SAMPLE_AlignBraces"), // NOI18N
84.88 - new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
84.89 - new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
84.90 - new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
84.91 - new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
84.92 - new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
84.93 - new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
84.94 - new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
84.95 - new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
84.96 - new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
84.97 - new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
84.98 - new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
84.99 - new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
84.100 - new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
84.101 - new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
84.102 - new String[] { FmtOptions.wrapAnnotationArgs, WrapStyle.WRAP_ALWAYS.name() },
84.103 - new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
84.104 - new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
84.105 - new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
84.106 - new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
84.107 - new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() } );
84.108 - */
84.109 - }
84.110 -
84.111 - /** This method is called from within the constructor to
84.112 - * initialize the form.
84.113 - * WARNING: Do NOT modify this code. The content of this method is
84.114 - * always regenerated by the Form Editor.
84.115 - */
84.116 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
84.117 - private void initComponents() {
84.118 -
84.119 - newLinesLabel = new javax.swing.JLabel();
84.120 - nlElseCheckBox = new javax.swing.JCheckBox();
84.121 - nlWhileCheckBox = new javax.swing.JCheckBox();
84.122 - nlCatchCheckBox = new javax.swing.JCheckBox();
84.123 - nlFinallyCheckBox = new javax.swing.JCheckBox();
84.124 - nlModifiersCheckBox = new javax.swing.JCheckBox();
84.125 - multilineAlignmentLabel = new javax.swing.JLabel();
84.126 - amMethodParamsCheckBox = new javax.swing.JCheckBox();
84.127 - amCallArgsCheckBox = new javax.swing.JCheckBox();
84.128 - amAnnotationArgsCheckBox = new javax.swing.JCheckBox();
84.129 - amImplementsCheckBox1 = new javax.swing.JCheckBox();
84.130 - amThrowsCheckBox1 = new javax.swing.JCheckBox();
84.131 - amArrayInitCheckBox1 = new javax.swing.JCheckBox();
84.132 - amBinaryOpCheckBox1 = new javax.swing.JCheckBox();
84.133 - amTernaryOpCheckBox1 = new javax.swing.JCheckBox();
84.134 - amAssignCheckBox1 = new javax.swing.JCheckBox();
84.135 - amForCheckBox1 = new javax.swing.JCheckBox();
84.136 - amParenthesizedCheckBox1 = new javax.swing.JCheckBox();
84.137 - jSeparator1 = new javax.swing.JSeparator();
84.138 - jSeparator2 = new javax.swing.JSeparator();
84.139 -
84.140 - setName(org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_Alignment")); // NOI18N
84.141 - setOpaque(false);
84.142 -
84.143 - org.openide.awt.Mnemonics.setLocalizedText(newLinesLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_newLines")); // NOI18N
84.144 -
84.145 - org.openide.awt.Mnemonics.setLocalizedText(nlElseCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Else")); // NOI18N
84.146 - nlElseCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.147 -
84.148 - org.openide.awt.Mnemonics.setLocalizedText(nlWhileCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_While")); // NOI18N
84.149 - nlWhileCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.150 -
84.151 - org.openide.awt.Mnemonics.setLocalizedText(nlCatchCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Catch")); // NOI18N
84.152 - nlCatchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.153 -
84.154 - org.openide.awt.Mnemonics.setLocalizedText(nlFinallyCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Finally")); // NOI18N
84.155 - nlFinallyCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.156 -
84.157 - org.openide.awt.Mnemonics.setLocalizedText(nlModifiersCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Modifiers")); // NOI18N
84.158 - nlModifiersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.159 -
84.160 - org.openide.awt.Mnemonics.setLocalizedText(multilineAlignmentLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_multilineAlignment")); // NOI18N
84.161 -
84.162 - org.openide.awt.Mnemonics.setLocalizedText(amMethodParamsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_MethodParams")); // NOI18N
84.163 - amMethodParamsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.164 -
84.165 - org.openide.awt.Mnemonics.setLocalizedText(amCallArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_CallArgs")); // NOI18N
84.166 - amCallArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.167 -
84.168 - org.openide.awt.Mnemonics.setLocalizedText(amAnnotationArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_AnnotationArgs")); // NOI18N
84.169 - amAnnotationArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.170 -
84.171 - org.openide.awt.Mnemonics.setLocalizedText(amImplementsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_an_Implements")); // NOI18N
84.172 - amImplementsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.173 -
84.174 - org.openide.awt.Mnemonics.setLocalizedText(amThrowsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Throws")); // NOI18N
84.175 - amThrowsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.176 -
84.177 - org.openide.awt.Mnemonics.setLocalizedText(amArrayInitCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_ArrayInit")); // NOI18N
84.178 - amArrayInitCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.179 -
84.180 - org.openide.awt.Mnemonics.setLocalizedText(amBinaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_BinaryOp")); // NOI18N
84.181 - amBinaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.182 -
84.183 - org.openide.awt.Mnemonics.setLocalizedText(amTernaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_TernaryOp")); // NOI18N
84.184 - amTernaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.185 -
84.186 - org.openide.awt.Mnemonics.setLocalizedText(amAssignCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Assign")); // NOI18N
84.187 - amAssignCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.188 -
84.189 - org.openide.awt.Mnemonics.setLocalizedText(amForCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_For")); // NOI18N
84.190 - amForCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.191 -
84.192 - org.openide.awt.Mnemonics.setLocalizedText(amParenthesizedCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Paren")); // NOI18N
84.193 - amParenthesizedCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
84.194 -
84.195 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
84.196 - this.setLayout(layout);
84.197 - layout.setHorizontalGroup(
84.198 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.199 - .addGroup(layout.createSequentialGroup()
84.200 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.201 - .addGroup(layout.createSequentialGroup()
84.202 - .addContainerGap()
84.203 - .addComponent(amParenthesizedCheckBox1))
84.204 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
84.205 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
84.206 - .addComponent(newLinesLabel)
84.207 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.208 - .addComponent(jSeparator1))
84.209 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
84.210 - .addComponent(multilineAlignmentLabel)
84.211 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.212 - .addComponent(jSeparator2))
84.213 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
84.214 - .addContainerGap()
84.215 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.216 - .addComponent(amThrowsCheckBox1)
84.217 - .addComponent(amBinaryOpCheckBox1)
84.218 - .addComponent(amAssignCheckBox1)
84.219 - .addComponent(amAnnotationArgsCheckBox)
84.220 - .addComponent(nlElseCheckBox)
84.221 - .addComponent(nlWhileCheckBox)
84.222 - .addComponent(nlCatchCheckBox)
84.223 - .addComponent(amMethodParamsCheckBox))
84.224 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.225 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.226 - .addComponent(amCallArgsCheckBox)
84.227 - .addComponent(nlModifiersCheckBox)
84.228 - .addComponent(nlFinallyCheckBox)
84.229 - .addComponent(amImplementsCheckBox1)
84.230 - .addComponent(amArrayInitCheckBox1)
84.231 - .addComponent(amTernaryOpCheckBox1)
84.232 - .addComponent(amForCheckBox1)))))
84.233 - .addGap(0, 0, 0))
84.234 - );
84.235 - layout.setVerticalGroup(
84.236 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.237 - .addGroup(layout.createSequentialGroup()
84.238 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.239 - .addGroup(layout.createSequentialGroup()
84.240 - .addContainerGap()
84.241 - .addComponent(newLinesLabel))
84.242 - .addGroup(layout.createSequentialGroup()
84.243 - .addGap(17, 17, 17)
84.244 - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
84.245 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.246 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.247 - .addComponent(nlElseCheckBox)
84.248 - .addComponent(nlFinallyCheckBox))
84.249 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.250 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.251 - .addComponent(nlWhileCheckBox)
84.252 - .addComponent(nlModifiersCheckBox))
84.253 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
84.254 - .addGroup(layout.createSequentialGroup()
84.255 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.256 - .addComponent(nlCatchCheckBox)
84.257 - .addGap(18, 18, 18)
84.258 - .addComponent(multilineAlignmentLabel))
84.259 - .addGroup(layout.createSequentialGroup()
84.260 - .addGap(44, 44, 44)
84.261 - .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
84.262 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.263 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.264 - .addComponent(amMethodParamsCheckBox)
84.265 - .addComponent(amCallArgsCheckBox))
84.266 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.267 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.268 - .addComponent(amAnnotationArgsCheckBox)
84.269 - .addComponent(amImplementsCheckBox1))
84.270 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.271 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.272 - .addComponent(amThrowsCheckBox1)
84.273 - .addComponent(amArrayInitCheckBox1))
84.274 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.275 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.276 - .addComponent(amBinaryOpCheckBox1)
84.277 - .addComponent(amTernaryOpCheckBox1))
84.278 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.279 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
84.280 - .addComponent(amAssignCheckBox1)
84.281 - .addComponent(amForCheckBox1))
84.282 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
84.283 - .addComponent(amParenthesizedCheckBox1)
84.284 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
84.285 - );
84.286 - }// </editor-fold>//GEN-END:initComponents
84.287 -
84.288 -
84.289 - // Variables declaration - do not modify//GEN-BEGIN:variables
84.290 - private javax.swing.JCheckBox amAnnotationArgsCheckBox;
84.291 - private javax.swing.JCheckBox amArrayInitCheckBox1;
84.292 - private javax.swing.JCheckBox amAssignCheckBox1;
84.293 - private javax.swing.JCheckBox amBinaryOpCheckBox1;
84.294 - private javax.swing.JCheckBox amCallArgsCheckBox;
84.295 - private javax.swing.JCheckBox amForCheckBox1;
84.296 - private javax.swing.JCheckBox amImplementsCheckBox1;
84.297 - private javax.swing.JCheckBox amMethodParamsCheckBox;
84.298 - private javax.swing.JCheckBox amParenthesizedCheckBox1;
84.299 - private javax.swing.JCheckBox amTernaryOpCheckBox1;
84.300 - private javax.swing.JCheckBox amThrowsCheckBox1;
84.301 - private javax.swing.JSeparator jSeparator1;
84.302 - private javax.swing.JSeparator jSeparator2;
84.303 - private javax.swing.JLabel multilineAlignmentLabel;
84.304 - private javax.swing.JLabel newLinesLabel;
84.305 - private javax.swing.JCheckBox nlCatchCheckBox;
84.306 - private javax.swing.JCheckBox nlElseCheckBox;
84.307 - private javax.swing.JCheckBox nlFinallyCheckBox;
84.308 - private javax.swing.JCheckBox nlModifiersCheckBox;
84.309 - private javax.swing.JCheckBox nlWhileCheckBox;
84.310 - // End of variables declaration//GEN-END:variables
84.311 -
84.312 -}
85.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtBlankLines.form Mon Aug 31 12:40:19 2015 +0200
85.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
85.3 @@ -1,284 +0,0 @@
85.4 -<?xml version="1.0" encoding="UTF-8" ?>
85.5 -
85.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
85.7 - <Properties>
85.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_BlankLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.10 - </Property>
85.11 - <Property name="opaque" type="boolean" value="false"/>
85.12 - </Properties>
85.13 - <AuxValues>
85.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
85.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
85.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
85.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
85.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
85.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
85.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
85.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
85.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
85.23 - </AuxValues>
85.24 -
85.25 - <Layout>
85.26 - <DimensionLayout dim="0">
85.27 - <Group type="103" groupAlignment="0" attributes="0">
85.28 - <Group type="102" attributes="0">
85.29 - <Group type="103" groupAlignment="0" attributes="0">
85.30 - <Component id="bPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.31 - <Component id="aPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.32 - <Component id="bImportsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.33 - <Component id="aImports" alignment="0" min="-2" max="-2" attributes="0"/>
85.34 - <Component id="bClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.35 - <Component id="aClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.36 - <Component id="aClassHeaderLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.37 - <Component id="bFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.38 - <Component id="aFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.39 - <Component id="bMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.40 - <Component id="aMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
85.41 - </Group>
85.42 - <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
85.43 - <Group type="103" groupAlignment="0" attributes="0">
85.44 - <Component id="aMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.45 - <Component id="bMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.46 - <Component id="aFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.47 - <Component id="bFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.48 - <Component id="aClassHeaderField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.49 - <Component id="aClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.50 - <Component id="bClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.51 - <Component id="aImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.52 - <Component id="bImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.53 - <Component id="aPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.54 - <Component id="bPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
85.55 - </Group>
85.56 - </Group>
85.57 - </Group>
85.58 - </DimensionLayout>
85.59 - <DimensionLayout dim="1">
85.60 - <Group type="103" groupAlignment="0" attributes="0">
85.61 - <Group type="102" attributes="0">
85.62 - <Group type="103" groupAlignment="3" attributes="0">
85.63 - <Component id="bPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.64 - <Component id="bPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.65 - </Group>
85.66 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.67 - <Group type="103" groupAlignment="3" attributes="0">
85.68 - <Component id="aPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.69 - <Component id="aPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.70 - </Group>
85.71 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.72 - <Group type="103" groupAlignment="3" attributes="0">
85.73 - <Component id="bImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.74 - <Component id="bImportsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.75 - </Group>
85.76 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.77 - <Group type="103" groupAlignment="3" attributes="0">
85.78 - <Component id="aImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.79 - <Component id="aImports" alignment="3" min="-2" max="-2" attributes="0"/>
85.80 - </Group>
85.81 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.82 - <Group type="103" groupAlignment="3" attributes="0">
85.83 - <Component id="bClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.84 - <Component id="bClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.85 - </Group>
85.86 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.87 - <Group type="103" groupAlignment="3" attributes="0">
85.88 - <Component id="aClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.89 - <Component id="aClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.90 - </Group>
85.91 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.92 - <Group type="103" groupAlignment="3" attributes="0">
85.93 - <Component id="aClassHeaderField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.94 - <Component id="aClassHeaderLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.95 - </Group>
85.96 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.97 - <Group type="103" groupAlignment="3" attributes="0">
85.98 - <Component id="bFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.99 - <Component id="bFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.100 - </Group>
85.101 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.102 - <Group type="103" groupAlignment="3" attributes="0">
85.103 - <Component id="aFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.104 - <Component id="aFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.105 - </Group>
85.106 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.107 - <Group type="103" groupAlignment="3" attributes="0">
85.108 - <Component id="bMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.109 - <Component id="bMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.110 - </Group>
85.111 - <EmptySpace min="4" pref="4" max="4" attributes="0"/>
85.112 - <Group type="103" groupAlignment="3" attributes="0">
85.113 - <Component id="aMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
85.114 - <Component id="aMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
85.115 - </Group>
85.116 - </Group>
85.117 - </Group>
85.118 - </DimensionLayout>
85.119 - </Layout>
85.120 - <SubComponents>
85.121 - <Component class="javax.swing.JLabel" name="bPackageLabel">
85.122 - <Properties>
85.123 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.124 - <ComponentRef name="bPackageField"/>
85.125 - </Property>
85.126 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.127 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforePackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.128 - </Property>
85.129 - </Properties>
85.130 - </Component>
85.131 - <Component class="javax.swing.JTextField" name="bPackageField">
85.132 - <Properties>
85.133 - <Property name="columns" type="int" value="5"/>
85.134 - </Properties>
85.135 - </Component>
85.136 - <Component class="javax.swing.JLabel" name="aPackageLabel">
85.137 - <Properties>
85.138 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.139 - <ComponentRef name="aPackageField"/>
85.140 - </Property>
85.141 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.142 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterPackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.143 - </Property>
85.144 - </Properties>
85.145 - </Component>
85.146 - <Component class="javax.swing.JTextField" name="aPackageField">
85.147 - <Properties>
85.148 - <Property name="columns" type="int" value="5"/>
85.149 - </Properties>
85.150 - </Component>
85.151 - <Component class="javax.swing.JLabel" name="bImportsLabel">
85.152 - <Properties>
85.153 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.154 - <ComponentRef name="bImportsField"/>
85.155 - </Property>
85.156 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.157 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.158 - </Property>
85.159 - </Properties>
85.160 - </Component>
85.161 - <Component class="javax.swing.JTextField" name="bImportsField">
85.162 - <Properties>
85.163 - <Property name="columns" type="int" value="5"/>
85.164 - </Properties>
85.165 - </Component>
85.166 - <Component class="javax.swing.JLabel" name="aImports">
85.167 - <Properties>
85.168 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.169 - <ComponentRef name="aImportsField"/>
85.170 - </Property>
85.171 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.172 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.173 - </Property>
85.174 - </Properties>
85.175 - </Component>
85.176 - <Component class="javax.swing.JTextField" name="aImportsField">
85.177 - <Properties>
85.178 - <Property name="columns" type="int" value="5"/>
85.179 - </Properties>
85.180 - </Component>
85.181 - <Component class="javax.swing.JLabel" name="bClassLabel">
85.182 - <Properties>
85.183 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.184 - <ComponentRef name="bClassField"/>
85.185 - </Property>
85.186 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.187 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.188 - </Property>
85.189 - </Properties>
85.190 - </Component>
85.191 - <Component class="javax.swing.JTextField" name="bClassField">
85.192 - <Properties>
85.193 - <Property name="columns" type="int" value="5"/>
85.194 - </Properties>
85.195 - </Component>
85.196 - <Component class="javax.swing.JLabel" name="aClassLabel">
85.197 - <Properties>
85.198 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.199 - <ComponentRef name="aClassField"/>
85.200 - </Property>
85.201 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.202 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.203 - </Property>
85.204 - </Properties>
85.205 - </Component>
85.206 - <Component class="javax.swing.JTextField" name="aClassField">
85.207 - <Properties>
85.208 - <Property name="columns" type="int" value="5"/>
85.209 - </Properties>
85.210 - </Component>
85.211 - <Component class="javax.swing.JLabel" name="aClassHeaderLabel">
85.212 - <Properties>
85.213 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.214 - <ComponentRef name="aClassHeaderField"/>
85.215 - </Property>
85.216 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.217 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClassHeader" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.218 - </Property>
85.219 - </Properties>
85.220 - </Component>
85.221 - <Component class="javax.swing.JTextField" name="aClassHeaderField">
85.222 - <Properties>
85.223 - <Property name="columns" type="int" value="5"/>
85.224 - </Properties>
85.225 - </Component>
85.226 - <Component class="javax.swing.JLabel" name="bFieldsLabel">
85.227 - <Properties>
85.228 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.229 - <ComponentRef name="bFieldsField"/>
85.230 - </Property>
85.231 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.232 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.233 - </Property>
85.234 - </Properties>
85.235 - </Component>
85.236 - <Component class="javax.swing.JTextField" name="bFieldsField">
85.237 - <Properties>
85.238 - <Property name="columns" type="int" value="5"/>
85.239 - </Properties>
85.240 - </Component>
85.241 - <Component class="javax.swing.JLabel" name="aFieldsLabel">
85.242 - <Properties>
85.243 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.244 - <ComponentRef name="aFieldsField"/>
85.245 - </Property>
85.246 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.247 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.248 - </Property>
85.249 - </Properties>
85.250 - </Component>
85.251 - <Component class="javax.swing.JTextField" name="aFieldsField">
85.252 - <Properties>
85.253 - <Property name="columns" type="int" value="5"/>
85.254 - </Properties>
85.255 - </Component>
85.256 - <Component class="javax.swing.JLabel" name="bMethodsLabel">
85.257 - <Properties>
85.258 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.259 - <ComponentRef name="bMethodsField"/>
85.260 - </Property>
85.261 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.262 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.263 - </Property>
85.264 - </Properties>
85.265 - </Component>
85.266 - <Component class="javax.swing.JTextField" name="bMethodsField">
85.267 - <Properties>
85.268 - <Property name="columns" type="int" value="5"/>
85.269 - </Properties>
85.270 - </Component>
85.271 - <Component class="javax.swing.JLabel" name="aMethodsLabel">
85.272 - <Properties>
85.273 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
85.274 - <ComponentRef name="aMethodsField"/>
85.275 - </Property>
85.276 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85.277 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
85.278 - </Property>
85.279 - </Properties>
85.280 - </Component>
85.281 - <Component class="javax.swing.JTextField" name="aMethodsField">
85.282 - <Properties>
85.283 - <Property name="columns" type="int" value="5"/>
85.284 - </Properties>
85.285 - </Component>
85.286 - </SubComponents>
85.287 -</Form>
86.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtBlankLines.java Mon Aug 31 12:40:19 2015 +0200
86.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
86.3 @@ -1,295 +0,0 @@
86.4 -/*
86.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
86.6 - *
86.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
86.8 - *
86.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
86.10 - * Other names may be trademarks of their respective owners.
86.11 - *
86.12 - * The contents of this file are subject to the terms of either the GNU
86.13 - * General Public License Version 2 only ("GPL") or the Common
86.14 - * Development and Distribution License("CDDL") (collectively, the
86.15 - * "License"). You may not use this file except in compliance with the
86.16 - * License. You can obtain a copy of the License at
86.17 - * http://www.netbeans.org/cddl-gplv2.html
86.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
86.19 - * specific language governing permissions and limitations under the
86.20 - * License. When distributing the software, include this License Header
86.21 - * Notice in each file and include the License file at
86.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
86.23 - * particular file as subject to the "Classpath" exception as provided
86.24 - * by Oracle in the GPL Version 2 section of the License file that
86.25 - * accompanied this code. If applicable, add the following below the
86.26 - * License Header, with the fields enclosed by brackets [] replaced by
86.27 - * your own identifying information:
86.28 - * "Portions Copyrighted [year] [name of copyright owner]"
86.29 - *
86.30 - * Contributor(s):
86.31 - *
86.32 - * The Original Software is NetBeans. The Initial Developer of the Original
86.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
86.34 - * Microsystems, Inc. All Rights Reserved.
86.35 - *
86.36 - * If you wish your version of this file to be governed by only the CDDL
86.37 - * or only the GPL Version 2, indicate your decision by adding
86.38 - * "[Contributor] elects to include this software in this distribution
86.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
86.40 - * single choice of license, a recipient has the option to distribute
86.41 - * your version of this file under either the CDDL, the GPL Version 2 or
86.42 - * to extend the choice of license to its licensees as provided above.
86.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
86.44 - * Version 2 license, then the option applies only if the new code is
86.45 - * made subject to such option by the copyright holder.
86.46 - */
86.47 -
86.48 -package org.netbeans.modules.python.editor.options;
86.49 -
86.50 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
86.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
86.52 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
86.53 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
86.54 -
86.55 -/**
86.56 - *
86.57 - * @author phrebejk
86.58 - */
86.59 -public class FmtBlankLines extends javax.swing.JPanel {
86.60 -
86.61 - /** Creates new form FmtBlankLines */
86.62 - public FmtBlankLines() {
86.63 - initComponents();
86.64 -/*
86.65 - bPackageField.putClientProperty(OPTION_ID, blankLinesBeforePackage );
86.66 - aPackageField.putClientProperty(OPTION_ID, blankLinesAfterPackage);
86.67 - bImportsField.putClientProperty(OPTION_ID, blankLinesBeforeImports);
86.68 - aImportsField.putClientProperty(OPTION_ID, blankLinesAfterImports);
86.69 - bClassField.putClientProperty(OPTION_ID, blankLinesBeforeClass);
86.70 - aClassField.putClientProperty(OPTION_ID, blankLinesAfterClass);
86.71 - aClassHeaderField.putClientProperty(OPTION_ID, blankLinesAfterClassHeader);
86.72 - bFieldsField.putClientProperty(OPTION_ID, blankLinesBeforeFields);
86.73 - aFieldsField.putClientProperty(OPTION_ID, blankLinesAfterFields);
86.74 - bMethodsField.putClientProperty(OPTION_ID, blankLinesBeforeMethods );
86.75 - aMethodsField.putClientProperty(OPTION_ID, blankLinesAfterMethods);
86.76 -
86.77 - bPackageField.addKeyListener(new NumericKeyListener());
86.78 - aPackageField.addKeyListener(new NumericKeyListener());
86.79 - bImportsField.addKeyListener(new NumericKeyListener());
86.80 - aImportsField.addKeyListener(new NumericKeyListener());
86.81 - bClassField.addKeyListener(new NumericKeyListener());
86.82 - aClassField.addKeyListener(new NumericKeyListener());
86.83 - aClassHeaderField.addKeyListener(new NumericKeyListener());
86.84 - bFieldsField.addKeyListener(new NumericKeyListener());
86.85 - aFieldsField.addKeyListener(new NumericKeyListener());
86.86 - bMethodsField.addKeyListener(new NumericKeyListener());
86.87 - aMethodsField.addKeyListener(new NumericKeyListener());
86.88 -
86.89 - }
86.90 -
86.91 - public static PreferencesCustomizer.Factory getController() {
86.92 - return new CategorySupport.Factory("blank-lines", FmtBlankLines.class, //NOI18N
86.93 - org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "SAMPLE_BlankLines")); // NOI18N
86.94 - */
86.95 - }
86.96 -
86.97 - /** This method is called from within the constructor to
86.98 - * initialize the form.
86.99 - * WARNING: Do NOT modify this code. The content of this method is
86.100 - * always regenerated by the Form Editor.
86.101 - */
86.102 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
86.103 - private void initComponents() {
86.104 -
86.105 - bPackageLabel = new javax.swing.JLabel();
86.106 - bPackageField = new javax.swing.JTextField();
86.107 - aPackageLabel = new javax.swing.JLabel();
86.108 - aPackageField = new javax.swing.JTextField();
86.109 - bImportsLabel = new javax.swing.JLabel();
86.110 - bImportsField = new javax.swing.JTextField();
86.111 - aImports = new javax.swing.JLabel();
86.112 - aImportsField = new javax.swing.JTextField();
86.113 - bClassLabel = new javax.swing.JLabel();
86.114 - bClassField = new javax.swing.JTextField();
86.115 - aClassLabel = new javax.swing.JLabel();
86.116 - aClassField = new javax.swing.JTextField();
86.117 - aClassHeaderLabel = new javax.swing.JLabel();
86.118 - aClassHeaderField = new javax.swing.JTextField();
86.119 - bFieldsLabel = new javax.swing.JLabel();
86.120 - bFieldsField = new javax.swing.JTextField();
86.121 - aFieldsLabel = new javax.swing.JLabel();
86.122 - aFieldsField = new javax.swing.JTextField();
86.123 - bMethodsLabel = new javax.swing.JLabel();
86.124 - bMethodsField = new javax.swing.JTextField();
86.125 - aMethodsLabel = new javax.swing.JLabel();
86.126 - aMethodsField = new javax.swing.JTextField();
86.127 -
86.128 - setName(org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_BlankLines")); // NOI18N
86.129 - setOpaque(false);
86.130 -
86.131 - bPackageLabel.setLabelFor(bPackageField);
86.132 - org.openide.awt.Mnemonics.setLocalizedText(bPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforePackage")); // NOI18N
86.133 -
86.134 - bPackageField.setColumns(5);
86.135 -
86.136 - aPackageLabel.setLabelFor(aPackageField);
86.137 - org.openide.awt.Mnemonics.setLocalizedText(aPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterPackage")); // NOI18N
86.138 -
86.139 - aPackageField.setColumns(5);
86.140 -
86.141 - bImportsLabel.setLabelFor(bImportsField);
86.142 - org.openide.awt.Mnemonics.setLocalizedText(bImportsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeImports")); // NOI18N
86.143 -
86.144 - bImportsField.setColumns(5);
86.145 -
86.146 - aImports.setLabelFor(aImportsField);
86.147 - org.openide.awt.Mnemonics.setLocalizedText(aImports, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterImports")); // NOI18N
86.148 -
86.149 - aImportsField.setColumns(5);
86.150 -
86.151 - bClassLabel.setLabelFor(bClassField);
86.152 - org.openide.awt.Mnemonics.setLocalizedText(bClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeClass")); // NOI18N
86.153 -
86.154 - bClassField.setColumns(5);
86.155 -
86.156 - aClassLabel.setLabelFor(aClassField);
86.157 - org.openide.awt.Mnemonics.setLocalizedText(aClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClass")); // NOI18N
86.158 -
86.159 - aClassField.setColumns(5);
86.160 -
86.161 - aClassHeaderLabel.setLabelFor(aClassHeaderField);
86.162 - org.openide.awt.Mnemonics.setLocalizedText(aClassHeaderLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClassHeader")); // NOI18N
86.163 -
86.164 - aClassHeaderField.setColumns(5);
86.165 -
86.166 - bFieldsLabel.setLabelFor(bFieldsField);
86.167 - org.openide.awt.Mnemonics.setLocalizedText(bFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeFields")); // NOI18N
86.168 -
86.169 - bFieldsField.setColumns(5);
86.170 -
86.171 - aFieldsLabel.setLabelFor(aFieldsField);
86.172 - org.openide.awt.Mnemonics.setLocalizedText(aFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterFields")); // NOI18N
86.173 -
86.174 - aFieldsField.setColumns(5);
86.175 -
86.176 - bMethodsLabel.setLabelFor(bMethodsField);
86.177 - org.openide.awt.Mnemonics.setLocalizedText(bMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeMethods")); // NOI18N
86.178 -
86.179 - bMethodsField.setColumns(5);
86.180 -
86.181 - aMethodsLabel.setLabelFor(aMethodsField);
86.182 - org.openide.awt.Mnemonics.setLocalizedText(aMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterMethods")); // NOI18N
86.183 -
86.184 - aMethodsField.setColumns(5);
86.185 -
86.186 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
86.187 - this.setLayout(layout);
86.188 - layout.setHorizontalGroup(
86.189 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
86.190 - .addGroup(layout.createSequentialGroup()
86.191 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
86.192 - .addComponent(bPackageLabel)
86.193 - .addComponent(aPackageLabel)
86.194 - .addComponent(bImportsLabel)
86.195 - .addComponent(aImports)
86.196 - .addComponent(bClassLabel)
86.197 - .addComponent(aClassLabel)
86.198 - .addComponent(aClassHeaderLabel)
86.199 - .addComponent(bFieldsLabel)
86.200 - .addComponent(aFieldsLabel)
86.201 - .addComponent(bMethodsLabel)
86.202 - .addComponent(aMethodsLabel))
86.203 - .addGap(6, 6, 6)
86.204 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
86.205 - .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.206 - .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.207 - .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.208 - .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.209 - .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.210 - .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.211 - .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.212 - .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.213 - .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.214 - .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.215 - .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
86.216 - );
86.217 -
86.218 - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
86.219 -
86.220 - layout.setVerticalGroup(
86.221 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
86.222 - .addGroup(layout.createSequentialGroup()
86.223 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.224 - .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.225 - .addComponent(bPackageLabel))
86.226 - .addGap(4, 4, 4)
86.227 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.228 - .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.229 - .addComponent(aPackageLabel))
86.230 - .addGap(4, 4, 4)
86.231 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.232 - .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.233 - .addComponent(bImportsLabel))
86.234 - .addGap(4, 4, 4)
86.235 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.236 - .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.237 - .addComponent(aImports))
86.238 - .addGap(4, 4, 4)
86.239 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.240 - .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.241 - .addComponent(bClassLabel))
86.242 - .addGap(4, 4, 4)
86.243 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.244 - .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.245 - .addComponent(aClassLabel))
86.246 - .addGap(4, 4, 4)
86.247 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.248 - .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.249 - .addComponent(aClassHeaderLabel))
86.250 - .addGap(4, 4, 4)
86.251 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.252 - .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.253 - .addComponent(bFieldsLabel))
86.254 - .addGap(4, 4, 4)
86.255 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.256 - .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.257 - .addComponent(aFieldsLabel))
86.258 - .addGap(4, 4, 4)
86.259 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.260 - .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.261 - .addComponent(bMethodsLabel))
86.262 - .addGap(4, 4, 4)
86.263 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86.264 - .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
86.265 - .addComponent(aMethodsLabel)))
86.266 - );
86.267 -
86.268 - layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
86.269 -
86.270 - }// </editor-fold>//GEN-END:initComponents
86.271 -
86.272 -
86.273 - // Variables declaration - do not modify//GEN-BEGIN:variables
86.274 - private javax.swing.JTextField aClassField;
86.275 - private javax.swing.JTextField aClassHeaderField;
86.276 - private javax.swing.JLabel aClassHeaderLabel;
86.277 - private javax.swing.JLabel aClassLabel;
86.278 - private javax.swing.JTextField aFieldsField;
86.279 - private javax.swing.JLabel aFieldsLabel;
86.280 - private javax.swing.JLabel aImports;
86.281 - private javax.swing.JTextField aImportsField;
86.282 - private javax.swing.JTextField aMethodsField;
86.283 - private javax.swing.JLabel aMethodsLabel;
86.284 - private javax.swing.JTextField aPackageField;
86.285 - private javax.swing.JLabel aPackageLabel;
86.286 - private javax.swing.JTextField bClassField;
86.287 - private javax.swing.JLabel bClassLabel;
86.288 - private javax.swing.JTextField bFieldsField;
86.289 - private javax.swing.JLabel bFieldsLabel;
86.290 - private javax.swing.JTextField bImportsField;
86.291 - private javax.swing.JLabel bImportsLabel;
86.292 - private javax.swing.JTextField bMethodsField;
86.293 - private javax.swing.JLabel bMethodsLabel;
86.294 - private javax.swing.JTextField bPackageField;
86.295 - private javax.swing.JLabel bPackageLabel;
86.296 - // End of variables declaration//GEN-END:variables
86.297 -
86.298 -}
87.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtImports.form Mon Aug 31 12:40:19 2015 +0200
87.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
87.3 @@ -1,129 +0,0 @@
87.4 -<?xml version="1.0" encoding="UTF-8" ?>
87.5 -
87.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
87.7 - <Properties>
87.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Imports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.10 - </Property>
87.11 - </Properties>
87.12 - <AuxValues>
87.13 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
87.14 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
87.15 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
87.16 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
87.17 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
87.18 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
87.19 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
87.20 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
87.21 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
87.22 - </AuxValues>
87.23 -
87.24 - <Layout>
87.25 - <DimensionLayout dim="0">
87.26 - <Group type="103" groupAlignment="0" attributes="0">
87.27 - <Group type="102" attributes="0">
87.28 - <Group type="103" groupAlignment="0" attributes="0">
87.29 - <Component id="formatImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
87.30 - <Component id="onePerLineCb" alignment="0" min="-2" max="-2" attributes="0"/>
87.31 - <Component id="systemLibsCb" alignment="0" min="-2" max="-2" attributes="0"/>
87.32 - <Component id="sortImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
87.33 - <Component id="sepFromImpCb" alignment="0" min="-2" max="-2" attributes="0"/>
87.34 - <Component id="removeDuplicateCb" alignment="0" min="-2" max="-2" attributes="0"/>
87.35 - <Component id="preferSymbols" alignment="0" min="-2" max="-2" attributes="0"/>
87.36 - <Group type="102" alignment="0" attributes="0">
87.37 - <Component id="cleanupLabel" min="-2" max="-2" attributes="0"/>
87.38 - <EmptySpace max="-2" attributes="0"/>
87.39 - <Component id="cleanupCombo" min="-2" max="-2" attributes="0"/>
87.40 - </Group>
87.41 - </Group>
87.42 - <EmptySpace max="32767" attributes="0"/>
87.43 - </Group>
87.44 - </Group>
87.45 - </DimensionLayout>
87.46 - <DimensionLayout dim="1">
87.47 - <Group type="103" groupAlignment="0" attributes="0">
87.48 - <Group type="102" alignment="0" attributes="0">
87.49 - <Component id="formatImportsCb" min="-2" max="-2" attributes="0"/>
87.50 - <EmptySpace type="separate" max="-2" attributes="0"/>
87.51 - <Component id="onePerLineCb" min="-2" max="-2" attributes="0"/>
87.52 - <EmptySpace max="-2" attributes="0"/>
87.53 - <Component id="systemLibsCb" min="-2" max="-2" attributes="0"/>
87.54 - <EmptySpace max="-2" attributes="0"/>
87.55 - <Component id="sortImportsCb" min="-2" max="-2" attributes="0"/>
87.56 - <EmptySpace max="-2" attributes="0"/>
87.57 - <Component id="sepFromImpCb" min="-2" max="-2" attributes="0"/>
87.58 - <EmptySpace max="-2" attributes="0"/>
87.59 - <Component id="removeDuplicateCb" min="-2" max="-2" attributes="0"/>
87.60 - <EmptySpace max="-2" attributes="0"/>
87.61 - <Component id="preferSymbols" min="-2" max="-2" attributes="0"/>
87.62 - <EmptySpace type="separate" max="-2" attributes="0"/>
87.63 - <Group type="103" groupAlignment="3" attributes="0">
87.64 - <Component id="cleanupLabel" alignment="3" min="-2" max="-2" attributes="0"/>
87.65 - <Component id="cleanupCombo" alignment="3" min="-2" max="-2" attributes="0"/>
87.66 - </Group>
87.67 - <EmptySpace max="32767" attributes="0"/>
87.68 - </Group>
87.69 - </Group>
87.70 - </DimensionLayout>
87.71 - </Layout>
87.72 - <SubComponents>
87.73 - <Component class="javax.swing.JCheckBox" name="formatImportsCb">
87.74 - <Properties>
87.75 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.76 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.formatImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.77 - </Property>
87.78 - </Properties>
87.79 - </Component>
87.80 - <Component class="javax.swing.JCheckBox" name="onePerLineCb">
87.81 - <Properties>
87.82 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.83 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.onePerLineCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.84 - </Property>
87.85 - </Properties>
87.86 - </Component>
87.87 - <Component class="javax.swing.JCheckBox" name="systemLibsCb">
87.88 - <Properties>
87.89 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.90 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.systemLibsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.91 - </Property>
87.92 - </Properties>
87.93 - </Component>
87.94 - <Component class="javax.swing.JCheckBox" name="removeDuplicateCb">
87.95 - <Properties>
87.96 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.97 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.removeDuplicateCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.98 - </Property>
87.99 - </Properties>
87.100 - </Component>
87.101 - <Component class="javax.swing.JLabel" name="cleanupLabel">
87.102 - <Properties>
87.103 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.104 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.cleanupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.105 - </Property>
87.106 - </Properties>
87.107 - </Component>
87.108 - <Component class="javax.swing.JComboBox" name="cleanupCombo">
87.109 - </Component>
87.110 - <Component class="javax.swing.JCheckBox" name="preferSymbols">
87.111 - <Properties>
87.112 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.113 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.preferSymbols.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.114 - </Property>
87.115 - </Properties>
87.116 - </Component>
87.117 - <Component class="javax.swing.JCheckBox" name="sortImportsCb">
87.118 - <Properties>
87.119 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.120 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sortImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.121 - </Property>
87.122 - </Properties>
87.123 - </Component>
87.124 - <Component class="javax.swing.JCheckBox" name="sepFromImpCb">
87.125 - <Properties>
87.126 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
87.127 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sepFromImpCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
87.128 - </Property>
87.129 - </Properties>
87.130 - </Component>
87.131 - </SubComponents>
87.132 -</Form>
88.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtImports.java Mon Aug 31 12:40:19 2015 +0200
88.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
88.3 @@ -1,169 +0,0 @@
88.4 -/*
88.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
88.6 - *
88.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
88.8 - *
88.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
88.10 - * Other names may be trademarks of their respective owners.
88.11 - *
88.12 - * The contents of this file are subject to the terms of either the GNU
88.13 - * General Public License Version 2 only ("GPL") or the Common
88.14 - * Development and Distribution License("CDDL") (collectively, the
88.15 - * "License"). You may not use this file except in compliance with the
88.16 - * License. You can obtain a copy of the License at
88.17 - * http://www.netbeans.org/cddl-gplv2.html
88.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
88.19 - * specific language governing permissions and limitations under the
88.20 - * License. When distributing the software, include this License Header
88.21 - * Notice in each file and include the License file at
88.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
88.23 - * particular file as subject to the "Classpath" exception as provided
88.24 - * by Oracle in the GPL Version 2 section of the License file that
88.25 - * accompanied this code. If applicable, add the following below the
88.26 - * License Header, with the fields enclosed by brackets [] replaced by
88.27 - * your own identifying information:
88.28 - * "Portions Copyrighted [year] [name of copyright owner]"
88.29 - *
88.30 - * Contributor(s):
88.31 - *
88.32 - * The Original Software is NetBeans. The Initial Developer of the Original
88.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
88.34 - * Microsystems, Inc. All Rights Reserved.
88.35 - *
88.36 - * If you wish your version of this file to be governed by only the CDDL
88.37 - * or only the GPL Version 2, indicate your decision by adding
88.38 - * "[Contributor] elects to include this software in this distribution
88.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
88.40 - * single choice of license, a recipient has the option to distribute
88.41 - * your version of this file under either the CDDL, the GPL Version 2 or
88.42 - * to extend the choice of license to its licensees as provided above.
88.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
88.44 - * Version 2 license, then the option applies only if the new code is
88.45 - * made subject to such option by the copyright holder.
88.46 - */
88.47 -
88.48 -package org.netbeans.modules.python.editor.options;
88.49 -
88.50 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
88.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
88.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
88.53 -
88.54 -/**
88.55 - * Options related to imports
88.56 - *
88.57 - * @author Tor Norbye
88.58 - */
88.59 -public class FmtImports extends javax.swing.JPanel {
88.60 -
88.61 - /** Creates new form FmtImports */
88.62 - public FmtImports() {
88.63 - initComponents();
88.64 -
88.65 - formatImportsCb.putClientProperty(OPTION_ID, formatImports);
88.66 - onePerLineCb.putClientProperty(OPTION_ID, oneImportPerLine);
88.67 - removeDuplicateCb.putClientProperty(OPTION_ID, removeDuplicates);
88.68 - systemLibsCb.putClientProperty(OPTION_ID, systemLibsFirst);
88.69 - cleanupCombo.putClientProperty(OPTION_ID, cleanupUnusedImports);
88.70 - preferSymbols.putClientProperty(OPTION_ID, preferSymbolImports);
88.71 - sortImportsCb.putClientProperty(OPTION_ID, sortImports);
88.72 - sepFromImpCb.putClientProperty(OPTION_ID, separateFromImps);
88.73 - }
88.74 -
88.75 - public static PreferencesCustomizer.Factory getController() {
88.76 - return new CategorySupport.Factory("imports", FmtImports.class,
88.77 - org.openide.util.NbBundle.getMessage(FmtImports.class, "SAMPLE_Imports"));
88.78 - }
88.79 -
88.80 - /** This method is called from within the constructor to
88.81 - * initialize the form.
88.82 - * WARNING: Do NOT modify this code. The content of this method is
88.83 - * always regenerated by the Form Editor.
88.84 - */
88.85 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
88.86 - private void initComponents() {
88.87 -
88.88 - formatImportsCb = new javax.swing.JCheckBox();
88.89 - onePerLineCb = new javax.swing.JCheckBox();
88.90 - systemLibsCb = new javax.swing.JCheckBox();
88.91 - removeDuplicateCb = new javax.swing.JCheckBox();
88.92 - cleanupLabel = new javax.swing.JLabel();
88.93 - cleanupCombo = new javax.swing.JComboBox();
88.94 - preferSymbols = new javax.swing.JCheckBox();
88.95 - sortImportsCb = new javax.swing.JCheckBox();
88.96 - sepFromImpCb = new javax.swing.JCheckBox();
88.97 -
88.98 - setName(org.openide.util.NbBundle.getMessage(FmtImports.class, "LBL_Imports")); // NOI18N
88.99 -
88.100 - org.openide.awt.Mnemonics.setLocalizedText(formatImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.formatImportsCb.text")); // NOI18N
88.101 -
88.102 - org.openide.awt.Mnemonics.setLocalizedText(onePerLineCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.onePerLineCb.text")); // NOI18N
88.103 -
88.104 - org.openide.awt.Mnemonics.setLocalizedText(systemLibsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.systemLibsCb.text")); // NOI18N
88.105 -
88.106 - org.openide.awt.Mnemonics.setLocalizedText(removeDuplicateCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.removeDuplicateCb.text")); // NOI18N
88.107 -
88.108 - org.openide.awt.Mnemonics.setLocalizedText(cleanupLabel, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.cleanupLabel.text")); // NOI18N
88.109 -
88.110 - org.openide.awt.Mnemonics.setLocalizedText(preferSymbols, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.preferSymbols.text")); // NOI18N
88.111 -
88.112 - org.openide.awt.Mnemonics.setLocalizedText(sortImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sortImportsCb.text")); // NOI18N
88.113 -
88.114 - org.openide.awt.Mnemonics.setLocalizedText(sepFromImpCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sepFromImpCb.text")); // NOI18N
88.115 -
88.116 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
88.117 - this.setLayout(layout);
88.118 - layout.setHorizontalGroup(
88.119 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
88.120 - .addGroup(layout.createSequentialGroup()
88.121 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
88.122 - .addComponent(formatImportsCb)
88.123 - .addComponent(onePerLineCb)
88.124 - .addComponent(systemLibsCb)
88.125 - .addComponent(sortImportsCb)
88.126 - .addComponent(sepFromImpCb)
88.127 - .addComponent(removeDuplicateCb)
88.128 - .addComponent(preferSymbols)
88.129 - .addGroup(layout.createSequentialGroup()
88.130 - .addComponent(cleanupLabel)
88.131 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
88.132 - .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
88.133 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
88.134 - );
88.135 - layout.setVerticalGroup(
88.136 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
88.137 - .addGroup(layout.createSequentialGroup()
88.138 - .addComponent(formatImportsCb)
88.139 - .addGap(18, 18, 18)
88.140 - .addComponent(onePerLineCb)
88.141 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
88.142 - .addComponent(systemLibsCb)
88.143 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
88.144 - .addComponent(sortImportsCb)
88.145 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
88.146 - .addComponent(sepFromImpCb)
88.147 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
88.148 - .addComponent(removeDuplicateCb)
88.149 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
88.150 - .addComponent(preferSymbols)
88.151 - .addGap(18, 18, 18)
88.152 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
88.153 - .addComponent(cleanupLabel)
88.154 - .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
88.155 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
88.156 - );
88.157 - }// </editor-fold>//GEN-END:initComponents
88.158 -
88.159 -
88.160 - // Variables declaration - do not modify//GEN-BEGIN:variables
88.161 - private javax.swing.JComboBox cleanupCombo;
88.162 - private javax.swing.JLabel cleanupLabel;
88.163 - private javax.swing.JCheckBox formatImportsCb;
88.164 - private javax.swing.JCheckBox onePerLineCb;
88.165 - private javax.swing.JCheckBox preferSymbols;
88.166 - private javax.swing.JCheckBox removeDuplicateCb;
88.167 - private javax.swing.JCheckBox sepFromImpCb;
88.168 - private javax.swing.JCheckBox sortImportsCb;
88.169 - private javax.swing.JCheckBox systemLibsCb;
88.170 - // End of variables declaration//GEN-END:variables
88.171 -
88.172 -}
89.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtOptions.java Mon Aug 31 12:40:19 2015 +0200
89.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
89.3 @@ -1,1035 +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-2007 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 -package org.netbeans.modules.python.editor.options;
89.48 -
89.49 -import java.awt.Component;
89.50 -import java.awt.Container;
89.51 -import java.awt.Rectangle;
89.52 -import java.awt.event.ActionEvent;
89.53 -import java.awt.event.ActionListener;
89.54 -import java.io.BufferedWriter;
89.55 -import java.io.File;
89.56 -import java.io.FileWriter;
89.57 -import java.io.IOException;
89.58 -import java.util.Arrays;
89.59 -import java.util.HashMap;
89.60 -import java.util.HashSet;
89.61 -import java.util.LinkedList;
89.62 -import java.util.List;
89.63 -import java.util.Map;
89.64 -import java.util.Set;
89.65 -import java.util.prefs.AbstractPreferences;
89.66 -import java.util.prefs.BackingStoreException;
89.67 -import java.util.prefs.Preferences;
89.68 -import javax.swing.ComboBoxModel;
89.69 -import javax.swing.DefaultComboBoxModel;
89.70 -import javax.swing.JCheckBox;
89.71 -import javax.swing.JComboBox;
89.72 -import javax.swing.JComponent;
89.73 -import javax.swing.JEditorPane;
89.74 -import javax.swing.JPanel;
89.75 -import javax.swing.JTextField;
89.76 -import javax.swing.event.DocumentEvent;
89.77 -import javax.swing.event.DocumentListener;
89.78 -import javax.swing.text.BadLocationException;
89.79 -import javax.swing.text.Document;
89.80 -import org.netbeans.api.editor.settings.SimpleValueNames;
89.81 -import static org.netbeans.modules.python.editor.options.CodeStyle.*;
89.82 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
89.83 -import org.netbeans.modules.options.editor.spi.PreviewProvider;
89.84 -import org.netbeans.modules.python.api.PythonMIMEResolver;
89.85 -import org.netbeans.modules.python.editor.PythonFormatter;
89.86 -import org.netbeans.modules.python.editor.PythonParserResult;
89.87 -import org.openide.cookies.SaveCookie;
89.88 -import org.openide.filesystems.FileObject;
89.89 -import org.openide.filesystems.FileUtil;
89.90 -import org.openide.loaders.DataObject;
89.91 -import org.openide.loaders.DataObjectNotFoundException;
89.92 -import org.openide.text.CloneableEditorSupport;
89.93 -import org.openide.util.Exceptions;
89.94 -import org.openide.util.HelpCtx;
89.95 -import org.openide.util.NbBundle;
89.96 -
89.97 -/**
89.98 - *
89.99 - * @author phrebejk
89.100 - */
89.101 -public class FmtOptions {
89.102 - public static final String expandTabToSpaces = SimpleValueNames.EXPAND_TABS;
89.103 - public static final String tabSize = SimpleValueNames.TAB_SIZE;
89.104 - public static final String spacesPerTab = SimpleValueNames.SPACES_PER_TAB;
89.105 - public static final String indentSize = SimpleValueNames.INDENT_SHIFT_WIDTH;
89.106 - public static final String continuationIndentSize = "continuationIndentSize"; //NOI18N
89.107 - public static final String labelIndent = "labelIndent"; //NOI18N
89.108 - public static final String absoluteLabelIndent = "absoluteLabelIndent"; //NOI18N
89.109 - public static final String indentTopLevelClassMembers = "indentTopLevelClassMembers"; //NOI18N
89.110 - public static final String indentCasesFromSwitch = "indentCasesFromSwitch"; //NOI18N
89.111 - public static final String rightMargin = SimpleValueNames.TEXT_LIMIT_WIDTH;
89.112 -
89.113 - /*
89.114 - public static final String addLeadingStarInComment = "addLeadingStarInComment"; //NOI18N
89.115 -
89.116 - public static final String preferLongerNames = "preferLongerNames"; //NOI18N
89.117 - public static final String fieldNamePrefix = "fieldNamePrefix"; //NOI18N
89.118 - public static final String fieldNameSuffix = "fieldNameSuffix"; //NOI18N
89.119 - public static final String staticFieldNamePrefix = "staticFieldNamePrefix"; //NOI18N
89.120 - public static final String staticFieldNameSuffix = "staticFieldNameSuffix"; //NOI18N
89.121 - public static final String parameterNamePrefix = "parameterNamePrefix"; //NOI18N
89.122 - public static final String parameterNameSuffix = "parameterNameSuffix"; //NOI18N
89.123 - public static final String localVarNamePrefix = "localVarNamePrefix"; //NOI18N
89.124 - public static final String localVarNameSuffix = "localVarNameSuffix"; //NOI18N
89.125 - public static final String qualifyFieldAccess = "qualifyFieldAccess"; //NOI18N
89.126 - public static final String useIsForBooleanGetters = "useIsForBooleanGetters"; //NOI18N
89.127 - public static final String addOverrideAnnotation = "addOverrideAnnotation"; //NOI18N
89.128 - public static final String makeLocalVarsFinal = "makeLocalVarsFinal"; //NOI18N
89.129 - public static final String makeParametersFinal = "makeParametersFinal"; //NOI18N
89.130 - public static final String classMembersOrder = "classMembersOrder"; //NOI18N
89.131 -
89.132 - public static final String alignMultilineMethodParams = "alignMultilineMethodParams"; //NOI18N
89.133 - public static final String alignMultilineCallArgs = "alignMultilineCallArgs"; //NOI18N
89.134 - public static final String alignMultilineAnnotationArgs = "alignMultilineAnnotationArgs"; //NOI18N
89.135 - public static final String alignMultilineImplements = "alignMultilineImplements"; //NOI18N
89.136 - public static final String alignMultilineThrows = "alignMultilineThrows"; //NOI18N
89.137 - public static final String alignMultilineParenthesized = "alignMultilineParenthesized"; //NOI18N
89.138 - public static final String alignMultilineBinaryOp = "alignMultilineBinaryOp"; //NOI18N
89.139 - public static final String alignMultilineTernaryOp = "alignMultilineTernaryOp"; //NOI18N
89.140 - public static final String alignMultilineAssignment = "alignMultilineAssignment"; //NOI18N
89.141 - public static final String alignMultilineFor = "alignMultilineFor"; //NOI18N
89.142 - public static final String alignMultilineArrayInit = "alignMultilineArrayInit"; //NOI18N
89.143 - public static final String placeElseOnNewLine = "placeElseOnNewLine"; //NOI18N
89.144 - public static final String placeWhileOnNewLine = "placeWhileOnNewLine"; //NOI18N
89.145 - public static final String placeCatchOnNewLine = "placeCatchOnNewLine"; //NOI18N
89.146 - public static final String placeFinallyOnNewLine = "placeFinallyOnNewLine"; //NOI18N
89.147 - public static final String placeNewLineAfterModifiers = "placeNewLineAfterModifiers"; //NOI18N
89.148 -
89.149 - public static final String wrapExtendsImplementsKeyword = "wrapExtendsImplementsKeyword"; //NOI18N
89.150 - public static final String wrapExtendsImplementsList = "wrapExtendsImplementsList"; //NOI18N
89.151 - public static final String wrapMethodParams = "wrapMethodParams"; //NOI18N
89.152 - public static final String wrapThrowsKeyword = "wrapThrowsKeyword"; //NOI18N
89.153 - public static final String wrapThrowsList = "wrapThrowsList"; //NOI18N
89.154 - public static final String wrapMethodCallArgs = "wrapMethodCallArgs"; //NOI18N
89.155 - public static final String wrapAnnotationArgs = "wrapAnnotationArgs"; //NOI18N
89.156 - public static final String wrapChainedMethodCalls = "wrapChainedMethodCalls"; //NOI18N
89.157 - public static final String wrapArrayInit = "wrapArrayInit"; //NOI18N
89.158 - public static final String wrapFor = "wrapFor"; //NOI18N
89.159 - public static final String wrapForStatement = "wrapForStatement"; //NOI18N
89.160 - public static final String wrapIfStatement = "wrapIfStatement"; //NOI18N
89.161 - public static final String wrapWhileStatement = "wrapWhileStatement"; //NOI18N
89.162 - public static final String wrapDoWhileStatement = "wrapDoWhileStatement"; //NOI18N
89.163 - public static final String wrapAssert = "wrapAssert"; //NOI18N
89.164 - public static final String wrapEnumConstants = "wrapEnumConstants"; //NOI18N
89.165 - public static final String wrapAnnotations = "wrapAnnotations"; //NOI18N
89.166 - public static final String wrapBinaryOps = "wrapBinaryOps"; //NOI18N
89.167 - public static final String wrapTernaryOps = "wrapTernaryOps"; //NOI18N
89.168 - public static final String wrapAssignOps = "wrapAssignOps"; //NOI18N
89.169 -
89.170 - public static final String blankLinesBeforePackage = "blankLinesBeforePackage"; //NOI18N
89.171 - public static final String blankLinesAfterPackage = "blankLinesAfterPackage"; //NOI18N
89.172 - public static final String blankLinesBeforeImports = "blankLinesBeforeImports"; //NOI18N
89.173 - public static final String blankLinesAfterImports = "blankLinesAfterImports"; //NOI18N
89.174 - public static final String blankLinesBeforeClass = "blankLinesBeforeClass"; //NOI18N
89.175 - public static final String blankLinesAfterClass = "blankLinesAfterClass"; //NOI18N
89.176 - public static final String blankLinesAfterClassHeader = "blankLinesAfterClassHeader"; //NOI18N
89.177 - public static final String blankLinesBeforeFields = "blankLinesBeforeFields"; //NOI18N
89.178 - public static final String blankLinesAfterFields = "blankLinesAfterFields"; //NOI18N
89.179 - public static final String blankLinesBeforeMethods = "blankLinesBeforeMethods"; //NOI18N
89.180 - public static final String blankLinesAfterMethods = "blankLinesAfterMethods"; //NOI18N
89.181 -
89.182 - public static final String spaceBeforeWhile = "spaceBeforeWhile"; //NOI18N
89.183 - public static final String spaceBeforeElse = "spaceBeforeElse"; //NOI18N
89.184 - public static final String spaceBeforeCatch = "spaceBeforeCatch"; //NOI18N
89.185 - public static final String spaceBeforeFinally = "spaceBeforeFinally"; //NOI18N
89.186 - public static final String spaceBeforeMethodDeclParen = "spaceBeforeMethodDeclParen"; //NOI18N
89.187 - public static final String spaceBeforeMethodCallParen = "spaceBeforeMethodCallParen"; //NOI18N
89.188 - public static final String spaceBeforeIfParen = "spaceBeforeIfParen"; //NOI18N
89.189 - public static final String spaceBeforeForParen = "spaceBeforeForParen"; //NOI18N
89.190 - public static final String spaceBeforeWhileParen = "spaceBeforeWhileParen"; //NOI18N
89.191 - public static final String spaceBeforeCatchParen = "spaceBeforeCatchParen"; //NOI18N
89.192 - public static final String spaceBeforeSwitchParen = "spaceBeforeSwitchParen"; //NOI18N
89.193 - public static final String spaceBeforeSynchronizedParen = "spaceBeforeSynchronizedParen"; //NOI18N
89.194 - public static final String spaceBeforeAnnotationParen = "spaceBeforeAnnotationParen"; //NOI18N
89.195 - public static final String spaceAroundUnaryOps = "spaceAroundUnaryOps"; //NOI18N
89.196 - public static final String spaceAroundBinaryOps = "spaceAroundBinaryOps"; //NOI18N
89.197 - public static final String spaceAroundTernaryOps = "spaceAroundTernaryOps"; //NOI18N
89.198 - public static final String spaceAroundAssignOps = "spaceAroundAssignOps"; //NOI18N
89.199 - public static final String spaceBeforeClassDeclLeftBrace = "spaceBeforeClassDeclLeftBrace"; //NOI18N
89.200 - public static final String spaceBeforeMethodDeclLeftBrace = "spaceBeforeMethodDeclLeftBrace"; //NOI18N
89.201 - public static final String spaceBeforeIfLeftBrace = "spaceBeforeIfLeftBrace"; //NOI18N
89.202 - public static final String spaceBeforeElseLeftBrace = "spaceBeforeElseLeftBrace"; //NOI18N
89.203 - public static final String spaceBeforeWhileLeftBrace = "spaceBeforeWhileLeftBrace"; //NOI18N
89.204 - public static final String spaceBeforeForLeftBrace = "spaceBeforeForLeftBrace"; //NOI18N
89.205 - public static final String spaceBeforeDoLeftBrace = "spaceBeforeDoLeftBrace"; //NOI18N
89.206 - public static final String spaceBeforeSwitchLeftBrace = "spaceBeforeSwitchLeftBrace"; //NOI18N
89.207 - public static final String spaceBeforeTryLeftBrace = "spaceBeforeTryLeftBrace"; //NOI18N
89.208 - public static final String spaceBeforeCatchLeftBrace = "spaceBeforeCatchLeftBrace"; //NOI18N
89.209 - public static final String spaceBeforeFinallyLeftBrace = "spaceBeforeFinallyLeftBrace"; //NOI18N
89.210 - public static final String spaceBeforeSynchronizedLeftBrace = "spaceBeforeSynchronizedLeftBrace"; //NOI18N
89.211 - public static final String spaceBeforeStaticInitLeftBrace = "spaceBeforeStaticInitLeftBrace"; //NOI18N
89.212 - public static final String spaceBeforeArrayInitLeftBrace = "spaceBeforeArrayInitLeftBrace"; //NOI18N
89.213 - public static final String spaceWithinParens = "spaceWithinParens"; //NOI18N
89.214 - public static final String spaceWithinMethodDeclParens = "spaceWithinMethodDeclParens"; //NOI18N
89.215 - public static final String spaceWithinMethodCallParens = "spaceWithinMethodCallParens"; //NOI18N
89.216 - public static final String spaceWithinIfParens = "spaceWithinIfParens"; //NOI18N
89.217 - public static final String spaceWithinForParens = "spaceWithinForParens"; //NOI18N
89.218 - public static final String spaceWithinWhileParens = "spaceWithinWhileParens"; //NOI18N
89.219 - public static final String spaceWithinSwitchParens = "spaceWithinSwitchParens"; //NOI18N
89.220 - public static final String spaceWithinCatchParens = "spaceWithinCatchParens"; //NOI18N
89.221 - public static final String spaceWithinSynchronizedParens = "spaceWithinSynchronizedParens"; //NOI18N
89.222 - public static final String spaceWithinTypeCastParens = "spaceWithinTypeCastParens"; //NOI18N
89.223 - public static final String spaceWithinAnnotationParens = "spaceWithinAnnotationParens"; //NOI18N
89.224 - public static final String spaceWithinBraces = "spaceWithinBraces"; //NOI18N
89.225 - public static final String spaceWithinArrayInitBrackets = "spaceWithinArrayInitBrackets"; //NOI18N
89.226 - public static final String spaceBeforeComma = "spaceBeforeComma"; //NOI18N
89.227 - public static final String spaceAfterComma = "spaceAfterComma"; //NOI18N
89.228 - public static final String spaceBeforeSemi = "spaceBeforeSemi"; //NOI18N
89.229 - public static final String spaceAfterSemi = "spaceAfterSemi"; //NOI18N
89.230 - public static final String spaceBeforeColon = "spaceBeforeColon"; //NOI18N
89.231 - public static final String spaceAfterColon = "spaceAfterColon"; //NOI18N
89.232 - public static final String spaceAfterTypeCast = "spaceAfterTypeCast"; //NOI18N
89.233 - */
89.234 -
89.235 - // Spaces
89.236 - public static final String addSpaceAroundOperators = "spaceAroundOperators"; //NOI18N
89.237 - public static final String removeSpaceInParens = "spaceInsideParens"; //NOI18N
89.238 - public static final String addSpaceAfterComma = "spaceAfterComma"; //NOI18N
89.239 - public static final String removeSpaceBeforeSep = "spaceBeforeSeparator"; //NOI18N
89.240 - public static final String removeSpaceInParamAssign = "spaceInKeywordAssign"; //NOI18N
89.241 - public static final String collapseSpaces = "collapseSpaces"; //NOI18N
89.242 - // Imports
89.243 - public static final String formatImports = "formatImports"; //NOI18N
89.244 - public static final String oneImportPerLine = "oneImportPerLine"; //NOI18N
89.245 - public static final String removeDuplicates = "removeDuplicates"; //NOI18N
89.246 - public static final String systemLibsFirst = "systemLibsFirst"; //NOI18N
89.247 - public static final String cleanupUnusedImports = "cleanupUnusedImports"; //NOI18N
89.248 - public static final String preferSymbolImports = "preferSymbolImports"; //NOI18N
89.249 - public static final String sortImports = "sortImports"; //NOI18N
89.250 - public static final String separateFromImps = "separateFromImps"; //NOI18N
89.251 - public static CodeStyleProducer codeStyleProducer;
89.252 - static final String CODE_STYLE_PROFILE = "CodeStyle"; // NOI18N
89.253 - static final String DEFAULT_PROFILE = "default"; // NOI18N
89.254 - static final String PROJECT_PROFILE = "project"; // NOI18N
89.255 - static final String usedProfile = "usedProfile"; // NOI18N
89.256 -
89.257 - private FmtOptions() {
89.258 - }
89.259 -
89.260 - public static int getDefaultAsInt(String key) {
89.261 - return Integer.parseInt(defaults.get(key));
89.262 - }
89.263 -
89.264 - public static boolean getDefaultAsBoolean(String key) {
89.265 - return Boolean.parseBoolean(defaults.get(key));
89.266 - }
89.267 -
89.268 - public static String getDefaultAsString(String key) {
89.269 - return defaults.get(key);
89.270 - }
89.271 -
89.272 - public static boolean isInteger(String optionID) {
89.273 - String value = defaults.get(optionID);
89.274 -
89.275 - try {
89.276 - Integer.parseInt(value);
89.277 - return true;
89.278 - } catch (NumberFormatException numberFormatException) {
89.279 - return false;
89.280 - }
89.281 - }
89.282 - // Private section ---------------------------------------------------------
89.283 - private static final String TRUE = "true"; // NOI18N
89.284 - private static final String FALSE = "false"; // NOI18N
89.285 - private static final String WRAP_ALWAYS = WrapStyle.WRAP_ALWAYS.name();
89.286 - //private static final String WRAP_IF_LONG = WrapStyle.WRAP_IF_LONG.name();
89.287 - private static final String WRAP_NEVER = WrapStyle.WRAP_NEVER.name();
89.288 -
89.289 - //private static final String CLEANUP_COMMENT = ImportCleanupStyle.COMMENT_OUT.name();
89.290 - private static final String IMP_LEAVE_ALONE = ImportCleanupStyle.LEAVE_ALONE.name();
89.291 - private static Map<String, String> defaults;
89.292 -
89.293 -
89.294 - static {
89.295 - createDefaults();
89.296 - }
89.297 -
89.298 - private static void createDefaults() {
89.299 - String defaultValues[][] = {
89.300 - {expandTabToSpaces, TRUE}, //NOI18N
89.301 - {tabSize, "4"}, //NOI18N
89.302 - {spacesPerTab, "4"}, //NOI18N
89.303 - {indentSize, "4"}, //NOI18N
89.304 - {continuationIndentSize, "8"}, //NOI18N
89.305 - {labelIndent, "0"}, //NOI18N
89.306 - {absoluteLabelIndent, FALSE}, //NOI18N
89.307 - {indentTopLevelClassMembers, TRUE}, //NOI18N
89.308 - {indentCasesFromSwitch, TRUE}, //NOI18N
89.309 - {rightMargin, "80"}, //NOI18N
89.310 -
89.311 - /*
89.312 - { addLeadingStarInComment, TRUE}, //NOI18N
89.313 -
89.314 - { preferLongerNames, TRUE}, //NOI18N
89.315 - { fieldNamePrefix, ""}, //NOI18N // XXX null
89.316 - { fieldNameSuffix, ""}, //NOI18N // XXX null
89.317 - { staticFieldNamePrefix, ""}, //NOI18N // XXX null
89.318 - { staticFieldNameSuffix, ""}, //NOI18N // XXX null
89.319 - { parameterNamePrefix, ""}, //NOI18N // XXX null
89.320 - { parameterNameSuffix, ""}, //NOI18N // XXX null
89.321 - { localVarNamePrefix, ""}, //NOI18N // XXX null
89.322 - { localVarNameSuffix, ""}, //NOI18N // XXX null
89.323 - { qualifyFieldAccess, FALSE}, //NOI18N // XXX
89.324 - { useIsForBooleanGetters, TRUE}, //NOI18N
89.325 - { addOverrideAnnotation, TRUE}, //NOI18N
89.326 - { makeLocalVarsFinal, FALSE}, //NOI18N
89.327 - { makeParametersFinal, FALSE}, //NOI18N
89.328 - { classMembersOrder, ""}, //NOI18N // XXX
89.329 -
89.330 - { alignMultilineMethodParams, FALSE}, //NOI18N
89.331 - { alignMultilineCallArgs, FALSE}, //NOI18N
89.332 - { alignMultilineAnnotationArgs, FALSE}, //NOI18N
89.333 - { alignMultilineImplements, FALSE}, //NOI18N
89.334 - { alignMultilineThrows, FALSE}, //NOI18N
89.335 - { alignMultilineParenthesized, FALSE}, //NOI18N
89.336 - { alignMultilineBinaryOp, FALSE}, //NOI18N
89.337 - { alignMultilineTernaryOp, FALSE}, //NOI18N
89.338 - { alignMultilineAssignment, FALSE}, //NOI18N
89.339 - { alignMultilineFor, FALSE}, //NOI18N
89.340 - { alignMultilineArrayInit, FALSE}, //NOI18N
89.341 - { placeElseOnNewLine, FALSE}, //NOI18N
89.342 - { placeWhileOnNewLine, FALSE}, //NOI18N
89.343 - { placeCatchOnNewLine, FALSE}, //NOI18N
89.344 - { placeFinallyOnNewLine, FALSE}, //NOI18N
89.345 - { placeNewLineAfterModifiers, FALSE}, //NOI18N
89.346 -
89.347 - { wrapExtendsImplementsKeyword, WRAP_NEVER}, //NOI18N
89.348 - { wrapExtendsImplementsList, WRAP_NEVER}, //NOI18N
89.349 - { wrapMethodParams, WRAP_NEVER}, //NOI18N
89.350 - { wrapThrowsKeyword, WRAP_NEVER}, //NOI18N
89.351 - { wrapThrowsList, WRAP_NEVER}, //NOI18N
89.352 - { wrapMethodCallArgs, WRAP_NEVER}, //NOI18N
89.353 - { wrapAnnotationArgs, WRAP_NEVER}, //NOI18N
89.354 - { wrapChainedMethodCalls, WRAP_NEVER}, //NOI18N
89.355 - { wrapArrayInit, WRAP_NEVER}, //NOI18N
89.356 - { wrapFor, WRAP_NEVER}, //NOI18N
89.357 - { wrapForStatement, WRAP_ALWAYS}, //NOI18N
89.358 - { wrapIfStatement, WRAP_ALWAYS}, //NOI18N
89.359 - { wrapWhileStatement, WRAP_ALWAYS}, //NOI18N
89.360 - { wrapDoWhileStatement, WRAP_ALWAYS}, //NOI18N
89.361 - { wrapAssert, WRAP_NEVER}, //NOI18N
89.362 - { wrapEnumConstants, WRAP_NEVER}, //NOI18N
89.363 - { wrapAnnotations, WRAP_ALWAYS}, //NOI18N
89.364 - { wrapBinaryOps, WRAP_NEVER}, //NOI18N
89.365 - { wrapTernaryOps, WRAP_NEVER}, //NOI18N
89.366 - { wrapAssignOps, WRAP_NEVER}, //NOI18N
89.367 -
89.368 - { blankLinesBeforePackage, "0"}, //NOI18N
89.369 - { blankLinesAfterPackage, "1"}, //NOI18N
89.370 - { blankLinesBeforeImports, "1"}, //NOI18N
89.371 - { blankLinesAfterImports, "1"}, //NOI18N
89.372 - { blankLinesBeforeClass, "1"}, //NOI18N
89.373 - { blankLinesAfterClass, "0"}, //NOI18N
89.374 - { blankLinesAfterClassHeader, "1"}, //NOI18N
89.375 - { blankLinesBeforeFields, "0"}, //NOI18N
89.376 - { blankLinesAfterFields, "0"}, //NOI18N
89.377 - { blankLinesBeforeMethods, "1"}, //NOI18N
89.378 - { blankLinesAfterMethods, "0"}, //NOI18N
89.379 -
89.380 - { spaceBeforeWhile, TRUE}, //NOI18N // XXX
89.381 - { spaceBeforeElse, TRUE}, //NOI18N // XXX
89.382 - { spaceBeforeCatch, TRUE}, //NOI18N // XXX
89.383 - { spaceBeforeFinally, TRUE}, //NOI18N // XXX
89.384 - { spaceBeforeMethodDeclParen, FALSE}, //NOI18N
89.385 - { spaceBeforeMethodCallParen, FALSE}, //NOI18N
89.386 - { spaceBeforeIfParen, TRUE}, //NOI18N
89.387 - { spaceBeforeForParen, TRUE}, //NOI18N
89.388 - { spaceBeforeWhileParen, TRUE}, //NOI18N
89.389 - { spaceBeforeCatchParen, TRUE}, //NOI18N
89.390 - { spaceBeforeSwitchParen, TRUE}, //NOI18N
89.391 - { spaceBeforeSynchronizedParen, TRUE}, //NOI18N
89.392 - { spaceBeforeAnnotationParen, FALSE}, //NOI18N
89.393 - { spaceAroundUnaryOps, FALSE}, //NOI18N
89.394 - { spaceAroundBinaryOps, TRUE}, //NOI18N
89.395 - { spaceAroundTernaryOps, TRUE}, //NOI18N
89.396 - { spaceAroundAssignOps, TRUE}, //NOI18N
89.397 - { spaceBeforeClassDeclLeftBrace, TRUE}, //NOI18N
89.398 - { spaceBeforeMethodDeclLeftBrace, TRUE}, //NOI18N
89.399 - { spaceBeforeIfLeftBrace, TRUE}, //NOI18N
89.400 - { spaceBeforeElseLeftBrace, TRUE}, //NOI18N
89.401 - { spaceBeforeWhileLeftBrace, TRUE}, //NOI18N
89.402 - { spaceBeforeForLeftBrace, TRUE}, //NOI18N
89.403 - { spaceBeforeDoLeftBrace, TRUE}, //NOI18N
89.404 - { spaceBeforeSwitchLeftBrace, TRUE}, //NOI18N
89.405 - { spaceBeforeTryLeftBrace, TRUE}, //NOI18N
89.406 - { spaceBeforeCatchLeftBrace, TRUE}, //NOI18N
89.407 - { spaceBeforeFinallyLeftBrace, TRUE}, //NOI18N
89.408 - { spaceBeforeSynchronizedLeftBrace, TRUE}, //NOI18N
89.409 - { spaceBeforeStaticInitLeftBrace, TRUE}, //NOI18N
89.410 - { spaceBeforeArrayInitLeftBrace, FALSE}, //NOI18N
89.411 - { spaceWithinParens, FALSE}, //NOI18N
89.412 - { spaceWithinMethodDeclParens, FALSE}, //NOI18N
89.413 - { spaceWithinMethodCallParens, FALSE}, //NOI18N
89.414 - { spaceWithinIfParens, FALSE}, //NOI18N
89.415 - { spaceWithinForParens, FALSE}, //NOI18N
89.416 - { spaceWithinWhileParens, FALSE}, //NOI18N
89.417 - { spaceWithinSwitchParens, FALSE}, //NOI18N
89.418 - { spaceWithinCatchParens, FALSE}, //NOI18N
89.419 - { spaceWithinSynchronizedParens, FALSE}, //NOI18N
89.420 - { spaceWithinTypeCastParens, FALSE}, //NOI18N
89.421 - { spaceWithinAnnotationParens, FALSE}, //NOI18N
89.422 - { spaceWithinBraces, FALSE}, //NOI18N
89.423 - { spaceWithinArrayInitBrackets, FALSE}, //NOI18N
89.424 - { spaceBeforeComma, FALSE}, //NOI18N
89.425 - { spaceAfterComma, TRUE}, //NOI18N
89.426 - { spaceBeforeSemi, FALSE}, //NOI18N
89.427 - { spaceAfterSemi, TRUE}, //NOI18N
89.428 - { spaceBeforeColon, TRUE}, //NOI18N
89.429 - { spaceAfterColon, TRUE}, //NOI18N
89.430 - { spaceAfterTypeCast, TRUE}, //NOI18N
89.431 - */
89.432 - // Spaces
89.433 - {addSpaceAroundOperators, TRUE},
89.434 - {removeSpaceInParens, TRUE},
89.435 - {addSpaceAfterComma, TRUE},
89.436 - {removeSpaceBeforeSep, TRUE},
89.437 - {removeSpaceInParamAssign, TRUE},
89.438 - {collapseSpaces, TRUE},
89.439 - // Imports
89.440 - {formatImports, TRUE},
89.441 - {oneImportPerLine, TRUE},
89.442 - {removeDuplicates, TRUE},
89.443 - {systemLibsFirst, TRUE},
89.444 - {preferSymbolImports, TRUE},
89.445 - {sortImports, TRUE},
89.446 - {cleanupUnusedImports, IMP_LEAVE_ALONE},
89.447 - {separateFromImps, FALSE},};
89.448 -
89.449 - defaults = new HashMap<>();
89.450 -
89.451 - for (java.lang.String[] strings : defaultValues) {
89.452 - defaults.put(strings[0], strings[1]);
89.453 - }
89.454 -
89.455 - }
89.456 -
89.457 - // Support section ---------------------------------------------------------
89.458 - public static class CategorySupport implements ActionListener, DocumentListener, PreviewProvider, PreferencesCustomizer {
89.459 - public static final String OPTION_ID = "org.netbeans.modules.python.editor.options.FormatingOptions.ID";
89.460 - private static final int LOAD = 0;
89.461 - private static final int STORE = 1;
89.462 - private static final int ADD_LISTENERS = 2;
89.463 - private static final ComboItem wrap[] = new ComboItem[]{
89.464 - new ComboItem(WrapStyle.WRAP_ALWAYS.name(), "LBL_wrp_WRAP_ALWAYS"), // NOI18N
89.465 - new ComboItem(WrapStyle.WRAP_IF_LONG.name(), "LBL_wrp_WRAP_IF_LONG"), // NOI18N
89.466 - new ComboItem(WrapStyle.WRAP_NEVER.name(), "LBL_wrp_WRAP_NEVER") // NOI18N
89.467 - };
89.468 - private static final ComboItem cleanupImports[] = new ComboItem[]{
89.469 - new ComboItem(ImportCleanupStyle.LEAVE_ALONE.name(), "LBL_imp_LEAVE_ALONE"), // NOI18N
89.470 - new ComboItem(ImportCleanupStyle.COMMENT_OUT.name(), "LBL_imp_COMMENT_OUT"), // NOI18N
89.471 - new ComboItem(ImportCleanupStyle.DELETE.name(), "LBL_imp_DELETE") // NOI18N
89.472 - };
89.473 - private final String previewText;
89.474 - private final String id;
89.475 - protected final JPanel panel;
89.476 - private final List<JComponent> components = new LinkedList<>();
89.477 - private JEditorPane previewPane;
89.478 - private final Preferences preferences;
89.479 - private final Preferences previewPrefs;
89.480 -
89.481 - protected CategorySupport(Preferences preferences, String id, JPanel panel, String previewText, String[]... forcedOptions) {
89.482 - this.preferences = preferences;
89.483 - this.id = id;
89.484 - this.panel = panel;
89.485 - this.previewText = previewText != null ? previewText : NbBundle.getMessage(FmtOptions.class, "SAMPLE_Default"); //NOI18N
89.486 -
89.487 - // Scan the panel for its components
89.488 - scan(panel, components);
89.489 -
89.490 - // Initialize the preview preferences
89.491 - Preferences forcedPrefs = new PreviewPreferences();
89.492 - for (String[] option : forcedOptions) {
89.493 - forcedPrefs.put(option[0], option[1]);
89.494 - }
89.495 - this.previewPrefs = new ProxyPreferences(preferences, forcedPrefs);
89.496 -
89.497 - // Load and hook up all the components
89.498 - loadFrom(preferences);
89.499 - addListeners();
89.500 - }
89.501 -
89.502 - protected void addListeners() {
89.503 - scan(ADD_LISTENERS, null);
89.504 - }
89.505 -
89.506 - protected void loadFrom(Preferences preferences) {
89.507 -// loaded = true;
89.508 - scan(LOAD, preferences);
89.509 -// loaded = false;
89.510 - }
89.511 -//
89.512 -// public void applyChanges() {
89.513 -// storeTo(preferences);
89.514 -// }
89.515 -//
89.516 -
89.517 - protected void storeTo(Preferences p) {
89.518 - scan(STORE, p);
89.519 - }
89.520 -
89.521 - protected void notifyChanged() {
89.522 -// if (loaded)
89.523 -// return;
89.524 - storeTo(preferences);
89.525 - refreshPreview();
89.526 - }
89.527 -
89.528 - // ActionListener implementation ---------------------------------------
89.529 - @Override
89.530 - public void actionPerformed(ActionEvent e) {
89.531 - notifyChanged();
89.532 - }
89.533 -
89.534 - // DocumentListener implementation -------------------------------------
89.535 - @Override
89.536 - public void insertUpdate(DocumentEvent e) {
89.537 - notifyChanged();
89.538 - }
89.539 -
89.540 - @Override
89.541 - public void removeUpdate(DocumentEvent e) {
89.542 - notifyChanged();
89.543 - }
89.544 -
89.545 - @Override
89.546 - public void changedUpdate(DocumentEvent e) {
89.547 - notifyChanged();
89.548 - }
89.549 -
89.550 - // PreviewProvider methods -----------------------------------------------------
89.551 - @Override
89.552 - public JComponent getPreviewComponent() {
89.553 - if (previewPane == null) {
89.554 - previewPane = new JEditorPane();
89.555 - previewPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtOptions.class, "AN_Preview")); //NOI18N
89.556 - previewPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtOptions.class, "AD_Preview")); //NOI18N
89.557 - previewPane.putClientProperty("HighlightsLayerIncludes", "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.SyntaxHighlighting$"); //NOI18N
89.558 - previewPane.setEditorKit(CloneableEditorSupport.getEditorKit(PythonMIMEResolver.PYTHON_MIME_TYPE));
89.559 - previewPane.setEditable(false);
89.560 - }
89.561 - return previewPane;
89.562 - }
89.563 -
89.564 - @Override
89.565 - public void refreshPreview() {
89.566 - JEditorPane jep = (JEditorPane)getPreviewComponent();
89.567 - try {
89.568 - int rm = previewPrefs.getInt(rightMargin, getDefaultAsInt(rightMargin));
89.569 - jep.putClientProperty("TextLimitLine", rm); //NOI18N
89.570 - } catch (NumberFormatException e) {
89.571 - // Ignore it
89.572 - }
89.573 - try {
89.574 - Class.forName(CodeStyle.class.getName(), true, CodeStyle.class.getClassLoader());
89.575 - } catch (ClassNotFoundException cnfe) {
89.576 - // ignore
89.577 - }
89.578 -
89.579 - CodeStyle codeStyle = codeStyleProducer.create(previewPrefs);
89.580 - jep.setIgnoreRepaint(true);
89.581 -
89.582 -// if (jep.getDocument() instanceof BaseDocument) {
89.583 -// BaseDocument document = (BaseDocument) jep.getDocument();
89.584 -// final org.netbeans.editor.Formatter f = document.getFormatter();
89.585 -// try {
89.586 -// f.reformatLock();
89.587 -// try {
89.588 -// int reformattedLen = f.reformat(document, 0, document.getLength());
89.589 -// } catch (BadLocationException ex) {
89.590 -// Exceptions.printStackTrace(ex);
89.591 -// }
89.592 -// } finally {
89.593 -// f.reformatUnlock();
89.594 -// }
89.595 -// }
89.596 -
89.597 - // Hacky code to do preview: We want to preview blank text without
89.598 - // a data object... this doesn't work very well so requires some hacks
89.599 - // to create a temp file, format it, then save it and delete it
89.600 - // (to avoid save confirmation dialogs on the modified file etc)
89.601 - PythonFormatter formatter = new PythonFormatter(codeStyle);
89.602 - PythonParserResult info = null;
89.603 - File tmp = null;
89.604 - FileObject tmpFo = null;
89.605 - if (formatter.needsParserResult()) {
89.606 - try {
89.607 - tmp = File.createTempFile("preview", ".py"); // NOI18N
89.608 - BufferedWriter writer = new BufferedWriter(new FileWriter(tmp));
89.609 - writer.write(previewText);
89.610 - writer.close();
89.611 - final FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(tmp));
89.612 - tmpFo = fo;
89.613 - // TODO - I need to get the classpath involved here such that it can
89.614 - // find used/unused libraries
89.615 -// if (!SourceUtils.isScanInProgress()) {
89.616 -// // I'm using custom GSF code here because I want to set up an explicit
89.617 -// // source path for the fake file object which includes the Python
89.618 -// // libraries (since we need them for the isSystemModule lookup
89.619 -// //SourceModel model = SourceModelFactory.getInstance().getModel(fo);
89.620 -// //if (model != null && !model.isScanInProgress()) {
89.621 -// List<FileObject> roots = new ArrayList<FileObject>(new PythonLanguage().getCoreLibraries());
89.622 -//
89.623 -// final PythonPlatformManager manager = PythonPlatformManager.getInstance();
89.624 -// final String platformName = manager.getDefaultPlatform();
89.625 -// PythonPlatform activePlatform = manager.getPlatform(platformName);
89.626 -// if (activePlatform != null) {
89.627 -// roots.addAll(activePlatform.getUniqueLibraryRoots());
89.628 -// ClassPath boot = ClassPathSupport.createClassPath(roots.toArray(new FileObject[roots.size()]));
89.629 -// ClassPath source = ClassPathSupport.createClassPath(new FileObject[]{fo.getParent()});
89.630 -// ClassPath compile = source;
89.631 -//
89.632 -// ClasspathInfo cpInfo = ClasspathInfo.create(boot, compile, source);
89.633 -// Source model = Source.create(cpInfo, fo);
89.634 -// if (model != null) {
89.635 -// final CompilationInfo[] infoHolder = new CompilationInfo[1];
89.636 -// //model.runUserActionTask(new CancellableTask<CompilationInfo>() {
89.637 -// model.runUserActionTask(new CancellableTask<CompilationController>() {
89.638 -// public void cancel() {
89.639 -// }
89.640 -//
89.641 -// //public void run(CompilationInfo info) throws Exception {
89.642 -// public void run(CompilationController info) throws Exception {
89.643 -// info.toPhase(Phase.RESOLVED);
89.644 -// infoHolder[0] = info;
89.645 -// // Force open so info.getFileObject will succeed
89.646 -// GsfUtilities.getDocument(fo, true);
89.647 -// }
89.648 -// }, false);
89.649 -// info = infoHolder[0];
89.650 -// }
89.651 -// }
89.652 -// }
89.653 - } catch (IOException ex) {
89.654 - Exceptions.printStackTrace(ex);
89.655 - }
89.656 - }
89.657 - try {
89.658 - if (info != null && info.getSnapshot().getSource().getDocument(false) != null) {
89.659 - Document doc = info.getSnapshot().getSource().getDocument(false);
89.660 - formatter.reformat(null, doc, 0, doc.getLength(), info);
89.661 - jep.setText(doc.getText(0, doc.getLength()));
89.662 - // Save file to avoid warning on exit
89.663 - DataObject dobj = DataObject.find(info.getSnapshot().getSource().getFileObject());
89.664 - SaveCookie cookie = dobj.getCookie(SaveCookie.class);
89.665 - if (cookie != null) {
89.666 - cookie.save();
89.667 - }
89.668 - } else {
89.669 - Document doc = jep.getDocument();
89.670 - if (doc.getLength() > 0) {
89.671 - doc.remove(0, doc.getLength());
89.672 - }
89.673 - doc.insertString(0, previewText, null);
89.674 - formatter.reformat(null, doc, 0, doc.getLength(), null);
89.675 - jep.setText(doc.getText(0, doc.getLength()));
89.676 - }
89.677 - } catch (DataObjectNotFoundException dof) {
89.678 - Exceptions.printStackTrace(dof);
89.679 - } catch (IOException | BadLocationException ioe) {
89.680 - Exceptions.printStackTrace(ioe);
89.681 - }
89.682 -
89.683 - if (tmpFo != null) {
89.684 - try {
89.685 - tmpFo.delete();
89.686 - } catch (IOException ex) {
89.687 - Exceptions.printStackTrace(ex);
89.688 - }
89.689 - } else if (tmp != null) {
89.690 - tmp.delete();
89.691 - }
89.692 -
89.693 -
89.694 - jep.setIgnoreRepaint(false);
89.695 - jep.scrollRectToVisible(new Rectangle(0, 0, 10, 10));
89.696 - jep.repaint(100);
89.697 - }
89.698 -
89.699 - // PreferencesCustomizer implementation --------------------------------
89.700 - @Override
89.701 - public JComponent getComponent() {
89.702 - return panel;
89.703 - }
89.704 -
89.705 - @Override
89.706 - public String getDisplayName() {
89.707 - return panel.getName();
89.708 - }
89.709 -
89.710 - @Override
89.711 - public String getId() {
89.712 - return id;
89.713 - }
89.714 -
89.715 - @Override
89.716 - public HelpCtx getHelpCtx() {
89.717 - return null;
89.718 - }
89.719 -
89.720 - // PreferencesCustomizer.Factory implementation ------------------------
89.721 - public static final class Factory implements PreferencesCustomizer.Factory {
89.722 - private final String id;
89.723 - private final Class<? extends JPanel> panelClass;
89.724 - private final String previewText;
89.725 - private final String[][] forcedOptions;
89.726 -
89.727 - public Factory(String id, Class<? extends JPanel> panelClass, String previewText, String[]... forcedOptions) {
89.728 - this.id = id;
89.729 - this.panelClass = panelClass;
89.730 - this.previewText = previewText;
89.731 - this.forcedOptions = forcedOptions;
89.732 - }
89.733 -
89.734 - @Override
89.735 - public PreferencesCustomizer create(Preferences preferences) {
89.736 - try {
89.737 - return new CategorySupport(preferences, id, panelClass.newInstance(), previewText, forcedOptions);
89.738 - } catch (IllegalAccessException | InstantiationException e) {
89.739 - return null;
89.740 - }
89.741 - }
89.742 - } // End of CategorySupport.Factory class
89.743 -
89.744 - // Private methods -----------------------------------------------------
89.745 - private void performOperation(int operation, JComponent jc, String optionID, Preferences p) {
89.746 - switch (operation) {
89.747 - case LOAD:
89.748 - loadData(jc, optionID, p);
89.749 - break;
89.750 - case STORE:
89.751 - storeData(jc, optionID, p);
89.752 - break;
89.753 - case ADD_LISTENERS:
89.754 - addListener(jc);
89.755 - break;
89.756 - }
89.757 - }
89.758 -
89.759 - private void scan(int what, Preferences p) {
89.760 - for (JComponent jc : components) {
89.761 - Object o = jc.getClientProperty(OPTION_ID);
89.762 - if (o instanceof String) {
89.763 - performOperation(what, jc, (String)o, p);
89.764 - } else if (o instanceof String[]) {
89.765 - for (String oid : (String[])o) {
89.766 - performOperation(what, jc, oid, p);
89.767 - }
89.768 - }
89.769 - }
89.770 - }
89.771 -
89.772 - private void scan(Container container, List<JComponent> components) {
89.773 - for (Component c : container.getComponents()) {
89.774 - if (c instanceof JComponent) {
89.775 - JComponent jc = (JComponent)c;
89.776 - Object o = jc.getClientProperty(OPTION_ID);
89.777 - if (o instanceof String || o instanceof String[]) {
89.778 - components.add(jc);
89.779 - }
89.780 - }
89.781 - if (c instanceof Container) {
89.782 - scan((Container)c, components);
89.783 - }
89.784 - }
89.785 - }
89.786 -
89.787 - /** Very smart method which tries to set the values in the components correctly
89.788 - */
89.789 - private void loadData(JComponent jc, String optionID, Preferences node) {
89.790 -
89.791 - if (jc instanceof JTextField) {
89.792 - JTextField field = (JTextField)jc;
89.793 - field.setText(node.get(optionID, getDefaultAsString(optionID)));
89.794 - } else if (jc instanceof JCheckBox) {
89.795 - JCheckBox checkBox = (JCheckBox)jc;
89.796 - boolean df = getDefaultAsBoolean(optionID);
89.797 - checkBox.setSelected(node.getBoolean(optionID, df));
89.798 - } else if (jc instanceof JComboBox) {
89.799 - JComboBox cb = (JComboBox)jc;
89.800 - String value = node.get(optionID, getDefaultAsString(optionID));
89.801 - ComboBoxModel model = createModel(value);
89.802 - cb.setModel(model);
89.803 - ComboItem item = whichItem(value, model);
89.804 - cb.setSelectedItem(item);
89.805 - }
89.806 -
89.807 - }
89.808 -
89.809 - private void storeData(JComponent jc, String optionID, Preferences node) {
89.810 -
89.811 - if (jc instanceof JTextField) {
89.812 - JTextField field = (JTextField)jc;
89.813 -
89.814 - String text = field.getText();
89.815 -
89.816 - // XXX test for numbers
89.817 - if (isInteger(optionID)) {
89.818 - try {
89.819 - int i = Integer.parseInt(text);
89.820 - } catch (NumberFormatException e) {
89.821 - return;
89.822 - }
89.823 - }
89.824 -
89.825 - // XXX: watch out, tabSize, spacesPerTab, indentSize and expandTabToSpaces
89.826 - // fall back on getGlopalXXX() values and not getDefaultAsXXX value,
89.827 - // which is why we must not remove them. Proper solution would be to
89.828 - // store formatting preferences to MimeLookup and not use NbPreferences.
89.829 - // The problem currently is that MimeLookup based Preferences do not support subnodes.
89.830 - if (!optionID.equals(tabSize) &&
89.831 - !optionID.equals(spacesPerTab) && !optionID.equals(indentSize) &&
89.832 - getDefaultAsString(optionID).equals(text)) {
89.833 - node.remove(optionID);
89.834 - } else {
89.835 - node.put(optionID, text);
89.836 - }
89.837 - } else if (jc instanceof JCheckBox) {
89.838 - JCheckBox checkBox = (JCheckBox)jc;
89.839 - if (!optionID.equals(expandTabToSpaces) && getDefaultAsBoolean(optionID) == checkBox.isSelected()) {
89.840 - node.remove(optionID);
89.841 - } else {
89.842 - node.putBoolean(optionID, checkBox.isSelected());
89.843 - }
89.844 - } else if (jc instanceof JComboBox) {
89.845 - JComboBox cb = (JComboBox)jc;
89.846 - // Logger.global.info( cb.getSelectedItem() + " " + optionID);
89.847 - String value = ((ComboItem)cb.getSelectedItem()).value;
89.848 - if (getDefaultAsString(optionID).equals(value)) {
89.849 - node.remove(optionID);
89.850 - } else {
89.851 - node.put(optionID, value);
89.852 - }
89.853 - }
89.854 - }
89.855 -
89.856 - private void addListener(JComponent jc) {
89.857 - if (jc instanceof JTextField) {
89.858 - JTextField field = (JTextField)jc;
89.859 - field.addActionListener(this);
89.860 - field.getDocument().addDocumentListener(this);
89.861 - } else if (jc instanceof JCheckBox) {
89.862 - JCheckBox checkBox = (JCheckBox)jc;
89.863 - checkBox.addActionListener(this);
89.864 - } else if (jc instanceof JComboBox) {
89.865 - JComboBox cb = (JComboBox)jc;
89.866 - cb.addActionListener(this);
89.867 - }
89.868 - }
89.869 -
89.870 - private ComboBoxModel createModel(String value) {
89.871 -
89.872 - // is it imports?
89.873 - for (ComboItem comboItem : cleanupImports) {
89.874 - if (value.equals(comboItem.value)) {
89.875 - return new DefaultComboBoxModel(cleanupImports);
89.876 - }
89.877 - }
89.878 -
89.879 - // is it wrap
89.880 - for (ComboItem comboItem : wrap) {
89.881 - if (value.equals(comboItem.value)) {
89.882 - return new DefaultComboBoxModel(wrap);
89.883 - }
89.884 - }
89.885 -
89.886 - return null;
89.887 - }
89.888 -
89.889 - private static ComboItem whichItem(String value, ComboBoxModel model) {
89.890 -
89.891 - for (int i = 0; i < model.getSize(); i++) {
89.892 - ComboItem item = (ComboItem)model.getElementAt(i);
89.893 - if (value.equals(item.value)) {
89.894 - return item;
89.895 - }
89.896 - }
89.897 - return null;
89.898 - }
89.899 -
89.900 - private static class ComboItem {
89.901 - String value;
89.902 - String displayName;
89.903 -
89.904 - public ComboItem(String value, String key) {
89.905 - this.value = value;
89.906 - this.displayName = NbBundle.getMessage(FmtOptions.class, key);
89.907 - }
89.908 -
89.909 - @Override
89.910 - public String toString() {
89.911 - return displayName;
89.912 - }
89.913 - }
89.914 - }
89.915 -
89.916 - public static class PreviewPreferences extends AbstractPreferences {
89.917 - private Map<String, Object> map = new HashMap<>();
89.918 -
89.919 - public PreviewPreferences() {
89.920 - super(null, ""); // NOI18N
89.921 - }
89.922 -
89.923 - @Override
89.924 - protected void putSpi(String key, String value) {
89.925 - map.put(key, value);
89.926 - }
89.927 -
89.928 - @Override
89.929 - protected String getSpi(String key) {
89.930 - return (String)map.get(key);
89.931 - }
89.932 -
89.933 - @Override
89.934 - protected void removeSpi(String key) {
89.935 - map.remove(key);
89.936 - }
89.937 -
89.938 - @Override
89.939 - protected void removeNodeSpi() throws BackingStoreException {
89.940 - throw new UnsupportedOperationException("Not supported yet.");
89.941 - }
89.942 -
89.943 - @Override
89.944 - protected String[] keysSpi() throws BackingStoreException {
89.945 - String array[] = new String[map.keySet().size()];
89.946 - return map.keySet().toArray(array);
89.947 - }
89.948 -
89.949 - @Override
89.950 - protected String[] childrenNamesSpi() throws BackingStoreException {
89.951 - throw new UnsupportedOperationException("Not supported yet.");
89.952 - }
89.953 -
89.954 - @Override
89.955 - protected AbstractPreferences childSpi(String name) {
89.956 - throw new UnsupportedOperationException("Not supported yet.");
89.957 - }
89.958 -
89.959 - @Override
89.960 - protected void syncSpi() throws BackingStoreException {
89.961 - throw new UnsupportedOperationException("Not supported yet.");
89.962 - }
89.963 -
89.964 - @Override
89.965 - protected void flushSpi() throws BackingStoreException {
89.966 - throw new UnsupportedOperationException("Not supported yet.");
89.967 - }
89.968 - }
89.969 -
89.970 - // read-only, no subnodes
89.971 - public static final class ProxyPreferences extends AbstractPreferences {
89.972 - private final Preferences[] delegates;
89.973 -
89.974 - public ProxyPreferences(Preferences... delegates) {
89.975 - super(null, ""); // NOI18N
89.976 - this.delegates = delegates;
89.977 - }
89.978 -
89.979 - @Override
89.980 - protected void putSpi(String key, String value) {
89.981 - throw new UnsupportedOperationException("Not supported yet.");
89.982 - }
89.983 -
89.984 - @Override
89.985 - protected String getSpi(String key) {
89.986 - for (Preferences p : delegates) {
89.987 - String value = p.get(key, null);
89.988 - if (value != null) {
89.989 - return value;
89.990 - }
89.991 - }
89.992 - return null;
89.993 - }
89.994 -
89.995 - @Override
89.996 - protected void removeSpi(String key) {
89.997 - throw new UnsupportedOperationException("Not supported yet.");
89.998 - }
89.999 -
89.1000 - @Override
89.1001 - protected void removeNodeSpi() throws BackingStoreException {
89.1002 - throw new UnsupportedOperationException("Not supported yet.");
89.1003 - }
89.1004 -
89.1005 - @Override
89.1006 - protected String[] keysSpi() throws BackingStoreException {
89.1007 - Set<String> keys = new HashSet<>();
89.1008 - for (Preferences p : delegates) {
89.1009 - keys.addAll(Arrays.asList(p.keys()));
89.1010 - }
89.1011 - return keys.toArray(new String[keys.size()]);
89.1012 - }
89.1013 -
89.1014 - @Override
89.1015 - protected String[] childrenNamesSpi() throws BackingStoreException {
89.1016 - throw new UnsupportedOperationException("Not supported yet.");
89.1017 - }
89.1018 -
89.1019 - @Override
89.1020 - protected AbstractPreferences childSpi(String name) {
89.1021 - throw new UnsupportedOperationException("Not supported yet.");
89.1022 - }
89.1023 -
89.1024 - @Override
89.1025 - protected void syncSpi() throws BackingStoreException {
89.1026 - throw new UnsupportedOperationException("Not supported yet.");
89.1027 - }
89.1028 -
89.1029 - @Override
89.1030 - protected void flushSpi() throws BackingStoreException {
89.1031 - throw new UnsupportedOperationException("Not supported yet.");
89.1032 - }
89.1033 - } // End of ProxyPreferences class
89.1034 -
89.1035 - public static interface CodeStyleProducer {
89.1036 - public CodeStyle create(Preferences preferences);
89.1037 - }
89.1038 -}
90.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtSpaces.form Mon Aug 31 12:40:19 2015 +0200
90.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
90.3 @@ -1,104 +0,0 @@
90.4 -<?xml version="1.0" encoding="UTF-8" ?>
90.5 -
90.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
90.7 - <Properties>
90.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Spaces" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.10 - </Property>
90.11 - <Property name="opaque" type="boolean" value="false"/>
90.12 - </Properties>
90.13 - <AuxValues>
90.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
90.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
90.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
90.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
90.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
90.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
90.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
90.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
90.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
90.23 - </AuxValues>
90.24 -
90.25 - <Layout>
90.26 - <DimensionLayout dim="0">
90.27 - <Group type="103" groupAlignment="0" attributes="0">
90.28 - <Group type="102" attributes="0">
90.29 - <Group type="103" groupAlignment="0" attributes="0">
90.30 - <Component id="addAroundOp" alignment="0" min="-2" max="-2" attributes="0"/>
90.31 - <Group type="102" alignment="0" attributes="0">
90.32 - <EmptySpace min="27" pref="27" max="27" attributes="0"/>
90.33 - <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
90.34 - </Group>
90.35 - <Component id="removeInParen" alignment="0" min="-2" max="-2" attributes="0"/>
90.36 - <Component id="addAfterComma" alignment="0" min="-2" max="-2" attributes="0"/>
90.37 - <Component id="removeBeforeSep" alignment="0" min="-2" max="-2" attributes="0"/>
90.38 - <Component id="collapseSpacesCb" alignment="0" min="-2" max="-2" attributes="0"/>
90.39 - </Group>
90.40 - <EmptySpace max="32767" attributes="0"/>
90.41 - </Group>
90.42 - </Group>
90.43 - </DimensionLayout>
90.44 - <DimensionLayout dim="1">
90.45 - <Group type="103" groupAlignment="0" attributes="0">
90.46 - <Group type="102" alignment="0" attributes="0">
90.47 - <Component id="addAroundOp" min="-2" max="-2" attributes="0"/>
90.48 - <EmptySpace max="-2" attributes="0"/>
90.49 - <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
90.50 - <EmptySpace max="-2" attributes="0"/>
90.51 - <Component id="removeInParen" min="-2" max="-2" attributes="0"/>
90.52 - <EmptySpace max="-2" attributes="0"/>
90.53 - <Component id="addAfterComma" min="-2" max="-2" attributes="0"/>
90.54 - <EmptySpace max="-2" attributes="0"/>
90.55 - <Component id="removeBeforeSep" min="-2" max="-2" attributes="0"/>
90.56 - <EmptySpace max="-2" attributes="0"/>
90.57 - <Component id="collapseSpacesCb" min="-2" max="-2" attributes="0"/>
90.58 - <EmptySpace max="32767" attributes="0"/>
90.59 - </Group>
90.60 - </Group>
90.61 - </DimensionLayout>
90.62 - </Layout>
90.63 - <SubComponents>
90.64 - <Component class="javax.swing.JCheckBox" name="addAroundOp">
90.65 - <Properties>
90.66 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.67 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAroundOp.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.68 - </Property>
90.69 - </Properties>
90.70 - </Component>
90.71 - <Component class="javax.swing.JCheckBox" name="removeInParam">
90.72 - <Properties>
90.73 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.74 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParam.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.75 - </Property>
90.76 - </Properties>
90.77 - </Component>
90.78 - <Component class="javax.swing.JCheckBox" name="removeInParen">
90.79 - <Properties>
90.80 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.81 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.82 - </Property>
90.83 - </Properties>
90.84 - </Component>
90.85 - <Component class="javax.swing.JCheckBox" name="addAfterComma">
90.86 - <Properties>
90.87 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.88 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAfterComma.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.89 - </Property>
90.90 - </Properties>
90.91 - </Component>
90.92 - <Component class="javax.swing.JCheckBox" name="removeBeforeSep">
90.93 - <Properties>
90.94 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.95 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeBeforeSep.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.96 - </Property>
90.97 - </Properties>
90.98 - </Component>
90.99 - <Component class="javax.swing.JCheckBox" name="collapseSpacesCb">
90.100 - <Properties>
90.101 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
90.102 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.collapseSpacesCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
90.103 - </Property>
90.104 - </Properties>
90.105 - </Component>
90.106 - </SubComponents>
90.107 -</Form>
91.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtSpaces.java Mon Aug 31 12:40:19 2015 +0200
91.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
91.3 @@ -1,143 +0,0 @@
91.4 -/*
91.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
91.6 - *
91.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
91.8 - *
91.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
91.10 - * Other names may be trademarks of their respective owners.
91.11 - *
91.12 - * The contents of this file are subject to the terms of either the GNU
91.13 - * General Public License Version 2 only ("GPL") or the Common
91.14 - * Development and Distribution License("CDDL") (collectively, the
91.15 - * "License"). You may not use this file except in compliance with the
91.16 - * License. You can obtain a copy of the License at
91.17 - * http://www.netbeans.org/cddl-gplv2.html
91.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
91.19 - * specific language governing permissions and limitations under the
91.20 - * License. When distributing the software, include this License Header
91.21 - * Notice in each file and include the License file at
91.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
91.23 - * particular file as subject to the "Classpath" exception as provided
91.24 - * by Oracle in the GPL Version 2 section of the License file that
91.25 - * accompanied this code. If applicable, add the following below the
91.26 - * License Header, with the fields enclosed by brackets [] replaced by
91.27 - * your own identifying information:
91.28 - * "Portions Copyrighted [year] [name of copyright owner]"
91.29 - *
91.30 - * Contributor(s):
91.31 - *
91.32 - * The Original Software is NetBeans. The Initial Developer of the Original
91.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
91.34 - * Microsystems, Inc. All Rights Reserved.
91.35 - *
91.36 - * If you wish your version of this file to be governed by only the CDDL
91.37 - * or only the GPL Version 2, indicate your decision by adding
91.38 - * "[Contributor] elects to include this software in this distribution
91.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
91.40 - * single choice of license, a recipient has the option to distribute
91.41 - * your version of this file under either the CDDL, the GPL Version 2 or
91.42 - * to extend the choice of license to its licensees as provided above.
91.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
91.44 - * Version 2 license, then the option applies only if the new code is
91.45 - * made subject to such option by the copyright holder.
91.46 - */
91.47 -
91.48 -package org.netbeans.modules.python.editor.options;
91.49 -
91.50 -import javax.swing.JPanel;
91.51 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
91.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
91.53 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
91.54 -
91.55 -/**
91.56 - * Preferences for formatting related to spaces
91.57 - *
91.58 - * @author Tor Norbye
91.59 - */
91.60 -public class FmtSpaces extends JPanel {
91.61 - public FmtSpaces() {
91.62 - initComponents();
91.63 -
91.64 - addAroundOp.putClientProperty(OPTION_ID, addSpaceAroundOperators);
91.65 - addAfterComma.putClientProperty(OPTION_ID, addSpaceAfterComma);
91.66 - removeBeforeSep.putClientProperty(OPTION_ID, removeSpaceBeforeSep);
91.67 - removeInParam.putClientProperty(OPTION_ID, removeSpaceInParamAssign);
91.68 - removeInParen.putClientProperty(OPTION_ID, removeSpaceInParens);
91.69 - collapseSpacesCb.putClientProperty(OPTION_ID, collapseSpaces);
91.70 - }
91.71 -
91.72 - public static PreferencesCustomizer.Factory getController() {
91.73 - return new CategorySupport.Factory("spaces", FmtSpaces.class, // NOI18N
91.74 - org.openide.util.NbBundle.getMessage(FmtSpaces.class, "SAMPLE_Spaces"));
91.75 - }
91.76 -
91.77 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
91.78 - private void initComponents() {
91.79 -
91.80 - addAroundOp = new javax.swing.JCheckBox();
91.81 - removeInParam = new javax.swing.JCheckBox();
91.82 - removeInParen = new javax.swing.JCheckBox();
91.83 - addAfterComma = new javax.swing.JCheckBox();
91.84 - removeBeforeSep = new javax.swing.JCheckBox();
91.85 - collapseSpacesCb = new javax.swing.JCheckBox();
91.86 -
91.87 - setName(org.openide.util.NbBundle.getMessage(FmtSpaces.class, "LBL_Spaces")); // NOI18N
91.88 - setOpaque(false);
91.89 -
91.90 - org.openide.awt.Mnemonics.setLocalizedText(addAroundOp, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAroundOp.text")); // NOI18N
91.91 -
91.92 - org.openide.awt.Mnemonics.setLocalizedText(removeInParam, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParam.text")); // NOI18N
91.93 -
91.94 - org.openide.awt.Mnemonics.setLocalizedText(removeInParen, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParen.text")); // NOI18N
91.95 -
91.96 - org.openide.awt.Mnemonics.setLocalizedText(addAfterComma, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAfterComma.text")); // NOI18N
91.97 -
91.98 - org.openide.awt.Mnemonics.setLocalizedText(removeBeforeSep, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeBeforeSep.text")); // NOI18N
91.99 -
91.100 - org.openide.awt.Mnemonics.setLocalizedText(collapseSpacesCb, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.collapseSpacesCb.text")); // NOI18N
91.101 -
91.102 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
91.103 - this.setLayout(layout);
91.104 - layout.setHorizontalGroup(
91.105 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
91.106 - .addGroup(layout.createSequentialGroup()
91.107 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
91.108 - .addComponent(addAroundOp)
91.109 - .addGroup(layout.createSequentialGroup()
91.110 - .addGap(27, 27, 27)
91.111 - .addComponent(removeInParam))
91.112 - .addComponent(removeInParen)
91.113 - .addComponent(addAfterComma)
91.114 - .addComponent(removeBeforeSep)
91.115 - .addComponent(collapseSpacesCb))
91.116 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
91.117 - );
91.118 - layout.setVerticalGroup(
91.119 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
91.120 - .addGroup(layout.createSequentialGroup()
91.121 - .addComponent(addAroundOp)
91.122 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91.123 - .addComponent(removeInParam)
91.124 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91.125 - .addComponent(removeInParen)
91.126 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91.127 - .addComponent(addAfterComma)
91.128 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91.129 - .addComponent(removeBeforeSep)
91.130 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91.131 - .addComponent(collapseSpacesCb)
91.132 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
91.133 - );
91.134 - }// </editor-fold>//GEN-END:initComponents
91.135 -
91.136 -
91.137 - // Variables declaration - do not modify//GEN-BEGIN:variables
91.138 - private javax.swing.JCheckBox addAfterComma;
91.139 - private javax.swing.JCheckBox addAroundOp;
91.140 - private javax.swing.JCheckBox collapseSpacesCb;
91.141 - private javax.swing.JCheckBox removeBeforeSep;
91.142 - private javax.swing.JCheckBox removeInParam;
91.143 - private javax.swing.JCheckBox removeInParen;
91.144 - // End of variables declaration//GEN-END:variables
91.145 -
91.146 -}
92.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtTabsIndents.form Mon Aug 31 12:40:19 2015 +0200
92.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
92.3 @@ -1,127 +0,0 @@
92.4 -<?xml version="1.0" encoding="UTF-8" ?>
92.5 -
92.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
92.7 - <Properties>
92.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
92.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_TabsAndIndents" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
92.10 - </Property>
92.11 - <Property name="opaque" type="boolean" value="false"/>
92.12 - </Properties>
92.13 - <AuxValues>
92.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
92.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
92.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
92.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
92.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
92.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
92.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
92.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
92.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
92.23 - </AuxValues>
92.24 -
92.25 - <Layout>
92.26 - <DimensionLayout dim="0">
92.27 - <Group type="103" groupAlignment="0" attributes="0">
92.28 - <Group type="102" alignment="0" attributes="0">
92.29 - <Group type="103" groupAlignment="0" attributes="0">
92.30 - <Component id="continuationIndentSizeLabel" max="32767" attributes="0"/>
92.31 - <Component id="labelIndentLabel" min="-2" max="-2" attributes="0"/>
92.32 - </Group>
92.33 - <EmptySpace max="-2" attributes="0"/>
92.34 - <Group type="103" groupAlignment="1" attributes="0">
92.35 - <Component id="continuationIndentSizeField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
92.36 - <Component id="labelIndentField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
92.37 - </Group>
92.38 - </Group>
92.39 - <Component id="indentCasesFromSwitchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
92.40 - <Component id="indentTopLevelClassMembersCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
92.41 - <Component id="absoluteLabelIndentCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
92.42 - </Group>
92.43 - </DimensionLayout>
92.44 - <DimensionLayout dim="1">
92.45 - <Group type="103" groupAlignment="0" attributes="0">
92.46 - <Group type="102" attributes="0">
92.47 - <EmptySpace max="-2" attributes="0"/>
92.48 - <Group type="103" groupAlignment="3" attributes="0">
92.49 - <Component id="continuationIndentSizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
92.50 - <Component id="continuationIndentSizeField" alignment="3" min="-2" max="-2" attributes="0"/>
92.51 - </Group>
92.52 - <EmptySpace min="-2" max="-2" attributes="0"/>
92.53 - <Group type="103" groupAlignment="3" attributes="0">
92.54 - <Component id="labelIndentLabel" alignment="3" min="-2" max="-2" attributes="0"/>
92.55 - <Component id="labelIndentField" alignment="3" min="-2" max="-2" attributes="0"/>
92.56 - </Group>
92.57 - <EmptySpace type="unrelated" max="-2" attributes="0"/>
92.58 - <Component id="absoluteLabelIndentCheckBox" min="-2" max="-2" attributes="0"/>
92.59 - <EmptySpace max="-2" attributes="0"/>
92.60 - <Component id="indentTopLevelClassMembersCheckBox" min="-2" max="-2" attributes="0"/>
92.61 - <EmptySpace max="-2" attributes="0"/>
92.62 - <Component id="indentCasesFromSwitchCheckBox" min="-2" max="-2" attributes="0"/>
92.63 - <EmptySpace max="32767" attributes="0"/>
92.64 - </Group>
92.65 - </Group>
92.66 - </DimensionLayout>
92.67 - </Layout>
92.68 - <SubComponents>
92.69 - <Component class="javax.swing.JLabel" name="continuationIndentSizeLabel">
92.70 - <Properties>
92.71 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
92.72 - <ComponentRef name="continuationIndentSizeField"/>
92.73 - </Property>
92.74 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
92.75 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_ContinuationIndentSize" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
92.76 - </Property>
92.77 - </Properties>
92.78 - </Component>
92.79 - <Component class="javax.swing.JTextField" name="continuationIndentSizeField">
92.80 - </Component>
92.81 - <Component class="javax.swing.JLabel" name="labelIndentLabel">
92.82 - <Properties>
92.83 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
92.84 - <ComponentRef name="labelIndentField"/>
92.85 - </Property>
92.86 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
92.87 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_LabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
92.88 - </Property>
92.89 - </Properties>
92.90 - </Component>
92.91 - <Component class="javax.swing.JTextField" name="labelIndentField">
92.92 - </Component>
92.93 - <Component class="javax.swing.JCheckBox" name="absoluteLabelIndentCheckBox">
92.94 - <Properties>
92.95 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
92.96 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_AbsoluteLabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
92.97 - </Property>
92.98 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
92.99 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
92.100 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
92.101 - </Border>
92.102 - </Property>
92.103 - </Properties>
92.104 - </Component>
92.105 - <Component class="javax.swing.JCheckBox" name="indentTopLevelClassMembersCheckBox">
92.106 - <Properties>
92.107 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
92.108 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentTopLevelClassMemberts" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
92.109 - </Property>
92.110 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
92.111 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
92.112 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
92.113 - </Border>
92.114 - </Property>
92.115 - </Properties>
92.116 - </Component>
92.117 - <Component class="javax.swing.JCheckBox" name="indentCasesFromSwitchCheckBox">
92.118 - <Properties>
92.119 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
92.120 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentCasesFromSwitch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
92.121 - </Property>
92.122 - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
92.123 - <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
92.124 - <EmptyBorder bottom="0" left="0" right="0" top="0"/>
92.125 - </Border>
92.126 - </Property>
92.127 - </Properties>
92.128 - </Component>
92.129 - </SubComponents>
92.130 -</Form>
93.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtTabsIndents.java Mon Aug 31 12:40:19 2015 +0200
93.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
93.3 @@ -1,196 +0,0 @@
93.4 -/*
93.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
93.6 - *
93.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
93.8 - *
93.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
93.10 - * Other names may be trademarks of their respective owners.
93.11 - *
93.12 - * The contents of this file are subject to the terms of either the GNU
93.13 - * General Public License Version 2 only ("GPL") or the Common
93.14 - * Development and Distribution License("CDDL") (collectively, the
93.15 - * "License"). You may not use this file except in compliance with the
93.16 - * License. You can obtain a copy of the License at
93.17 - * http://www.netbeans.org/cddl-gplv2.html
93.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
93.19 - * specific language governing permissions and limitations under the
93.20 - * License. When distributing the software, include this License Header
93.21 - * Notice in each file and include the License file at
93.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
93.23 - * particular file as subject to the "Classpath" exception as provided
93.24 - * by Oracle in the GPL Version 2 section of the License file that
93.25 - * accompanied this code. If applicable, add the following below the
93.26 - * License Header, with the fields enclosed by brackets [] replaced by
93.27 - * your own identifying information:
93.28 - * "Portions Copyrighted [year] [name of copyright owner]"
93.29 - *
93.30 - * Contributor(s):
93.31 - *
93.32 - * The Original Software is NetBeans. The Initial Developer of the Original
93.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
93.34 - * Microsystems, Inc. All Rights Reserved.
93.35 - *
93.36 - * If you wish your version of this file to be governed by only the CDDL
93.37 - * or only the GPL Version 2, indicate your decision by adding
93.38 - * "[Contributor] elects to include this software in this distribution
93.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
93.40 - * single choice of license, a recipient has the option to distribute
93.41 - * your version of this file under either the CDDL, the GPL Version 2 or
93.42 - * to extend the choice of license to its licensees as provided above.
93.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
93.44 - * Version 2 license, then the option applies only if the new code is
93.45 - * made subject to such option by the copyright holder.
93.46 - */
93.47 -
93.48 -package org.netbeans.modules.python.editor.options;
93.49 -
93.50 -import org.netbeans.modules.python.editor.options.CodeStyle.WrapStyle;
93.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
93.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
93.53 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
93.54 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
93.55 -
93.56 -/**
93.57 - *
93.58 - * @author phrebejk
93.59 - */
93.60 -public class FmtTabsIndents extends javax.swing.JPanel {
93.61 -
93.62 - /** Creates new form FmtTabsIndents */
93.63 - public FmtTabsIndents() {
93.64 - initComponents();
93.65 -/*
93.66 -// expandTabCheckBox.putClientProperty(OPTION_ID, expandTabToSpaces);
93.67 -// tabSizeField.putClientProperty(OPTION_ID, tabSize);
93.68 -// indentSizeField.putClientProperty(OPTION_ID, new String [] { indentSize, spacesPerTab });
93.69 - continuationIndentSizeField.putClientProperty(OPTION_ID, continuationIndentSize);
93.70 - labelIndentField.putClientProperty(OPTION_ID, labelIndent);
93.71 - absoluteLabelIndentCheckBox.putClientProperty(OPTION_ID, absoluteLabelIndent);
93.72 - indentTopLevelClassMembersCheckBox.putClientProperty(OPTION_ID, indentTopLevelClassMembers);
93.73 - indentCasesFromSwitchCheckBox.putClientProperty(OPTION_ID, indentCasesFromSwitch);
93.74 -// rightMarginField.putClientProperty(OPTION_ID, rightMargin);
93.75 - }
93.76 -
93.77 - public static PreferencesCustomizer.Factory getController() {
93.78 - return new CategorySupport.Factory(PreferencesCustomizer.TABS_AND_INDENTS_ID, FmtTabsIndents.class, //NOI18N
93.79 - org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "SAMPLE_TabsIndents"), // NOI18N
93.80 - new String[] { FmtOptions.rightMargin, "30" }, //NOI18N
93.81 - new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
93.82 - new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
93.83 - new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
93.84 - new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
93.85 - new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
93.86 - new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
93.87 - new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
93.88 - new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
93.89 - new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
93.90 - new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
93.91 - new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
93.92 - new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
93.93 - new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
93.94 - new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
93.95 - new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
93.96 - new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
93.97 - new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
93.98 - new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
93.99 - new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
93.100 - new String[] { FmtOptions.alignMultilineArrayInit, Boolean.FALSE.toString() },
93.101 - new String[] { FmtOptions.alignMultilineAssignment, Boolean.FALSE.toString() },
93.102 - new String[] { FmtOptions.alignMultilineBinaryOp, Boolean.FALSE.toString() },
93.103 - new String[] { FmtOptions.alignMultilineCallArgs, Boolean.FALSE.toString() },
93.104 - new String[] { FmtOptions.alignMultilineFor, Boolean.FALSE.toString() },
93.105 - new String[] { FmtOptions.alignMultilineImplements, Boolean.FALSE.toString() },
93.106 - new String[] { FmtOptions.alignMultilineMethodParams, Boolean.FALSE.toString() },
93.107 - new String[] { FmtOptions.alignMultilineParenthesized, Boolean.FALSE.toString() },
93.108 - new String[] { FmtOptions.alignMultilineTernaryOp, Boolean.FALSE.toString() },
93.109 - new String[] { FmtOptions.alignMultilineThrows, Boolean.FALSE.toString() }
93.110 - );
93.111 - */
93.112 - }
93.113 -
93.114 - /** This method is called from within the constructor to
93.115 - * initialize the form.
93.116 - * WARNING: Do NOT modify this code. The content of this method is
93.117 - * always regenerated by the Form Editor.
93.118 - */
93.119 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
93.120 - private void initComponents() {
93.121 -
93.122 - continuationIndentSizeLabel = new javax.swing.JLabel();
93.123 - continuationIndentSizeField = new javax.swing.JTextField();
93.124 - labelIndentLabel = new javax.swing.JLabel();
93.125 - labelIndentField = new javax.swing.JTextField();
93.126 - absoluteLabelIndentCheckBox = new javax.swing.JCheckBox();
93.127 - indentTopLevelClassMembersCheckBox = new javax.swing.JCheckBox();
93.128 - indentCasesFromSwitchCheckBox = new javax.swing.JCheckBox();
93.129 -
93.130 - setName(org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_TabsAndIndents")); // NOI18N
93.131 - setOpaque(false);
93.132 -
93.133 - continuationIndentSizeLabel.setLabelFor(continuationIndentSizeField);
93.134 - org.openide.awt.Mnemonics.setLocalizedText(continuationIndentSizeLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_ContinuationIndentSize")); // NOI18N
93.135 -
93.136 - labelIndentLabel.setLabelFor(labelIndentField);
93.137 - org.openide.awt.Mnemonics.setLocalizedText(labelIndentLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_LabelIndent")); // NOI18N
93.138 -
93.139 - org.openide.awt.Mnemonics.setLocalizedText(absoluteLabelIndentCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_AbsoluteLabelIndent")); // NOI18N
93.140 - absoluteLabelIndentCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
93.141 -
93.142 - org.openide.awt.Mnemonics.setLocalizedText(indentTopLevelClassMembersCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentTopLevelClassMemberts")); // NOI18N
93.143 - indentTopLevelClassMembersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
93.144 -
93.145 - org.openide.awt.Mnemonics.setLocalizedText(indentCasesFromSwitchCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentCasesFromSwitch")); // NOI18N
93.146 - indentCasesFromSwitchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
93.147 -
93.148 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
93.149 - this.setLayout(layout);
93.150 - layout.setHorizontalGroup(
93.151 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
93.152 - .addGroup(layout.createSequentialGroup()
93.153 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
93.154 - .addComponent(continuationIndentSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
93.155 - .addComponent(labelIndentLabel))
93.156 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
93.157 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
93.158 - .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
93.159 - .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)))
93.160 - .addComponent(indentCasesFromSwitchCheckBox)
93.161 - .addComponent(indentTopLevelClassMembersCheckBox)
93.162 - .addComponent(absoluteLabelIndentCheckBox)
93.163 - );
93.164 -
93.165 - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {continuationIndentSizeField, labelIndentField});
93.166 -
93.167 - layout.setVerticalGroup(
93.168 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
93.169 - .addGroup(layout.createSequentialGroup()
93.170 - .addContainerGap()
93.171 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
93.172 - .addComponent(continuationIndentSizeLabel)
93.173 - .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
93.174 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
93.175 - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
93.176 - .addComponent(labelIndentLabel)
93.177 - .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
93.178 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
93.179 - .addComponent(absoluteLabelIndentCheckBox)
93.180 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
93.181 - .addComponent(indentTopLevelClassMembersCheckBox)
93.182 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
93.183 - .addComponent(indentCasesFromSwitchCheckBox)
93.184 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
93.185 - );
93.186 - }// </editor-fold>//GEN-END:initComponents
93.187 -
93.188 -
93.189 - // Variables declaration - do not modify//GEN-BEGIN:variables
93.190 - private javax.swing.JCheckBox absoluteLabelIndentCheckBox;
93.191 - private javax.swing.JTextField continuationIndentSizeField;
93.192 - private javax.swing.JLabel continuationIndentSizeLabel;
93.193 - private javax.swing.JCheckBox indentCasesFromSwitchCheckBox;
93.194 - private javax.swing.JCheckBox indentTopLevelClassMembersCheckBox;
93.195 - private javax.swing.JTextField labelIndentField;
93.196 - private javax.swing.JLabel labelIndentLabel;
93.197 - // End of variables declaration//GEN-END:variables
93.198 -
93.199 -}
94.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtWrapping.form Mon Aug 31 12:40:19 2015 +0200
94.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
94.3 @@ -1,706 +0,0 @@
94.4 -<?xml version="1.0" encoding="UTF-8" ?>
94.5 -
94.6 -<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
94.7 - <Properties>
94.8 - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.9 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Wrapping" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.10 - </Property>
94.11 - <Property name="opaque" type="boolean" value="false"/>
94.12 - </Properties>
94.13 - <AuxValues>
94.14 - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
94.15 - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
94.16 - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
94.17 - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
94.18 - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
94.19 - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
94.20 - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
94.21 - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
94.22 - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
94.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"/>
94.24 - </AuxValues>
94.25 -
94.26 - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
94.27 - <SubComponents>
94.28 - <Container class="javax.swing.JScrollPane" name="scrollPane">
94.29 - <Properties>
94.30 - <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
94.31 - <Dimension value="[300, 200]"/>
94.32 - </Property>
94.33 - <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
94.34 - <Dimension value="[350, 600]"/>
94.35 - </Property>
94.36 - </Properties>
94.37 - <Constraints>
94.38 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
94.39 - <BorderConstraints direction="Center"/>
94.40 - </Constraint>
94.41 - </Constraints>
94.42 -
94.43 - <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
94.44 - <SubComponents>
94.45 - <Container class="javax.swing.JPanel" name="panel1">
94.46 - <Properties>
94.47 - <Property name="opaque" type="boolean" value="false"/>
94.48 - </Properties>
94.49 -
94.50 - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
94.51 - <SubComponents>
94.52 - <Component class="javax.swing.JLabel" name="extendsImplemetsKeywordLabel">
94.53 - <Properties>
94.54 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.55 - <ComponentRef name="extendsImplementsKeywordCombo"/>
94.56 - </Property>
94.57 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.58 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.59 - </Property>
94.60 - </Properties>
94.61 - <Constraints>
94.62 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.64 - </Constraint>
94.65 - </Constraints>
94.66 - </Component>
94.67 - <Component class="javax.swing.JComboBox" name="extendsImplementsKeywordCombo">
94.68 - <Properties>
94.69 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.70 - <StringArray count="4">
94.71 - <StringItem index="0" value="Item 1"/>
94.72 - <StringItem index="1" value="Item 2"/>
94.73 - <StringItem index="2" value="Item 3"/>
94.74 - <StringItem index="3" value="Item 4"/>
94.75 - </StringArray>
94.76 - </Property>
94.77 - </Properties>
94.78 - <Constraints>
94.79 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.81 - </Constraint>
94.82 - </Constraints>
94.83 - </Component>
94.84 - <Component class="javax.swing.JLabel" name="extendsImplementsListLabel">
94.85 - <Properties>
94.86 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.87 - <ComponentRef name="extendsImplementsListCombo"/>
94.88 - </Property>
94.89 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.90 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.91 - </Property>
94.92 - </Properties>
94.93 - <Constraints>
94.94 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.96 - </Constraint>
94.97 - </Constraints>
94.98 - </Component>
94.99 - <Component class="javax.swing.JComboBox" name="extendsImplementsListCombo">
94.100 - <Properties>
94.101 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.102 - <StringArray count="4">
94.103 - <StringItem index="0" value="Item 1"/>
94.104 - <StringItem index="1" value="Item 2"/>
94.105 - <StringItem index="2" value="Item 3"/>
94.106 - <StringItem index="3" value="Item 4"/>
94.107 - </StringArray>
94.108 - </Property>
94.109 - </Properties>
94.110 - <Constraints>
94.111 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.113 - </Constraint>
94.114 - </Constraints>
94.115 - </Component>
94.116 - <Component class="javax.swing.JLabel" name="methodParamsLabel">
94.117 - <Properties>
94.118 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.119 - <ComponentRef name="methodParamsCombo"/>
94.120 - </Property>
94.121 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.122 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodParameters" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.123 - </Property>
94.124 - </Properties>
94.125 - <Constraints>
94.126 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.128 - </Constraint>
94.129 - </Constraints>
94.130 - </Component>
94.131 - <Component class="javax.swing.JComboBox" name="methodParamsCombo">
94.132 - <Properties>
94.133 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.134 - <StringArray count="4">
94.135 - <StringItem index="0" value="Item 1"/>
94.136 - <StringItem index="1" value="Item 2"/>
94.137 - <StringItem index="2" value="Item 3"/>
94.138 - <StringItem index="3" value="Item 4"/>
94.139 - </StringArray>
94.140 - </Property>
94.141 - </Properties>
94.142 - <Constraints>
94.143 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.145 - </Constraint>
94.146 - </Constraints>
94.147 - </Component>
94.148 - <Component class="javax.swing.JLabel" name="methodCallArgsLabel">
94.149 - <Properties>
94.150 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.151 - <ComponentRef name="methodCallArgsCombo"/>
94.152 - </Property>
94.153 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.154 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodCallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.155 - </Property>
94.156 - </Properties>
94.157 - <Constraints>
94.158 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.160 - </Constraint>
94.161 - </Constraints>
94.162 - </Component>
94.163 - <Component class="javax.swing.JComboBox" name="methodCallArgsCombo">
94.164 - <Properties>
94.165 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.166 - <StringArray count="4">
94.167 - <StringItem index="0" value="Item 1"/>
94.168 - <StringItem index="1" value="Item 2"/>
94.169 - <StringItem index="2" value="Item 3"/>
94.170 - <StringItem index="3" value="Item 4"/>
94.171 - </StringArray>
94.172 - </Property>
94.173 - </Properties>
94.174 - <Constraints>
94.175 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.177 - </Constraint>
94.178 - </Constraints>
94.179 - </Component>
94.180 - <Component class="javax.swing.JLabel" name="annotationArgsLabel">
94.181 - <Properties>
94.182 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.183 - <ComponentRef name="annotationArgsCombo"/>
94.184 - </Property>
94.185 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.186 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.187 - </Property>
94.188 - </Properties>
94.189 - <Constraints>
94.190 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.192 - </Constraint>
94.193 - </Constraints>
94.194 - </Component>
94.195 - <Component class="javax.swing.JComboBox" name="annotationArgsCombo">
94.196 - <Properties>
94.197 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.198 - <StringArray count="4">
94.199 - <StringItem index="0" value="Item 1"/>
94.200 - <StringItem index="1" value="Item 2"/>
94.201 - <StringItem index="2" value="Item 3"/>
94.202 - <StringItem index="3" value="Item 4"/>
94.203 - </StringArray>
94.204 - </Property>
94.205 - </Properties>
94.206 - <Constraints>
94.207 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.209 - </Constraint>
94.210 - </Constraints>
94.211 - </Component>
94.212 - <Component class="javax.swing.JLabel" name="chainedMethodCallsLabel">
94.213 - <Properties>
94.214 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.215 - <ComponentRef name="chainedMethodCallsCombo"/>
94.216 - </Property>
94.217 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.218 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_chainedMethodCalls" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.219 - </Property>
94.220 - </Properties>
94.221 - <Constraints>
94.222 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.224 - </Constraint>
94.225 - </Constraints>
94.226 - </Component>
94.227 - <Component class="javax.swing.JComboBox" name="chainedMethodCallsCombo">
94.228 - <Properties>
94.229 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.230 - <StringArray count="4">
94.231 - <StringItem index="0" value="Item 1"/>
94.232 - <StringItem index="1" value="Item 2"/>
94.233 - <StringItem index="2" value="Item 3"/>
94.234 - <StringItem index="3" value="Item 4"/>
94.235 - </StringArray>
94.236 - </Property>
94.237 - </Properties>
94.238 - <Constraints>
94.239 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.241 - </Constraint>
94.242 - </Constraints>
94.243 - </Component>
94.244 - <Component class="javax.swing.JLabel" name="throwsKeywordLabel">
94.245 - <Properties>
94.246 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.247 - <ComponentRef name="throwsKeywordCombo"/>
94.248 - </Property>
94.249 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.250 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.251 - </Property>
94.252 - </Properties>
94.253 - <Constraints>
94.254 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.256 - </Constraint>
94.257 - </Constraints>
94.258 - </Component>
94.259 - <Component class="javax.swing.JComboBox" name="throwsKeywordCombo">
94.260 - <Properties>
94.261 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.262 - <StringArray count="4">
94.263 - <StringItem index="0" value="Item 1"/>
94.264 - <StringItem index="1" value="Item 2"/>
94.265 - <StringItem index="2" value="Item 3"/>
94.266 - <StringItem index="3" value="Item 4"/>
94.267 - </StringArray>
94.268 - </Property>
94.269 - </Properties>
94.270 - <Constraints>
94.271 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.273 - </Constraint>
94.274 - </Constraints>
94.275 - </Component>
94.276 - <Component class="javax.swing.JLabel" name="throwsListLabel">
94.277 - <Properties>
94.278 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.279 - <ComponentRef name="throwsListCombo"/>
94.280 - </Property>
94.281 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.282 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.283 - </Property>
94.284 - </Properties>
94.285 - <Constraints>
94.286 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.288 - </Constraint>
94.289 - </Constraints>
94.290 - </Component>
94.291 - <Component class="javax.swing.JComboBox" name="throwsListCombo">
94.292 - <Properties>
94.293 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.294 - <StringArray count="4">
94.295 - <StringItem index="0" value="Item 1"/>
94.296 - <StringItem index="1" value="Item 2"/>
94.297 - <StringItem index="2" value="Item 3"/>
94.298 - <StringItem index="3" value="Item 4"/>
94.299 - </StringArray>
94.300 - </Property>
94.301 - </Properties>
94.302 - <Constraints>
94.303 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.305 - </Constraint>
94.306 - </Constraints>
94.307 - </Component>
94.308 - <Component class="javax.swing.JLabel" name="arrayInitLabel">
94.309 - <Properties>
94.310 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.311 - <ComponentRef name="arrayInitCombo"/>
94.312 - </Property>
94.313 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.314 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_arrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.315 - </Property>
94.316 - </Properties>
94.317 - <Constraints>
94.318 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.320 - </Constraint>
94.321 - </Constraints>
94.322 - </Component>
94.323 - <Component class="javax.swing.JComboBox" name="arrayInitCombo">
94.324 - <Properties>
94.325 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.326 - <StringArray count="4">
94.327 - <StringItem index="0" value="Item 1"/>
94.328 - <StringItem index="1" value="Item 2"/>
94.329 - <StringItem index="2" value="Item 3"/>
94.330 - <StringItem index="3" value="Item 4"/>
94.331 - </StringArray>
94.332 - </Property>
94.333 - </Properties>
94.334 - <Constraints>
94.335 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.337 - </Constraint>
94.338 - </Constraints>
94.339 - </Component>
94.340 - <Component class="javax.swing.JLabel" name="forLabel">
94.341 - <Properties>
94.342 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.343 - <ComponentRef name="forCombo"/>
94.344 - </Property>
94.345 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.346 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_for" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.347 - </Property>
94.348 - </Properties>
94.349 - <Constraints>
94.350 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.352 - </Constraint>
94.353 - </Constraints>
94.354 - </Component>
94.355 - <Component class="javax.swing.JComboBox" name="forCombo">
94.356 - <Properties>
94.357 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.358 - <StringArray count="4">
94.359 - <StringItem index="0" value="Item 1"/>
94.360 - <StringItem index="1" value="Item 2"/>
94.361 - <StringItem index="2" value="Item 3"/>
94.362 - <StringItem index="3" value="Item 4"/>
94.363 - </StringArray>
94.364 - </Property>
94.365 - </Properties>
94.366 - <Constraints>
94.367 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.369 - </Constraint>
94.370 - </Constraints>
94.371 - </Component>
94.372 - <Component class="javax.swing.JLabel" name="forStatementLabel">
94.373 - <Properties>
94.374 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.375 - <ComponentRef name="forStatementCombo"/>
94.376 - </Property>
94.377 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.378 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_forStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.379 - </Property>
94.380 - </Properties>
94.381 - <Constraints>
94.382 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.384 - </Constraint>
94.385 - </Constraints>
94.386 - </Component>
94.387 - <Component class="javax.swing.JComboBox" name="forStatementCombo">
94.388 - <Properties>
94.389 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.390 - <StringArray count="4">
94.391 - <StringItem index="0" value="Item 1"/>
94.392 - <StringItem index="1" value="Item 2"/>
94.393 - <StringItem index="2" value="Item 3"/>
94.394 - <StringItem index="3" value="Item 4"/>
94.395 - </StringArray>
94.396 - </Property>
94.397 - </Properties>
94.398 - <Constraints>
94.399 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.401 - </Constraint>
94.402 - </Constraints>
94.403 - </Component>
94.404 - <Component class="javax.swing.JLabel" name="ifStatementLabel">
94.405 - <Properties>
94.406 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.407 - <ComponentRef name="ifStatementCombo"/>
94.408 - </Property>
94.409 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.410 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ifStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.411 - </Property>
94.412 - </Properties>
94.413 - <Constraints>
94.414 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.416 - </Constraint>
94.417 - </Constraints>
94.418 - </Component>
94.419 - <Component class="javax.swing.JComboBox" name="ifStatementCombo">
94.420 - <Properties>
94.421 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.422 - <StringArray count="4">
94.423 - <StringItem index="0" value="Item 1"/>
94.424 - <StringItem index="1" value="Item 2"/>
94.425 - <StringItem index="2" value="Item 3"/>
94.426 - <StringItem index="3" value="Item 4"/>
94.427 - </StringArray>
94.428 - </Property>
94.429 - </Properties>
94.430 - <Constraints>
94.431 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.433 - </Constraint>
94.434 - </Constraints>
94.435 - </Component>
94.436 - <Component class="javax.swing.JLabel" name="whileStatementLabel">
94.437 - <Properties>
94.438 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.439 - <ComponentRef name="whileStatementComboBox"/>
94.440 - </Property>
94.441 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.442 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_whileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.443 - </Property>
94.444 - </Properties>
94.445 - <Constraints>
94.446 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.448 - </Constraint>
94.449 - </Constraints>
94.450 - </Component>
94.451 - <Component class="javax.swing.JComboBox" name="whileStatementComboBox">
94.452 - <Properties>
94.453 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.454 - <StringArray count="4">
94.455 - <StringItem index="0" value="Item 1"/>
94.456 - <StringItem index="1" value="Item 2"/>
94.457 - <StringItem index="2" value="Item 3"/>
94.458 - <StringItem index="3" value="Item 4"/>
94.459 - </StringArray>
94.460 - </Property>
94.461 - </Properties>
94.462 - <Constraints>
94.463 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.465 - </Constraint>
94.466 - </Constraints>
94.467 - </Component>
94.468 - <Component class="javax.swing.JLabel" name="doWhileStatementLabel">
94.469 - <Properties>
94.470 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.471 - <ComponentRef name="doWhileStatementCombo"/>
94.472 - </Property>
94.473 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.474 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_doWhileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.475 - </Property>
94.476 - </Properties>
94.477 - <Constraints>
94.478 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.480 - </Constraint>
94.481 - </Constraints>
94.482 - </Component>
94.483 - <Component class="javax.swing.JComboBox" name="doWhileStatementCombo">
94.484 - <Properties>
94.485 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.486 - <StringArray count="4">
94.487 - <StringItem index="0" value="Item 1"/>
94.488 - <StringItem index="1" value="Item 2"/>
94.489 - <StringItem index="2" value="Item 3"/>
94.490 - <StringItem index="3" value="Item 4"/>
94.491 - </StringArray>
94.492 - </Property>
94.493 - </Properties>
94.494 - <Constraints>
94.495 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.497 - </Constraint>
94.498 - </Constraints>
94.499 - </Component>
94.500 - <Component class="javax.swing.JLabel" name="assertLabel">
94.501 - <Properties>
94.502 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.503 - <ComponentRef name="assertCombo"/>
94.504 - </Property>
94.505 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.506 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assert" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.507 - </Property>
94.508 - </Properties>
94.509 - <Constraints>
94.510 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.512 - </Constraint>
94.513 - </Constraints>
94.514 - </Component>
94.515 - <Component class="javax.swing.JComboBox" name="assertCombo">
94.516 - <Properties>
94.517 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.518 - <StringArray count="4">
94.519 - <StringItem index="0" value="Item 1"/>
94.520 - <StringItem index="1" value="Item 2"/>
94.521 - <StringItem index="2" value="Item 3"/>
94.522 - <StringItem index="3" value="Item 4"/>
94.523 - </StringArray>
94.524 - </Property>
94.525 - </Properties>
94.526 - <Constraints>
94.527 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.529 - </Constraint>
94.530 - </Constraints>
94.531 - </Component>
94.532 - <Component class="javax.swing.JLabel" name="enumConstantsLabel">
94.533 - <Properties>
94.534 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.535 - <ComponentRef name="enumConstantsCombo"/>
94.536 - </Property>
94.537 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.538 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_enumConstants" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.539 - </Property>
94.540 - </Properties>
94.541 - <Constraints>
94.542 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.544 - </Constraint>
94.545 - </Constraints>
94.546 - </Component>
94.547 - <Component class="javax.swing.JComboBox" name="enumConstantsCombo">
94.548 - <Properties>
94.549 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.550 - <StringArray count="4">
94.551 - <StringItem index="0" value="Item 1"/>
94.552 - <StringItem index="1" value="Item 2"/>
94.553 - <StringItem index="2" value="Item 3"/>
94.554 - <StringItem index="3" value="Item 4"/>
94.555 - </StringArray>
94.556 - </Property>
94.557 - </Properties>
94.558 - <Constraints>
94.559 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.561 - </Constraint>
94.562 - </Constraints>
94.563 - </Component>
94.564 - <Component class="javax.swing.JLabel" name="annotationsLabel">
94.565 - <Properties>
94.566 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.567 - <ComponentRef name="annotationsCombo"/>
94.568 - </Property>
94.569 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.570 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotations" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.571 - </Property>
94.572 - </Properties>
94.573 - <Constraints>
94.574 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.576 - </Constraint>
94.577 - </Constraints>
94.578 - </Component>
94.579 - <Component class="javax.swing.JComboBox" name="annotationsCombo">
94.580 - <Properties>
94.581 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.582 - <StringArray count="4">
94.583 - <StringItem index="0" value="Item 1"/>
94.584 - <StringItem index="1" value="Item 2"/>
94.585 - <StringItem index="2" value="Item 3"/>
94.586 - <StringItem index="3" value="Item 4"/>
94.587 - </StringArray>
94.588 - </Property>
94.589 - </Properties>
94.590 - <Constraints>
94.591 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.593 - </Constraint>
94.594 - </Constraints>
94.595 - </Component>
94.596 - <Component class="javax.swing.JLabel" name="binaryOpsLabel">
94.597 - <Properties>
94.598 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.599 - <ComponentRef name="binaryOpsCombo"/>
94.600 - </Property>
94.601 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.602 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_binaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.603 - </Property>
94.604 - </Properties>
94.605 - <Constraints>
94.606 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.608 - </Constraint>
94.609 - </Constraints>
94.610 - </Component>
94.611 - <Component class="javax.swing.JComboBox" name="binaryOpsCombo">
94.612 - <Properties>
94.613 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.614 - <StringArray count="4">
94.615 - <StringItem index="0" value="Item 1"/>
94.616 - <StringItem index="1" value="Item 2"/>
94.617 - <StringItem index="2" value="Item 3"/>
94.618 - <StringItem index="3" value="Item 4"/>
94.619 - </StringArray>
94.620 - </Property>
94.621 - </Properties>
94.622 - <Constraints>
94.623 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.625 - </Constraint>
94.626 - </Constraints>
94.627 - </Component>
94.628 - <Component class="javax.swing.JLabel" name="ternaryOpsLabel">
94.629 - <Properties>
94.630 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.631 - <ComponentRef name="ternaryOpsCombo"/>
94.632 - </Property>
94.633 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.634 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ternaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.635 - </Property>
94.636 - </Properties>
94.637 - <Constraints>
94.638 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.640 - </Constraint>
94.641 - </Constraints>
94.642 - </Component>
94.643 - <Component class="javax.swing.JComboBox" name="ternaryOpsCombo">
94.644 - <Properties>
94.645 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.646 - <StringArray count="4">
94.647 - <StringItem index="0" value="Item 1"/>
94.648 - <StringItem index="1" value="Item 2"/>
94.649 - <StringItem index="2" value="Item 3"/>
94.650 - <StringItem index="3" value="Item 4"/>
94.651 - </StringArray>
94.652 - </Property>
94.653 - </Properties>
94.654 - <Constraints>
94.655 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.657 - </Constraint>
94.658 - </Constraints>
94.659 - </Component>
94.660 - <Component class="javax.swing.JLabel" name="assignOpsLabel">
94.661 - <Properties>
94.662 - <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
94.663 - <ComponentRef name="assignOpsCombo"/>
94.664 - </Property>
94.665 - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
94.666 - <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assignOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
94.667 - </Property>
94.668 - </Properties>
94.669 - <Constraints>
94.670 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.672 - </Constraint>
94.673 - </Constraints>
94.674 - </Component>
94.675 - <Component class="javax.swing.JComboBox" name="assignOpsCombo">
94.676 - <Properties>
94.677 - <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
94.678 - <StringArray count="4">
94.679 - <StringItem index="0" value="Item 1"/>
94.680 - <StringItem index="1" value="Item 2"/>
94.681 - <StringItem index="2" value="Item 3"/>
94.682 - <StringItem index="3" value="Item 4"/>
94.683 - </StringArray>
94.684 - </Property>
94.685 - </Properties>
94.686 - <Constraints>
94.687 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.689 - </Constraint>
94.690 - </Constraints>
94.691 - </Component>
94.692 - <Container class="javax.swing.JPanel" name="spacerPanel1">
94.693 - <Properties>
94.694 - <Property name="opaque" type="boolean" value="false"/>
94.695 - </Properties>
94.696 - <Constraints>
94.697 - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
94.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"/>
94.699 - </Constraint>
94.700 - </Constraints>
94.701 -
94.702 - <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
94.703 - </Container>
94.704 - </SubComponents>
94.705 - </Container>
94.706 - </SubComponents>
94.707 - </Container>
94.708 - </SubComponents>
94.709 -</Form>
95.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/FmtWrapping.java Mon Aug 31 12:40:19 2015 +0200
95.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
95.3 @@ -1,505 +0,0 @@
95.4 -/*
95.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
95.6 - *
95.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
95.8 - *
95.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
95.10 - * Other names may be trademarks of their respective owners.
95.11 - *
95.12 - * The contents of this file are subject to the terms of either the GNU
95.13 - * General Public License Version 2 only ("GPL") or the Common
95.14 - * Development and Distribution License("CDDL") (collectively, the
95.15 - * "License"). You may not use this file except in compliance with the
95.16 - * License. You can obtain a copy of the License at
95.17 - * http://www.netbeans.org/cddl-gplv2.html
95.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
95.19 - * specific language governing permissions and limitations under the
95.20 - * License. When distributing the software, include this License Header
95.21 - * Notice in each file and include the License file at
95.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
95.23 - * particular file as subject to the "Classpath" exception as provided
95.24 - * by Oracle in the GPL Version 2 section of the License file that
95.25 - * accompanied this code. If applicable, add the following below the
95.26 - * License Header, with the fields enclosed by brackets [] replaced by
95.27 - * your own identifying information:
95.28 - * "Portions Copyrighted [year] [name of copyright owner]"
95.29 - *
95.30 - * Contributor(s):
95.31 - *
95.32 - * The Original Software is NetBeans. The Initial Developer of the Original
95.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
95.34 - * Microsystems, Inc. All Rights Reserved.
95.35 - *
95.36 - * If you wish your version of this file to be governed by only the CDDL
95.37 - * or only the GPL Version 2, indicate your decision by adding
95.38 - * "[Contributor] elects to include this software in this distribution
95.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
95.40 - * single choice of license, a recipient has the option to distribute
95.41 - * your version of this file under either the CDDL, the GPL Version 2 or
95.42 - * to extend the choice of license to its licensees as provided above.
95.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
95.44 - * Version 2 license, then the option applies only if the new code is
95.45 - * made subject to such option by the copyright holder.
95.46 - */
95.47 -
95.48 -package org.netbeans.modules.python.editor.options;
95.49 -
95.50 -import org.netbeans.modules.python.editor.options.CodeStyle;
95.51 -import static org.netbeans.modules.python.editor.options.FmtOptions.*;
95.52 -import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
95.53 -import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
95.54 -import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
95.55 -
95.56 -
95.57 -/**
95.58 - *
95.59 - * @author phrebejk
95.60 - */
95.61 -public class FmtWrapping extends javax.swing.JPanel {
95.62 -
95.63 - /** Creates new form FmtWrapping */
95.64 - public FmtWrapping() {
95.65 - initComponents();
95.66 -
95.67 - scrollPane.getViewport().setBackground(java.awt.SystemColor.controlLtHighlight);
95.68 -
95.69 -/*
95.70 - extendsImplementsKeywordCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsKeyword);
95.71 - extendsImplementsListCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsList);
95.72 - methodParamsCombo.putClientProperty(OPTION_ID, wrapMethodParams);
95.73 - methodCallArgsCombo.putClientProperty(OPTION_ID, wrapMethodCallArgs);
95.74 - annotationArgsCombo.putClientProperty(OPTION_ID, wrapAnnotationArgs);
95.75 - chainedMethodCallsCombo.putClientProperty(OPTION_ID, wrapChainedMethodCalls);
95.76 - throwsKeywordCombo.putClientProperty(OPTION_ID, wrapThrowsKeyword);
95.77 - throwsListCombo.putClientProperty(OPTION_ID, wrapThrowsList);
95.78 - arrayInitCombo.putClientProperty(OPTION_ID, wrapArrayInit);
95.79 - forCombo.putClientProperty(OPTION_ID, wrapFor);
95.80 - forStatementCombo.putClientProperty(OPTION_ID, wrapForStatement );
95.81 - ifStatementCombo.putClientProperty(OPTION_ID, wrapIfStatement);
95.82 - whileStatementComboBox.putClientProperty(OPTION_ID, wrapWhileStatement);
95.83 - doWhileStatementCombo.putClientProperty(OPTION_ID, wrapDoWhileStatement);
95.84 - assertCombo.putClientProperty(OPTION_ID, wrapAssert);
95.85 - enumConstantsCombo.putClientProperty(OPTION_ID, wrapEnumConstants);
95.86 - annotationsCombo.putClientProperty(OPTION_ID, wrapAnnotations);
95.87 - binaryOpsCombo.putClientProperty(OPTION_ID, wrapBinaryOps);
95.88 - ternaryOpsCombo.putClientProperty(OPTION_ID, wrapTernaryOps);
95.89 - assignOpsCombo.putClientProperty(OPTION_ID, wrapAssignOps);
95.90 - }
95.91 -
95.92 - public static PreferencesCustomizer.Factory getController() {
95.93 - return new CategorySupport.Factory("wrapping", FmtWrapping.class, //NOI18N
95.94 - org.openide.util.NbBundle.getMessage(FmtWrapping.class, "SAMPLE_Wrapping"), //NOI18N
95.95 - new String[] { FmtOptions.rightMargin, "30" } //NOI18N
95.96 -// new String[] { FmtOptions.redundantDoWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
95.97 -// new String[] { FmtOptions.redundantForBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
95.98 -// new String[] { FmtOptions.redundantIfBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
95.99 -// new String[] { FmtOptions.redundantWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() }
95.100 - ); // NOI18N
95.101 - */
95.102 - }
95.103 -
95.104 - /** This method is called from within the constructor to
95.105 - * initialize the form.
95.106 - * WARNING: Do NOT modify this code. The content of this method is
95.107 - * always regenerated by the Form Editor.
95.108 - */
95.109 - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
95.110 - private void initComponents() {
95.111 - java.awt.GridBagConstraints gridBagConstraints;
95.112 -
95.113 - scrollPane = new javax.swing.JScrollPane();
95.114 - panel1 = new javax.swing.JPanel();
95.115 - extendsImplemetsKeywordLabel = new javax.swing.JLabel();
95.116 - extendsImplementsKeywordCombo = new javax.swing.JComboBox();
95.117 - extendsImplementsListLabel = new javax.swing.JLabel();
95.118 - extendsImplementsListCombo = new javax.swing.JComboBox();
95.119 - methodParamsLabel = new javax.swing.JLabel();
95.120 - methodParamsCombo = new javax.swing.JComboBox();
95.121 - methodCallArgsLabel = new javax.swing.JLabel();
95.122 - methodCallArgsCombo = new javax.swing.JComboBox();
95.123 - annotationArgsLabel = new javax.swing.JLabel();
95.124 - annotationArgsCombo = new javax.swing.JComboBox();
95.125 - chainedMethodCallsLabel = new javax.swing.JLabel();
95.126 - chainedMethodCallsCombo = new javax.swing.JComboBox();
95.127 - throwsKeywordLabel = new javax.swing.JLabel();
95.128 - throwsKeywordCombo = new javax.swing.JComboBox();
95.129 - throwsListLabel = new javax.swing.JLabel();
95.130 - throwsListCombo = new javax.swing.JComboBox();
95.131 - arrayInitLabel = new javax.swing.JLabel();
95.132 - arrayInitCombo = new javax.swing.JComboBox();
95.133 - forLabel = new javax.swing.JLabel();
95.134 - forCombo = new javax.swing.JComboBox();
95.135 - forStatementLabel = new javax.swing.JLabel();
95.136 - forStatementCombo = new javax.swing.JComboBox();
95.137 - ifStatementLabel = new javax.swing.JLabel();
95.138 - ifStatementCombo = new javax.swing.JComboBox();
95.139 - whileStatementLabel = new javax.swing.JLabel();
95.140 - whileStatementComboBox = new javax.swing.JComboBox();
95.141 - doWhileStatementLabel = new javax.swing.JLabel();
95.142 - doWhileStatementCombo = new javax.swing.JComboBox();
95.143 - assertLabel = new javax.swing.JLabel();
95.144 - assertCombo = new javax.swing.JComboBox();
95.145 - enumConstantsLabel = new javax.swing.JLabel();
95.146 - enumConstantsCombo = new javax.swing.JComboBox();
95.147 - annotationsLabel = new javax.swing.JLabel();
95.148 - annotationsCombo = new javax.swing.JComboBox();
95.149 - binaryOpsLabel = new javax.swing.JLabel();
95.150 - binaryOpsCombo = new javax.swing.JComboBox();
95.151 - ternaryOpsLabel = new javax.swing.JLabel();
95.152 - ternaryOpsCombo = new javax.swing.JComboBox();
95.153 - assignOpsLabel = new javax.swing.JLabel();
95.154 - assignOpsCombo = new javax.swing.JComboBox();
95.155 - spacerPanel1 = new javax.swing.JPanel();
95.156 -
95.157 - setName(org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_Wrapping")); // NOI18N
95.158 - setOpaque(false);
95.159 - setLayout(new java.awt.BorderLayout());
95.160 -
95.161 - scrollPane.setMinimumSize(new java.awt.Dimension(300, 200));
95.162 - scrollPane.setPreferredSize(new java.awt.Dimension(350, 600));
95.163 -
95.164 - panel1.setOpaque(false);
95.165 - panel1.setLayout(new java.awt.GridBagLayout());
95.166 -
95.167 - extendsImplemetsKeywordLabel.setLabelFor(extendsImplementsKeywordCombo);
95.168 - org.openide.awt.Mnemonics.setLocalizedText(extendsImplemetsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsKeyword")); // NOI18N
95.169 - gridBagConstraints = new java.awt.GridBagConstraints();
95.170 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.171 - gridBagConstraints.insets = new java.awt.Insets(8, 8, 4, 0);
95.172 - panel1.add(extendsImplemetsKeywordLabel, gridBagConstraints);
95.173 -
95.174 - extendsImplementsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.175 - gridBagConstraints = new java.awt.GridBagConstraints();
95.176 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.177 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.178 - gridBagConstraints.weightx = 1.0;
95.179 - gridBagConstraints.insets = new java.awt.Insets(8, 6, 4, 8);
95.180 - panel1.add(extendsImplementsKeywordCombo, gridBagConstraints);
95.181 -
95.182 - extendsImplementsListLabel.setLabelFor(extendsImplementsListCombo);
95.183 - org.openide.awt.Mnemonics.setLocalizedText(extendsImplementsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsList")); // NOI18N
95.184 - gridBagConstraints = new java.awt.GridBagConstraints();
95.185 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.186 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.187 - panel1.add(extendsImplementsListLabel, gridBagConstraints);
95.188 -
95.189 - extendsImplementsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.190 - gridBagConstraints = new java.awt.GridBagConstraints();
95.191 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.192 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.193 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.194 - panel1.add(extendsImplementsListCombo, gridBagConstraints);
95.195 -
95.196 - methodParamsLabel.setLabelFor(methodParamsCombo);
95.197 - org.openide.awt.Mnemonics.setLocalizedText(methodParamsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodParameters")); // NOI18N
95.198 - gridBagConstraints = new java.awt.GridBagConstraints();
95.199 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.200 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.201 - panel1.add(methodParamsLabel, gridBagConstraints);
95.202 -
95.203 - methodParamsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.204 - gridBagConstraints = new java.awt.GridBagConstraints();
95.205 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.206 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.207 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.208 - panel1.add(methodParamsCombo, gridBagConstraints);
95.209 -
95.210 - methodCallArgsLabel.setLabelFor(methodCallArgsCombo);
95.211 - org.openide.awt.Mnemonics.setLocalizedText(methodCallArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodCallArgs")); // NOI18N
95.212 - gridBagConstraints = new java.awt.GridBagConstraints();
95.213 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.214 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.215 - panel1.add(methodCallArgsLabel, gridBagConstraints);
95.216 -
95.217 - methodCallArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.218 - gridBagConstraints = new java.awt.GridBagConstraints();
95.219 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.220 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.221 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.222 - panel1.add(methodCallArgsCombo, gridBagConstraints);
95.223 -
95.224 - annotationArgsLabel.setLabelFor(annotationArgsCombo);
95.225 - org.openide.awt.Mnemonics.setLocalizedText(annotationArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotationArgs")); // NOI18N
95.226 - gridBagConstraints = new java.awt.GridBagConstraints();
95.227 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.228 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.229 - panel1.add(annotationArgsLabel, gridBagConstraints);
95.230 -
95.231 - annotationArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.232 - gridBagConstraints = new java.awt.GridBagConstraints();
95.233 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.234 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.235 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.236 - panel1.add(annotationArgsCombo, gridBagConstraints);
95.237 -
95.238 - chainedMethodCallsLabel.setLabelFor(chainedMethodCallsCombo);
95.239 - org.openide.awt.Mnemonics.setLocalizedText(chainedMethodCallsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_chainedMethodCalls")); // NOI18N
95.240 - gridBagConstraints = new java.awt.GridBagConstraints();
95.241 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.242 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.243 - panel1.add(chainedMethodCallsLabel, gridBagConstraints);
95.244 -
95.245 - chainedMethodCallsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.246 - gridBagConstraints = new java.awt.GridBagConstraints();
95.247 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.248 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.249 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.250 - panel1.add(chainedMethodCallsCombo, gridBagConstraints);
95.251 -
95.252 - throwsKeywordLabel.setLabelFor(throwsKeywordCombo);
95.253 - org.openide.awt.Mnemonics.setLocalizedText(throwsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsKeyword")); // NOI18N
95.254 - gridBagConstraints = new java.awt.GridBagConstraints();
95.255 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.256 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.257 - panel1.add(throwsKeywordLabel, gridBagConstraints);
95.258 -
95.259 - throwsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.260 - gridBagConstraints = new java.awt.GridBagConstraints();
95.261 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.262 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.263 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.264 - panel1.add(throwsKeywordCombo, gridBagConstraints);
95.265 -
95.266 - throwsListLabel.setLabelFor(throwsListCombo);
95.267 - org.openide.awt.Mnemonics.setLocalizedText(throwsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsList")); // NOI18N
95.268 - gridBagConstraints = new java.awt.GridBagConstraints();
95.269 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.270 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.271 - panel1.add(throwsListLabel, gridBagConstraints);
95.272 -
95.273 - throwsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.274 - gridBagConstraints = new java.awt.GridBagConstraints();
95.275 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.276 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.277 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.278 - panel1.add(throwsListCombo, gridBagConstraints);
95.279 -
95.280 - arrayInitLabel.setLabelFor(arrayInitCombo);
95.281 - org.openide.awt.Mnemonics.setLocalizedText(arrayInitLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_arrayInit")); // NOI18N
95.282 - gridBagConstraints = new java.awt.GridBagConstraints();
95.283 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.284 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.285 - panel1.add(arrayInitLabel, gridBagConstraints);
95.286 -
95.287 - arrayInitCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.288 - gridBagConstraints = new java.awt.GridBagConstraints();
95.289 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.290 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.291 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.292 - panel1.add(arrayInitCombo, gridBagConstraints);
95.293 -
95.294 - forLabel.setLabelFor(forCombo);
95.295 - org.openide.awt.Mnemonics.setLocalizedText(forLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_for")); // NOI18N
95.296 - gridBagConstraints = new java.awt.GridBagConstraints();
95.297 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.298 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.299 - panel1.add(forLabel, gridBagConstraints);
95.300 -
95.301 - forCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.302 - gridBagConstraints = new java.awt.GridBagConstraints();
95.303 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.304 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.305 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.306 - panel1.add(forCombo, gridBagConstraints);
95.307 -
95.308 - forStatementLabel.setLabelFor(forStatementCombo);
95.309 - org.openide.awt.Mnemonics.setLocalizedText(forStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_forStatement")); // NOI18N
95.310 - gridBagConstraints = new java.awt.GridBagConstraints();
95.311 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.312 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.313 - panel1.add(forStatementLabel, gridBagConstraints);
95.314 -
95.315 - forStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.316 - gridBagConstraints = new java.awt.GridBagConstraints();
95.317 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.318 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.319 - gridBagConstraints.weightx = 1.0;
95.320 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.321 - panel1.add(forStatementCombo, gridBagConstraints);
95.322 -
95.323 - ifStatementLabel.setLabelFor(ifStatementCombo);
95.324 - org.openide.awt.Mnemonics.setLocalizedText(ifStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ifStatement")); // NOI18N
95.325 - gridBagConstraints = new java.awt.GridBagConstraints();
95.326 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.327 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.328 - panel1.add(ifStatementLabel, gridBagConstraints);
95.329 -
95.330 - ifStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.331 - gridBagConstraints = new java.awt.GridBagConstraints();
95.332 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.333 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.334 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.335 - panel1.add(ifStatementCombo, gridBagConstraints);
95.336 -
95.337 - whileStatementLabel.setLabelFor(whileStatementComboBox);
95.338 - org.openide.awt.Mnemonics.setLocalizedText(whileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_whileStatement")); // NOI18N
95.339 - gridBagConstraints = new java.awt.GridBagConstraints();
95.340 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.341 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.342 - panel1.add(whileStatementLabel, gridBagConstraints);
95.343 -
95.344 - whileStatementComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.345 - gridBagConstraints = new java.awt.GridBagConstraints();
95.346 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.347 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.348 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.349 - panel1.add(whileStatementComboBox, gridBagConstraints);
95.350 -
95.351 - doWhileStatementLabel.setLabelFor(doWhileStatementCombo);
95.352 - org.openide.awt.Mnemonics.setLocalizedText(doWhileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_doWhileStatement")); // NOI18N
95.353 - gridBagConstraints = new java.awt.GridBagConstraints();
95.354 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.355 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.356 - panel1.add(doWhileStatementLabel, gridBagConstraints);
95.357 -
95.358 - doWhileStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.359 - gridBagConstraints = new java.awt.GridBagConstraints();
95.360 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.361 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.362 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.363 - panel1.add(doWhileStatementCombo, gridBagConstraints);
95.364 -
95.365 - assertLabel.setLabelFor(assertCombo);
95.366 - org.openide.awt.Mnemonics.setLocalizedText(assertLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assert")); // NOI18N
95.367 - gridBagConstraints = new java.awt.GridBagConstraints();
95.368 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.369 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.370 - panel1.add(assertLabel, gridBagConstraints);
95.371 -
95.372 - assertCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.373 - gridBagConstraints = new java.awt.GridBagConstraints();
95.374 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.375 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.376 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.377 - panel1.add(assertCombo, gridBagConstraints);
95.378 -
95.379 - enumConstantsLabel.setLabelFor(enumConstantsCombo);
95.380 - org.openide.awt.Mnemonics.setLocalizedText(enumConstantsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_enumConstants")); // NOI18N
95.381 - gridBagConstraints = new java.awt.GridBagConstraints();
95.382 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.383 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.384 - panel1.add(enumConstantsLabel, gridBagConstraints);
95.385 -
95.386 - enumConstantsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.387 - gridBagConstraints = new java.awt.GridBagConstraints();
95.388 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.389 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.390 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.391 - panel1.add(enumConstantsCombo, gridBagConstraints);
95.392 -
95.393 - annotationsLabel.setLabelFor(annotationsCombo);
95.394 - org.openide.awt.Mnemonics.setLocalizedText(annotationsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotations")); // NOI18N
95.395 - gridBagConstraints = new java.awt.GridBagConstraints();
95.396 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.397 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.398 - panel1.add(annotationsLabel, gridBagConstraints);
95.399 -
95.400 - annotationsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.401 - gridBagConstraints = new java.awt.GridBagConstraints();
95.402 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.403 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.404 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.405 - panel1.add(annotationsCombo, gridBagConstraints);
95.406 -
95.407 - binaryOpsLabel.setLabelFor(binaryOpsCombo);
95.408 - org.openide.awt.Mnemonics.setLocalizedText(binaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_binaryOps")); // NOI18N
95.409 - gridBagConstraints = new java.awt.GridBagConstraints();
95.410 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.411 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.412 - panel1.add(binaryOpsLabel, gridBagConstraints);
95.413 -
95.414 - binaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.415 - gridBagConstraints = new java.awt.GridBagConstraints();
95.416 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.417 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.418 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.419 - panel1.add(binaryOpsCombo, gridBagConstraints);
95.420 -
95.421 - ternaryOpsLabel.setLabelFor(ternaryOpsCombo);
95.422 - org.openide.awt.Mnemonics.setLocalizedText(ternaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ternaryOps")); // NOI18N
95.423 - gridBagConstraints = new java.awt.GridBagConstraints();
95.424 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.425 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.426 - panel1.add(ternaryOpsLabel, gridBagConstraints);
95.427 -
95.428 - ternaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.429 - gridBagConstraints = new java.awt.GridBagConstraints();
95.430 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.431 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.432 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.433 - panel1.add(ternaryOpsCombo, gridBagConstraints);
95.434 -
95.435 - assignOpsLabel.setLabelFor(assignOpsCombo);
95.436 - org.openide.awt.Mnemonics.setLocalizedText(assignOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assignOps")); // NOI18N
95.437 - gridBagConstraints = new java.awt.GridBagConstraints();
95.438 - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
95.439 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
95.440 - panel1.add(assignOpsLabel, gridBagConstraints);
95.441 -
95.442 - assignOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
95.443 - gridBagConstraints = new java.awt.GridBagConstraints();
95.444 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.445 - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
95.446 - gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
95.447 - panel1.add(assignOpsCombo, gridBagConstraints);
95.448 -
95.449 - spacerPanel1.setOpaque(false);
95.450 - gridBagConstraints = new java.awt.GridBagConstraints();
95.451 - gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
95.452 - gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
95.453 - gridBagConstraints.weighty = 1.0;
95.454 - gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 8);
95.455 - panel1.add(spacerPanel1, gridBagConstraints);
95.456 -
95.457 - scrollPane.setViewportView(panel1);
95.458 -
95.459 - add(scrollPane, java.awt.BorderLayout.CENTER);
95.460 - }// </editor-fold>//GEN-END:initComponents
95.461 -
95.462 - // Variables declaration - do not modify//GEN-BEGIN:variables
95.463 - private javax.swing.JComboBox annotationArgsCombo;
95.464 - private javax.swing.JLabel annotationArgsLabel;
95.465 - private javax.swing.JComboBox annotationsCombo;
95.466 - private javax.swing.JLabel annotationsLabel;
95.467 - private javax.swing.JComboBox arrayInitCombo;
95.468 - private javax.swing.JLabel arrayInitLabel;
95.469 - private javax.swing.JComboBox assertCombo;
95.470 - private javax.swing.JLabel assertLabel;
95.471 - private javax.swing.JComboBox assignOpsCombo;
95.472 - private javax.swing.JLabel assignOpsLabel;
95.473 - private javax.swing.JComboBox binaryOpsCombo;
95.474 - private javax.swing.JLabel binaryOpsLabel;
95.475 - private javax.swing.JComboBox chainedMethodCallsCombo;
95.476 - private javax.swing.JLabel chainedMethodCallsLabel;
95.477 - private javax.swing.JComboBox doWhileStatementCombo;
95.478 - private javax.swing.JLabel doWhileStatementLabel;
95.479 - private javax.swing.JComboBox enumConstantsCombo;
95.480 - private javax.swing.JLabel enumConstantsLabel;
95.481 - private javax.swing.JComboBox extendsImplementsKeywordCombo;
95.482 - private javax.swing.JComboBox extendsImplementsListCombo;
95.483 - private javax.swing.JLabel extendsImplementsListLabel;
95.484 - private javax.swing.JLabel extendsImplemetsKeywordLabel;
95.485 - private javax.swing.JComboBox forCombo;
95.486 - private javax.swing.JLabel forLabel;
95.487 - private javax.swing.JComboBox forStatementCombo;
95.488 - private javax.swing.JLabel forStatementLabel;
95.489 - private javax.swing.JComboBox ifStatementCombo;
95.490 - private javax.swing.JLabel ifStatementLabel;
95.491 - private javax.swing.JComboBox methodCallArgsCombo;
95.492 - private javax.swing.JLabel methodCallArgsLabel;
95.493 - private javax.swing.JComboBox methodParamsCombo;
95.494 - private javax.swing.JLabel methodParamsLabel;
95.495 - private javax.swing.JPanel panel1;
95.496 - private javax.swing.JScrollPane scrollPane;
95.497 - private javax.swing.JPanel spacerPanel1;
95.498 - private javax.swing.JComboBox ternaryOpsCombo;
95.499 - private javax.swing.JLabel ternaryOpsLabel;
95.500 - private javax.swing.JComboBox throwsKeywordCombo;
95.501 - private javax.swing.JLabel throwsKeywordLabel;
95.502 - private javax.swing.JComboBox throwsListCombo;
95.503 - private javax.swing.JLabel throwsListLabel;
95.504 - private javax.swing.JComboBox whileStatementComboBox;
95.505 - private javax.swing.JLabel whileStatementLabel;
95.506 - // End of variables declaration//GEN-END:variables
95.507 -
95.508 -}
96.1 --- a/python.editor/src/org/netbeans/modules/python/editor/options/NumericKeyListener.java Mon Aug 31 12:40:19 2015 +0200
96.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
96.3 @@ -1,74 +0,0 @@
96.4 -/*
96.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
96.6 - *
96.7 - * Copyright 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 - * If you wish your version of this file to be governed by only the CDDL
96.31 - * or only the GPL Version 2, indicate your decision by adding
96.32 - * "[Contributor] elects to include this software in this distribution
96.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
96.34 - * single choice of license, a recipient has the option to distribute
96.35 - * your version of this file under either the CDDL, the GPL Version 2 or
96.36 - * to extend the choice of license to its licensees as provided above.
96.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
96.38 - * Version 2 license, then the option applies only if the new code is
96.39 - * made subject to such option by the copyright holder.
96.40 - *
96.41 - * Contributor(s):
96.42 - *
96.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
96.44 - */
96.45 -package org.netbeans.modules.python.editor.options;
96.46 -
96.47 -import java.awt.Component;
96.48 -import java.awt.event.KeyEvent;
96.49 -import java.awt.event.KeyListener;
96.50 -
96.51 -/**
96.52 - *
96.53 - * @author tester
96.54 - */
96.55 -public class NumericKeyListener implements KeyListener {
96.56 - public NumericKeyListener() {
96.57 - }
96.58 -
96.59 - @Override
96.60 - public void keyPressed(KeyEvent evt) {
96.61 - }
96.62 -
96.63 - @Override
96.64 - public void keyReleased(KeyEvent evt) {
96.65 - }
96.66 -
96.67 - @Override
96.68 - public void keyTyped(KeyEvent evt) {
96.69 - if (!Character.isDigit(evt.getKeyChar()) && !Character.isISOControl(evt.getKeyChar())) {
96.70 - evt.consume();
96.71 - Component c = evt.getComponent();
96.72 - if (c != null) {
96.73 - c.getToolkit().beep();
96.74 - }
96.75 - }
96.76 - }
96.77 -}
97.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonElementCtx.java Mon Aug 31 12:40:19 2015 +0200
97.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonElementCtx.java Wed Sep 02 20:31:18 2015 +0200
97.3 @@ -32,15 +32,15 @@
97.4
97.5 import java.util.Iterator;
97.6
97.7 -import org.netbeans.modules.python.editor.elements.AstElement;
97.8 -import org.netbeans.modules.python.editor.elements.Element;
97.9 +import org.netbeans.modules.python.source.elements.AstElement;
97.10 +import org.netbeans.modules.python.source.elements.Element;
97.11 import org.netbeans.editor.BaseDocument;
97.12 import org.netbeans.modules.csl.api.ElementKind;
97.13 import org.netbeans.modules.csl.spi.GsfUtilities;
97.14 -import org.netbeans.modules.python.editor.AstPath;
97.15 -import org.netbeans.modules.python.editor.PythonAstUtils;
97.16 -import org.netbeans.modules.python.editor.PythonParserResult;
97.17 -import org.netbeans.modules.python.editor.elements.IndexedElement;
97.18 +import org.netbeans.modules.python.source.AstPath;
97.19 +import org.netbeans.modules.python.source.PythonAstUtils;
97.20 +import org.netbeans.modules.python.source.PythonParserResult;
97.21 +import org.netbeans.modules.python.source.elements.IndexedElement;
97.22 import org.openide.filesystems.FileObject;
97.23 import org.python.antlr.PythonTree;
97.24 import org.python.antlr.ast.Assign;
98.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefUtils.java Mon Aug 31 12:40:19 2015 +0200
98.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefUtils.java Wed Sep 02 20:31:18 2015 +0200
98.3 @@ -72,10 +72,10 @@
98.4 import org.netbeans.modules.csl.api.ElementKind;
98.5 import org.netbeans.modules.parsing.api.Source;
98.6 import org.netbeans.modules.python.api.PythonMIMEResolver;
98.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
98.8 -import org.netbeans.modules.python.editor.PythonParserResult;
98.9 -import org.netbeans.modules.python.editor.PythonUtils;
98.10 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
98.11 +import org.netbeans.modules.python.source.PythonAstUtils;
98.12 +import org.netbeans.modules.python.source.PythonParserResult;
98.13 +import org.netbeans.modules.python.source.PythonUtils;
98.14 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
98.15 import org.openide.cookies.EditorCookie;
98.16 import org.openide.filesystems.FileObject;
98.17 import org.openide.util.Lookup;
99.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefactoringsFactory.java Mon Aug 31 12:40:19 2015 +0200
99.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/PythonRefactoringsFactory.java Wed Sep 02 20:31:18 2015 +0200
99.3 @@ -43,7 +43,7 @@
99.4 */
99.5 package org.netbeans.modules.python.editor.refactoring;
99.6
99.7 -import org.netbeans.modules.python.editor.PythonUtils;
99.8 +import org.netbeans.modules.python.source.PythonUtils;
99.9 import org.netbeans.modules.refactoring.api.AbstractRefactoring;
99.10 import org.netbeans.modules.refactoring.api.RenameRefactoring;
99.11 import org.netbeans.modules.refactoring.api.WhereUsedQuery;
100.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/WhereUsedElement.java Mon Aug 31 12:40:19 2015 +0200
100.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/WhereUsedElement.java Wed Sep 02 20:31:18 2015 +0200
100.3 @@ -54,9 +54,9 @@
100.4 import org.netbeans.modules.csl.api.OffsetRange;
100.5 import org.netbeans.modules.csl.api.UiUtils;
100.6 import org.netbeans.modules.csl.spi.GsfUtilities;
100.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
100.8 -import org.netbeans.modules.python.editor.PythonParserResult;
100.9 -import org.netbeans.modules.python.editor.lexer.PythonLexerUtils;
100.10 +import org.netbeans.modules.python.source.PythonAstUtils;
100.11 +import org.netbeans.modules.python.source.PythonParserResult;
100.12 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
100.13 import org.netbeans.modules.python.editor.refactoring.ui.ElementGripFactory;
100.14 import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
100.15 import org.openide.filesystems.FileObject;
101.1 --- a/python.editor/src/org/netbeans/modules/python/editor/refactoring/ui/RefactoringActionsProvider.java Mon Aug 31 12:40:19 2015 +0200
101.2 +++ b/python.editor/src/org/netbeans/modules/python/editor/refactoring/ui/RefactoringActionsProvider.java Wed Sep 02 20:31:18 2015 +0200
101.3 @@ -64,14 +64,14 @@
101.4 import org.netbeans.modules.refactoring.spi.ui.UI;
101.5 import org.netbeans.modules.refactoring.spi.ui.ActionsImplementationProvider;
101.6 import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
101.7 -import org.netbeans.modules.python.editor.PythonAstUtils;
101.8 -import org.netbeans.modules.python.editor.PythonIndex;
101.9 -import org.netbeans.modules.python.editor.PythonParserResult;
101.10 -import org.netbeans.modules.python.editor.PythonStructureScanner;
101.11 -import org.netbeans.modules.python.editor.PythonStructureScanner.AnalysisResult;
101.12 -import org.netbeans.modules.python.editor.PythonUtils;
101.13 -import org.netbeans.modules.python.editor.elements.AstElement;
101.14 -import org.netbeans.modules.python.editor.elements.Element;
101.15 +import org.netbeans.modules.python.source.PythonAstUtils;
101.16 +import org.netbeans.modules.python.source.PythonIndex;
101.17 +import org.netbeans.modules.python.source.PythonParserResult;
101.18 +import org.netbeans.modules.python.source.PythonStructureScanner;
101.19 +import org.netbeans.modules.python.source.PythonStructureScanner.AnalysisResult;
101.20 +import org.netbeans.modules.python.source.PythonUtils;
101.21 +import org.netbeans.modules.python.source.elements.AstElement;
101.22 +import org.netbeans.modules.python.source.elements.Element;
101.23 import org.openide.ErrorManager;
101.24 import org.openide.cookies.EditorCookie;
101.25 import org.openide.filesystems.FileObject;
102.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ArgListCompiler.java Mon Aug 31 12:40:19 2015 +0200
102.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
102.3 @@ -1,121 +0,0 @@
102.4 -// Copyright (c) Corporation for National Research Initiatives
102.5 -package org.netbeans.modules.python.editor.scopes;
102.6 -
102.7 -import java.util.ArrayList;
102.8 -
102.9 -import java.util.List;
102.10 -import org.python.antlr.PythonTree;
102.11 -import org.python.antlr.Visitor;
102.12 -import org.python.antlr.ast.Assign;
102.13 -import org.python.antlr.ast.Name;
102.14 -import org.python.antlr.ast.Suite;
102.15 -import org.python.antlr.ast.Tuple;
102.16 -import org.python.antlr.ast.arguments;
102.17 -import org.python.antlr.ast.expr_contextType;
102.18 -import org.python.antlr.base.expr;
102.19 -import org.python.antlr.base.stmt;
102.20 -
102.21 -/** Based on org.python.compiler.ArgListCompiler */
102.22 -public class ArgListCompiler extends Visitor {
102.23 - public boolean arglist, keywordlist;
102.24 - public List<expr> defaults;
102.25 - public List<String> names;
102.26 - public ArrayList<PythonTree> nodes;
102.27 - public List<String> fpnames;
102.28 - public List<stmt> init_code;
102.29 - private SymbolTable symbolTable;
102.30 -
102.31 - public ArgListCompiler(SymbolTable symbolTable) {
102.32 - this.symbolTable = symbolTable;
102.33 - arglist = keywordlist = false;
102.34 - defaults = null;
102.35 - names = new ArrayList<>();
102.36 - nodes = new ArrayList<>();
102.37 - fpnames = new ArrayList<>();
102.38 - init_code = new ArrayList<>();
102.39 - }
102.40 -
102.41 - public void reset() {
102.42 - arglist = keywordlist = false;
102.43 - defaults = null;
102.44 - names.clear();
102.45 - nodes.clear();
102.46 - init_code.clear();
102.47 - }
102.48 -
102.49 - public void appendInitCode(Suite node) {
102.50 - node.getInternalBody().addAll(0, init_code);
102.51 - }
102.52 -
102.53 - public List<expr> getDefaults() {
102.54 - return defaults;
102.55 - }
102.56 -
102.57 - public void visitArgs(arguments args) throws Exception {
102.58 - for (int i = 0; i < args.getInternalArgs().size(); i++) {
102.59 - expr node = args.getInternalArgs().get(i);
102.60 - String name = (String)visit(node);
102.61 - names.add(name);
102.62 - nodes.add(node);
102.63 - if (node instanceof Tuple) {
102.64 - List<expr> targets = new ArrayList<>();
102.65 - targets.add(node);
102.66 - Assign ass = new Assign(node,
102.67 - targets,
102.68 - new Name(node, name, expr_contextType.Load));
102.69 - init_code.add(ass);
102.70 - }
102.71 - }
102.72 - if (args.getInternalVararg() != null) {
102.73 - arglist = true;
102.74 - names.add(args.getInternalVararg());
102.75 - //nodes.add(null); // no corresponding node?
102.76 - nodes.add(args); // just use the corresponding args node instead
102.77 - }
102.78 - if (args.getInternalKwarg() != null) {
102.79 - keywordlist = true;
102.80 - names.add(args.getInternalKwarg());
102.81 - //nodes.add(null); // no corresponding node?
102.82 - nodes.add(args); // just use the corresponding args node instead
102.83 - }
102.84 -
102.85 - defaults = args.getInternalDefaults();
102.86 - for (int i = 0; i < defaults.size(); i++) {
102.87 - if (defaults.get(i) == null) {
102.88 - symbolTable.error("non-default argument follows default argument", true,
102.89 - args.getInternalArgs().get(args.getInternalArgs().size() - defaults.size() + i));
102.90 - }
102.91 - }
102.92 - }
102.93 -
102.94 - @Override
102.95 - public Object visitName(Name node) throws Exception {
102.96 - //FIXME: do we need Store and Param, or just Param?
102.97 - if (node.getInternalCtx() != expr_contextType.Store && node.getInternalCtx() != expr_contextType.Param) {
102.98 - return null;
102.99 - }
102.100 -
102.101 - if (fpnames.contains(node.getInternalId())) {
102.102 - symbolTable.error("duplicate argument name found: " +
102.103 - node.getInternalId(), true, node);
102.104 - }
102.105 - fpnames.add(node.getInternalId());
102.106 - return node.getInternalId();
102.107 - }
102.108 -
102.109 - @Override
102.110 - public Object visitTuple(Tuple node) throws Exception {
102.111 - StringBuffer name = new StringBuffer("(");
102.112 - List<expr> elts = node.getInternalElts();
102.113 - if (elts != null) {
102.114 - int n = elts.size();
102.115 - for (int i = 0; i < n - 1; i++) {
102.116 - name.append(visit(elts.get(i)));
102.117 - name.append(", ");
102.118 - }
102.119 - name.append(visit(elts.get(n - 1)));
102.120 - }
102.121 - name.append(")");
102.122 - return name.toString();
102.123 - }
102.124 -}
103.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ScopeConstants.java Mon Aug 31 12:40:19 2015 +0200
103.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
103.3 @@ -1,28 +0,0 @@
103.4 -package org.netbeans.modules.python.editor.scopes;
103.5 -
103.6 -/** Based on org.python.compiler.ScopeConstants in Jython */
103.7 -public interface ScopeConstants {
103.8 - public final static int BOUND = 1 << 0;
103.9 - public final static int NGLOBAL = 1 << 1; // func scope expl global
103.10 - public final static int PARAM = 1 << 2;
103.11 - public final static int FROM_PARAM = 1 << 3;
103.12 - public final static int CELL = 1 << 4;
103.13 - public final static int FREE = 1 << 5;
103.14 - public final static int CLASS_GLOBAL = 1 << 6; // class scope expl global
103.15 - public final static int READ = 1 << 7;
103.16 - public final static int CALLED = 1 << 8;
103.17 - public final static int DEF = 1 << 9;
103.18 - public final static int IMPORTED = 1 << 10;
103.19 - public final static int CLASS = 1 << 11;
103.20 - public final static int FUNCTION = 1 << 12;
103.21 - public final static int MEMBER = 1 << 13;
103.22 - public final static int GENERATOR = 1 << 13; // it's a generator expression
103.23 - public final static int PRIVATE = 1 << 14;
103.24 - public final static int ALIAS = 1 << 15;
103.25 - public final static int PROTECTED = 1 << 16;
103.26 - public final static int BOUND_IN_CONSTRUCTOR = 1 << 17;
103.27 - public final static int GLOBAL = NGLOBAL | CLASS_GLOBAL; // all global
103.28 - public final static int TOPSCOPE = 0;
103.29 - public final static int FUNCSCOPE = 1;
103.30 - public final static int CLASSSCOPE = 2;
103.31 -}
104.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ScopeInfo.java Mon Aug 31 12:40:19 2015 +0200
104.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
104.3 @@ -1,575 +0,0 @@
104.4 -// (C) Copyright 2001 Samuele Pedroni
104.5 -package org.netbeans.modules.python.editor.scopes;
104.6 -
104.7 -import java.util.ArrayList;
104.8 -import java.util.Collections;
104.9 -import java.util.HashMap;
104.10 -import java.util.LinkedHashMap;
104.11 -import java.util.Map;
104.12 -import java.util.List;
104.13 -
104.14 -import org.netbeans.modules.python.editor.AstPath;
104.15 -import org.netbeans.modules.python.editor.PythonAstUtils;
104.16 -import org.python.antlr.ParseException;
104.17 -import org.python.antlr.PythonTree;
104.18 -import org.python.antlr.ast.Assign;
104.19 -import org.python.antlr.ast.Attribute;
104.20 -import org.python.antlr.ast.ClassDef;
104.21 -import org.python.antlr.ast.Name;
104.22 -import org.python.antlr.ast.Return;
104.23 -import org.python.antlr.ast.Tuple;
104.24 -import org.python.antlr.base.expr;
104.25 -import static org.netbeans.modules.python.editor.scopes.ScopeConstants.*;
104.26 -
104.27 -/**
104.28 - * Based on org.python.compiler.ScopeInfo in Jython
104.29 - *
104.30 - * See {@link ScopesCompiler} for details on my modifications
104.31 - */
104.32 -@SuppressWarnings("unchecked")
104.33 -public class ScopeInfo extends Object {
104.34 - public PythonTree scope_node;
104.35 - public String scope_name;
104.36 - public int level;
104.37 - public int func_level;
104.38 - public boolean hidden;
104.39 -
104.40 - public String dump() {
104.41 - StringBuilder sb = new StringBuilder();
104.42 -
104.43 - for (int i = 0; i < level; i++) {
104.44 - sb.append(" ");
104.45 - }
104.46 - sb.append("=============================================\n");
104.47 - for (int i = 0; i < level; i++) {
104.48 - sb.append(" ");
104.49 - }
104.50 - sb.append(((kind != CLASSSCOPE) ? scope_name : "class " +
104.51 - scope_name) + ": " + scope_node + " : " + PythonAstUtils.getRange(scope_node) + "\n");
104.52 - //for(int i=0; i<level; i++) sb.append(" ");
104.53 - //sb.append("UP=" + up);
104.54 - //sb.append(" NESTED=" + nested);
104.55 - //sb.append("\n");
104.56 -
104.57 -
104.58 - // Sort to make test output stable
104.59 - List<String> keys = new ArrayList<>(tbl.keySet());
104.60 - Collections.sort(keys);
104.61 - for (String name : keys) {
104.62 - SymInfo info = tbl.get(name);
104.63 - for (int i = 0; i < level; i++) {
104.64 - sb.append(" ");
104.65 - }
104.66 - sb.append(name);
104.67 - sb.append(" ");
104.68 - sb.append(info.dumpFlags(this));
104.69 - sb.append("\n");
104.70 - }
104.71 -
104.72 - if (inner_free.size() > 0 || cellvars.size() > 0 || jy_paramcells.size() > 0 ||
104.73 - jy_npurecell != 0 /*|| cell != 0 || distance != 0 || up != null*/) {
104.74 - for (int i = 0; i < level; i++) {
104.75 - sb.append(" ");
104.76 - }
104.77 - sb.append("---------------------------------------------\n");
104.78 - }
104.79 -
104.80 - if (inner_free.size() > 0) {
104.81 - List<String> sorted = new ArrayList<>();
104.82 - for (String s : inner_free.keySet()) {
104.83 - sorted.add(s + "=" + inner_free.get(s));
104.84 - }
104.85 - Collections.sort(sorted);
104.86 -
104.87 - for (int i = 0; i < level; i++) {
104.88 - sb.append(" ");
104.89 - }
104.90 - sb.append("inner_free: {"); // NOI18N
104.91 - boolean first = true;
104.92 - for (String s : sorted) {
104.93 - if (first) {
104.94 - first = false;
104.95 - } else {
104.96 - sb.append(", "); // NOI18N
104.97 - }
104.98 - sb.append(s);
104.99 - }
104.100 - sb.append("}\n"); // NOI18N
104.101 - }
104.102 - if (cellvars.size() > 0) {
104.103 - Collections.sort(cellvars);
104.104 - for (int i = 0; i < level; i++) {
104.105 - sb.append(" ");
104.106 - }
104.107 - sb.append("cellvars: " + cellvars.toString() + "\n"); // TODO - sort
104.108 - }
104.109 - if (jy_paramcells.size() > 0) {
104.110 - Collections.sort(jy_paramcells);
104.111 - for (int i = 0; i < level; i++) {
104.112 - sb.append(" ");
104.113 - }
104.114 - sb.append("jy_paramcells: " + jy_paramcells.toString() + "\n"); // TODO - sort
104.115 - }
104.116 - if (jy_npurecell != 0) {
104.117 - for (int i = 0; i < level; i++) {
104.118 - sb.append(" ");
104.119 - }
104.120 - sb.append("jy_npurecell: " + jy_npurecell + "\n"); // TODO - sort
104.121 - }
104.122 - //if (cell != 0) {
104.123 - // for(int i=0; i<level; i++) sb.append(" ");
104.124 - // sb.append("cell: " + cell + "\n"); // TODO - sort
104.125 - //}
104.126 - //if (distance != 0) {
104.127 - // for(int i=0; i<level; i++) sb.append(" ");
104.128 - // sb.append("distance: " + distance + "\n"); // TODO - sort
104.129 - //}
104.130 - //if (up != null) {
104.131 - // for(int i=0; i<level; i++) sb.append(" ");
104.132 - // sb.append("up: " + up.scope_node);
104.133 - //}
104.134 -
104.135 - if (attributes.size() > 0) {
104.136 - for (int i = 0; i < level; i++) {
104.137 - sb.append(" ");
104.138 - }
104.139 - sb.append("------ Attributes ---------------------------------------\n"); // NOI18N
104.140 - // Sort
104.141 - List<String> attributeNames = new ArrayList<>(attributes.keySet());
104.142 - Collections.sort(attributeNames);
104.143 - for (String attributeName : attributeNames) {
104.144 - for (int i = 0; i < level; i++) {
104.145 - sb.append(" ");
104.146 - }
104.147 - sb.append(attributeName);
104.148 - sb.append(" : "); // NOI18N
104.149 - sb.append(attributes.get(attributeName));
104.150 - sb.append("\n"); // NOI18N
104.151 - }
104.152 - }
104.153 -
104.154 - return sb.toString();
104.155 - }
104.156 -
104.157 - public ScopeInfo(String name, PythonTree node, int level, int kind,
104.158 - int func_level, ArgListCompiler ac) {
104.159 - scope_name = name;
104.160 - scope_node = node;
104.161 - this.level = level;
104.162 - this.kind = kind;
104.163 - this.func_level = func_level;
104.164 - this.ac = ac;
104.165 - }
104.166 - public int kind;
104.167 - public boolean unqual_exec;
104.168 - public boolean exec;
104.169 - public boolean from_import_star;
104.170 - public boolean contains_ns_free_vars;
104.171 - public boolean generator;
104.172 - private boolean hasReturnWithValue;
104.173 - public int yield_count;
104.174 - public int max_with_count;
104.175 - public ArgListCompiler ac;
104.176 - public Map<String, SymInfo> tbl = new LinkedHashMap<>();
104.177 -
104.178 - // define a separate dictionary for dynamic bounded variables
104.179 - public Map<String, SymInfo> attributes = new HashMap<>();
104.180 - public List<String> names = new ArrayList<>();
104.181 -
104.182 - private void addAttributeEntry(String name, PythonTree node, int flags) {
104.183 - SymInfo info = attributes.get(name);
104.184 - if (info == null) {
104.185 - SymInfo entry = new SymInfo(flags);
104.186 - if (SymInfo.isPrivateName(name)) {
104.187 - entry.flags |= PRIVATE;
104.188 - } else if (SymInfo.isProtectedName(name)) {
104.189 - entry.flags |= PROTECTED;
104.190 - }
104.191 - entry.node = node;
104.192 - attributes.put(name, entry);
104.193 - }
104.194 - }
104.195 -
104.196 - private void addToClassScope(String name, PythonTree node, boolean inConstructor) {
104.197 - int flags = CLASSSCOPE | BOUND | MEMBER;
104.198 - if (inConstructor) {
104.199 - flags |= BOUND_IN_CONSTRUCTOR;
104.200 - }
104.201 - addAttributeEntry(name, node, flags);
104.202 - }
104.203 -
104.204 - public ScopeInfo getClassScope() {
104.205 - ScopeInfo cur = this;
104.206 - while ((cur != null) &&
104.207 - (!(cur.scope_node instanceof ClassDef))) {
104.208 - cur = cur.nested;
104.209 - }
104.210 - return cur;
104.211 - }
104.212 -
104.213 - private boolean belongsToExprList(List<expr> types, expr cur) {
104.214 - return types != null && types.contains(cur);
104.215 - }
104.216 -
104.217 - boolean isAttributeAssigment(AstPath path, Attribute attr) {
104.218 - PythonTree leaf = path.leaf();
104.219 - Assign assign = null;
104.220 - expr target = attr; // default to single
104.221 - if (leaf instanceof Assign) {
104.222 - assign = (Assign)leaf;
104.223 - } else if (leaf instanceof Tuple) {
104.224 - // check for tuple assignment
104.225 - Tuple tuple = (Tuple)leaf;
104.226 - PythonTree tupleParent = path.leafParent();
104.227 - if (belongsToExprList(tuple.getInternalElts(), attr)) {
104.228 - if (tupleParent instanceof Assign) {
104.229 - assign = (Assign)tupleParent;
104.230 - target = tuple; // tuple assignment target
104.231 - }
104.232 - }
104.233 - }
104.234 - // check if we got assignment
104.235 - if (assign == null) {
104.236 - return false;
104.237 - }
104.238 - if (belongsToExprList(assign.getInternalTargets(), target)) {
104.239 - return true;
104.240 - }
104.241 - return false;
104.242 - }
104.243 -
104.244 - public void addAttribute(AstPath path, String name, PythonTree node) {
104.245 - // deeply check assignment context for attribute.
104.246 - Attribute curAttr = (Attribute)node;
104.247 -
104.248 - if (curAttr.getInternalValue() instanceof Attribute) {
104.249 - // recursice attributes( x.y.z.w ) to be handled later
104.250 - } else if (curAttr.getInternalValue() instanceof Name) {
104.251 -
104.252 - Name parentName = (Name)curAttr.getInternalValue();
104.253 -
104.254 - ScopeInfo classScope = getClassScope();
104.255 - boolean inConstructor = false;
104.256 - String parName = parentName.getInternalId();
104.257 -
104.258 - // for simplicity handle only at classScope in current source
104.259 - if (classScope != null) {
104.260 - // check for self or inherited parent name prefix
104.261 - if ((parName.equals("self")) ||
104.262 - (PythonAstUtils.getParentClassFromNode(path, classScope.scope_node, parName) != null)) {
104.263 - if (!(parName.equals("self"))) {
104.264 - // check classname not overridden by local scope variable
104.265 - if (tbl.get(parName) != null) {
104.266 - return;
104.267 - }
104.268 - }
104.269 - if (scope_name.equals("__init__") || scope_name.equals("__new__")) {
104.270 - inConstructor = true; // set in constructor
104.271 - }
104.272 - //
104.273 - // put in class scope
104.274 - if (isAttributeAssigment(path, curAttr)) {
104.275 - classScope.addToClassScope(name, node, inConstructor);
104.276 - } else {
104.277 - // store at current scope if parName is not overriding
104.278 - // classname at current scope
104.279 - int flags = CLASSSCOPE | READ;
104.280 - addAttributeEntry(name, node, flags);
104.281 - }
104.282 - }
104.283 - }
104.284 - }
104.285 - }
104.286 -
104.287 - public int addGlobal(String name, PythonTree node) {
104.288 - // global kind = func vs. class
104.289 - int global = kind == CLASSSCOPE ? CLASS_GLOBAL : NGLOBAL;
104.290 - SymInfo info = tbl.get(name);
104.291 - if (info == null) {
104.292 - SymInfo entry = new SymInfo(global | BOUND);
104.293 - if (SymInfo.isPrivateName(name)) {
104.294 - entry.flags |= PRIVATE;
104.295 - } else if (SymInfo.isProtectedName(name)) {
104.296 - entry.flags |= PROTECTED;
104.297 - }
104.298 - entry.node = node;
104.299 - tbl.put(name, entry);
104.300 - return -1;
104.301 - }
104.302 - int prev = info.flags;
104.303 - info.flags |= global | BOUND;
104.304 - return prev;
104.305 - }
104.306 - public int local = 0;
104.307 -
104.308 - public void addParam(String name, PythonTree node) {
104.309 - SymInfo entry = new SymInfo(PARAM | BOUND, local++);
104.310 - entry.node = node;
104.311 - tbl.put(name, entry);
104.312 - names.add(name);
104.313 - }
104.314 -
104.315 - // <netbeans>
104.316 - public boolean isUnused(String name) {
104.317 - SymInfo info = tbl.get(name);
104.318 - if (info != null) {
104.319 - return info.isUnused(this);
104.320 - }
104.321 - return false;
104.322 - }
104.323 -
104.324 - public boolean isParameter(String name) {
104.325 - SymInfo info = tbl.get(name);
104.326 - if (info != null) {
104.327 - return info.isParameter();
104.328 - }
104.329 - return false;
104.330 - }
104.331 - // </netbeans>
104.332 -
104.333 - public void markFromParam() {
104.334 - for (SymInfo info : tbl.values()) {
104.335 - info.flags |= FROM_PARAM;
104.336 - }
104.337 - }
104.338 -
104.339 - public SymInfo addBound(String name, PythonTree node) {
104.340 - SymInfo info = tbl.get(name);
104.341 - if (info == null) {
104.342 - info = new SymInfo(BOUND);
104.343 - if (SymInfo.isPrivateName(name)) {
104.344 - info.flags |= PRIVATE;
104.345 - } else if (SymInfo.isProtectedName(name)) {
104.346 - info.flags |= PROTECTED;
104.347 - }
104.348 - tbl.put(name, info);
104.349 - info.node = node;
104.350 - return info;
104.351 - }
104.352 - info.flags |= BOUND;
104.353 -
104.354 - return info;
104.355 - }
104.356 -
104.357 - public SymInfo addUsed(String name, PythonTree node) {
104.358 - SymInfo info = tbl.get(name);
104.359 - if (info == null) {
104.360 - // <netbeans>
104.361 - info = new SymInfo(0);
104.362 - tbl.put(name, info);
104.363 - info.node = node;
104.364 - }
104.365 - info.flags |= READ;
104.366 -
104.367 - return info;
104.368 - // </netbeans>
104.369 - }
104.370 -
104.371 -
104.372 - // <netbeans>
104.373 - void markCall(String name) {
104.374 - SymInfo entry = tbl.get(name);
104.375 - if (entry != null) {
104.376 - entry.flags |= CALLED;
104.377 - }
104.378 - }
104.379 - // </netbeans>
104.380 - private final static String PRESENT = new String("PRESENT");
104.381 - public HashMap<String, String> inner_free = new HashMap<>();
104.382 - public List<String> cellvars = new ArrayList<>();
104.383 - public List<String> jy_paramcells = new ArrayList<>();
104.384 - public int jy_npurecell;
104.385 - public int cell, distance;
104.386 - public ScopeInfo up;
104.387 - public ScopeInfo nested;
104.388 -
104.389 - //Resolve the names used in the given scope, and mark any freevars used in the up scope
104.390 - public void cook(ScopeInfo up, int distance, SymbolTable ctxt) throws Exception {
104.391 - if (up == null) {
104.392 - return; // top level => nop
104.393 - }
104.394 - this.up = up;
104.395 - this.distance = distance;
104.396 - boolean func = kind == FUNCSCOPE;
104.397 - List<String> purecells = new ArrayList<>();
104.398 - cell = 0;
104.399 - boolean some_inner_free = inner_free.size() > 0;
104.400 -
104.401 - for (String name : inner_free.keySet()) {
104.402 -
104.403 - SymInfo info = tbl.get(name);
104.404 - if (info == null) {
104.405 - tbl.put(name, new SymInfo(FREE));
104.406 - continue;
104.407 - }
104.408 - int flags = info.flags;
104.409 - if (func) {
104.410 - // not func global and bound ?
104.411 - if ((flags & NGLOBAL) == 0 && (flags & BOUND) != 0) {
104.412 - info.flags |= CELL;
104.413 - if ((info.flags & PARAM) != 0) {
104.414 - jy_paramcells.add(name);
104.415 - }
104.416 - cellvars.add(name);
104.417 - info.env_index = cell++;
104.418 - if ((flags & PARAM) == 0) {
104.419 - purecells.add(name);
104.420 - }
104.421 - continue;
104.422 - }
104.423 - } else {
104.424 - info.flags |= FREE;
104.425 - }
104.426 - }
104.427 - boolean some_free = false;
104.428 -
104.429 - boolean nested = up.kind != TOPSCOPE;
104.430 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
104.431 - String name = entry.getKey();
104.432 - SymInfo info = entry.getValue();
104.433 - int flags = info.flags;
104.434 - if (nested && (flags & FREE) != 0) {
104.435 - up.inner_free.put(name, PRESENT);
104.436 - }
104.437 - if ((flags & (GLOBAL | PARAM | CELL)) == 0) {
104.438 - if ((flags & BOUND) != 0) { // ?? only func
104.439 - // System.err.println("local: "+name);
104.440 - names.add(name);
104.441 - info.locals_index = local++;
104.442 - continue;
104.443 - }
104.444 - info.flags |= FREE;
104.445 - some_free = true;
104.446 - if (nested) {
104.447 - up.inner_free.put(name, PRESENT);
104.448 - }
104.449 - }
104.450 -
104.451 - // <netbeans>
104.452 - if ((info.flags & FREE) != 0) {
104.453 - // Mark definition symbol as read as well
104.454 - ScopeInfo curr = up;
104.455 - while (curr != null) {
104.456 - SymInfo s = curr.tbl.get(name);
104.457 - if (s != null && ((s.flags & BOUND) != 0)) {
104.458 - s.flags |= READ;
104.459 - s.flags |= (info.flags & (CALLED));
104.460 - break;
104.461 - }
104.462 - curr = curr.up;
104.463 - while (curr != null && curr.kind == CLASSSCOPE) {
104.464 - curr = curr.up;
104.465 - }
104.466 - }
104.467 - }
104.468 -
104.469 - // </netbeans>
104.470 - }
104.471 - if ((jy_npurecell = purecells.size()) > 0) {
104.472 - int sz = purecells.size();
104.473 - for (int i = 0; i < sz; i++) {
104.474 - names.add(purecells.get(i));
104.475 - }
104.476 - }
104.477 -
104.478 - if (some_free && nested) {
104.479 - up.contains_ns_free_vars = true;
104.480 - }
104.481 - // XXX - this doesn't catch all cases - may depend subtly
104.482 - // on how visiting NOW works with antlr compared to javacc
104.483 - if ((unqual_exec || from_import_star)) {
104.484 - if (some_inner_free) {
104.485 - dynastuff_trouble(true, ctxt);
104.486 - } else if (func_level > 1 && some_free) {
104.487 - dynastuff_trouble(false, ctxt);
104.488 - }
104.489 - }
104.490 -
104.491 - }
104.492 -
104.493 - private void dynastuff_trouble(boolean inner_free,
104.494 - SymbolTable ctxt) throws Exception {
104.495 - String illegal;
104.496 - if (unqual_exec && from_import_star) {
104.497 - illegal = "function '" + scope_name +
104.498 - "' uses import * and bare exec, which are illegal";
104.499 - } else if (unqual_exec) {
104.500 - illegal = "unqualified exec is not allowed in function '" +
104.501 - scope_name + "'";
104.502 - } else {
104.503 - illegal = "import * is not allowed in function '" + scope_name + "'";
104.504 - }
104.505 - String why;
104.506 - if (inner_free) {
104.507 - why = " because it contains a function with free variables";
104.508 - } else {
104.509 - why = " because it contains free variables";
104.510 - }
104.511 - ctxt.error(illegal + why, true, scope_node);
104.512 - }
104.513 - public List<String> freevars = new ArrayList<>();
104.514 -
104.515 - /**
104.516 - * setup the closure on this scope using the scope passed into cook as up as
104.517 - * the containing scope
104.518 - */
104.519 - public void setup_closure() {
104.520 - setup_closure(up);
104.521 - }
104.522 -
104.523 - /**
104.524 - * setup the closure on this scope using the passed in scope. This is used
104.525 - * by jythonc to setup its closures.
104.526 - */
104.527 - public void setup_closure(ScopeInfo up) {
104.528 - int free = cell; // env = cell...,free...
104.529 - Map<String, SymInfo> up_tbl = up.tbl;
104.530 - boolean nested = up.kind != TOPSCOPE;
104.531 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
104.532 - String name = entry.getKey();
104.533 - SymInfo info = entry.getValue();
104.534 - int flags = info.flags;
104.535 - if ((flags & FREE) != 0) {
104.536 - SymInfo up_info = up_tbl.get(name);
104.537 - // ?? differs from CPython -- what is the intended behaviour?
104.538 - if (up_info != null) {
104.539 - int up_flags = up_info.flags;
104.540 - if ((up_flags & (CELL | FREE)) != 0) {
104.541 - info.env_index = free++;
104.542 - freevars.add(name);
104.543 - continue;
104.544 - }
104.545 - // ! func global affect nested scopes
104.546 - if (nested && (up_flags & NGLOBAL) != 0) {
104.547 - info.flags = NGLOBAL | BOUND;
104.548 - continue;
104.549 - }
104.550 - }
104.551 - info.flags &= ~FREE;
104.552 - }
104.553 - }
104.554 -
104.555 - }
104.556 -
104.557 - @Override
104.558 - public String toString() {
104.559 - return "ScopeInfo[" + scope_name + " " + kind + "]@" +
104.560 - System.identityHashCode(this);
104.561 - }
104.562 -
104.563 - public void defineAsGenerator(expr node) {
104.564 - generator = true;
104.565 - if (hasReturnWithValue) {
104.566 - throw new ParseException("'return' with argument " +
104.567 - "inside generator", node);
104.568 - }
104.569 - }
104.570 -
104.571 - public void noteReturnValue(Return node) {
104.572 - if (generator) {
104.573 - throw new ParseException("'return' with argument " +
104.574 - "inside generator", node);
104.575 - }
104.576 - hasReturnWithValue = true;
104.577 - }
104.578 -}
105.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/ScopesCompiler.java Mon Aug 31 12:40:19 2015 +0200
105.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
105.3 @@ -1,641 +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.List;
105.9 -import java.util.Map;
105.10 -import java.util.Set;
105.11 -import java.util.Stack;
105.12 -import org.netbeans.modules.python.editor.AstPath;
105.13 -import org.openide.util.Exceptions;
105.14 -import org.python.antlr.PythonTree;
105.15 -import org.python.antlr.Visitor;
105.16 -import org.python.antlr.ast.Assign;
105.17 -import org.python.antlr.ast.Attribute;
105.18 -import org.python.antlr.ast.Call;
105.19 -import org.python.antlr.ast.ClassDef;
105.20 -import org.python.antlr.ast.Delete;
105.21 -import org.python.antlr.ast.Exec;
105.22 -import org.python.antlr.ast.Expression;
105.23 -import org.python.antlr.ast.FunctionDef;
105.24 -import org.python.antlr.ast.GeneratorExp;
105.25 -import org.python.antlr.ast.Global;
105.26 -import org.python.antlr.ast.Import;
105.27 -import org.python.antlr.ast.ImportFrom;
105.28 -import org.python.antlr.ast.Interactive;
105.29 -import org.python.antlr.ast.Lambda;
105.30 -import org.python.antlr.ast.ListComp;
105.31 -import org.python.antlr.ast.Name;
105.32 -import org.python.antlr.ast.Return;
105.33 -import org.python.antlr.ast.Str;
105.34 -import org.python.antlr.ast.With;
105.35 -import org.python.antlr.ast.Yield;
105.36 -import org.python.antlr.ast.alias;
105.37 -import org.python.antlr.ast.arguments;
105.38 -import org.python.antlr.base.expr;
105.39 -import org.python.antlr.ast.expr_contextType;
105.40 -import org.python.antlr.base.stmt;
105.41 -
105.42 -/**
105.43 - * Based on org.python.compiler.ScopesCompiler in Jython
105.44 - *
105.45 - * Modifications I've made:
105.46 - * - Methods for finding all the free variables
105.47 - * - Methods for identifying unused bound variables
105.48 - * - Track whether symbols are referenced as calls or not
105.49 - * (so I can determine whether to look in the index for
105.50 - * functions or data etc. when trying to resolve imports)
105.51 - * - Track variable reads/writes
105.52 - * - Track imports etc.
105.53 - * - Add nodes to each SymInfo
105.54 - * - Replace old style Java (Hashtable, Vector, implements ScopeConstants) with
105.55 - * modern Java (HashMap, ArrayList, import static)
105.56 - *
105.57 - */
105.58 -@SuppressWarnings("unchecked")
105.59 -public class ScopesCompiler extends Visitor implements ScopeConstants {
105.60 - private SymbolTable symbolTable;
105.61 - private Stack scopes;
105.62 - private ScopeInfo cur = null;
105.63 - private Map<PythonTree, ScopeInfo> nodeScopes;
105.64 - private int level = 0;
105.65 - private int func_level = 0;
105.66 - private List<Import> imports;
105.67 - private List<PythonTree> mainImports;
105.68 - private List<ImportFrom> importsFrom;
105.69 - private Set<PythonTree> topLevelImports;
105.70 - private PythonTree root;
105.71 - private PythonTree parent;
105.72 - private AstPath path = new AstPath();
105.73 - /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
105.74 - private List<Str> publicSymbols;
105.75 - /** Set to true if we encountered manipulation on __all__ that I don't understand */
105.76 - private boolean invalidPublicSymbols;
105.77 -
105.78 - public ScopesCompiler(SymbolTable symbolTable, Map<PythonTree, ScopeInfo> nodeScopes, PythonTree root,
105.79 - List<Import> imports, List<ImportFrom> importsFrom, List<PythonTree> mainImports, Set<PythonTree> topLevelImports) {
105.80 - this.symbolTable = symbolTable;
105.81 - this.nodeScopes = nodeScopes;
105.82 - scopes = new Stack();
105.83 - this.root = root;
105.84 -
105.85 - this.imports = imports;
105.86 - this.importsFrom = importsFrom;
105.87 - this.mainImports = mainImports;
105.88 - this.topLevelImports = topLevelImports;
105.89 - }
105.90 -
105.91 - @Override
105.92 - public void traverse(PythonTree node) throws Exception {
105.93 - // Jython's parser often doesn't set the parent references correctly
105.94 - // so try to fix that here
105.95 - node.setParent(parent);
105.96 -
105.97 - PythonTree oldParent = parent;
105.98 - parent = node;
105.99 -
105.100 - path.descend(node);
105.101 - super.traverse(node);
105.102 - parent = oldParent;
105.103 - path.ascend();
105.104 - }
105.105 -
105.106 - public void beginScope(String name, int kind, PythonTree node,
105.107 - ArgListCompiler ac) {
105.108 - if (cur != null) {
105.109 - scopes.push(cur);
105.110 - }
105.111 - if (kind == FUNCSCOPE) {
105.112 - func_level++;
105.113 - }
105.114 - cur = new ScopeInfo(name, node, level++, kind, func_level, ac);
105.115 - nodeScopes.put(node, cur);
105.116 - }
105.117 -
105.118 - public void endScope() throws Exception {
105.119 - if (cur.kind == FUNCSCOPE) {
105.120 - func_level--;
105.121 - }
105.122 - level--;
105.123 - ScopeInfo up = null;
105.124 - if (!scopes.empty()) {
105.125 - up = (ScopeInfo)scopes.pop();
105.126 - }
105.127 - //Go into the stack to find a non class containing scope to use making the closure
105.128 - //See PEP 227
105.129 - int dist = 1;
105.130 - ScopeInfo referenceable = up;
105.131 - for (int i = scopes.size() - 1; i >= 0 && referenceable.kind == CLASSSCOPE; i--, dist++) {
105.132 - referenceable = ((ScopeInfo)scopes.get(i));
105.133 - }
105.134 - cur.cook(referenceable, dist, symbolTable);
105.135 -// cur.dump(); // debug
105.136 - cur = up;
105.137 - }
105.138 -
105.139 - public void parse() {
105.140 - try {
105.141 - visit(root);
105.142 - } catch (Throwable t) {
105.143 - Exceptions.printStackTrace(t);
105.144 - //throw org.python.core.ParserFacade.fixParseError(null, t,
105.145 - // code_compiler.getFilename());
105.146 - }
105.147 - }
105.148 -
105.149 - @Override
105.150 - public Object visitInteractive(Interactive node) throws Exception {
105.151 - beginScope("<single-top>", TOPSCOPE, node, null);
105.152 - PythonTree oldParent = parent;
105.153 - parent = node;
105.154 - suite(node.getInternalBody());
105.155 - parent = oldParent;
105.156 - endScope();
105.157 - return null;
105.158 - }
105.159 -
105.160 - @Override
105.161 - public Object visitModule(org.python.antlr.ast.Module node)
105.162 - throws Exception {
105.163 - List<stmt> body = node.getInternalBody();
105.164 - if (body != null && body.size() > 0) {
105.165 - boolean foundFirst = false;
105.166 - for (stmt stmt : body) {
105.167 - if (stmt != null) {
105.168 - if (stmt instanceof Import || stmt instanceof ImportFrom) {
105.169 - if (!foundFirst) {
105.170 - foundFirst = true;
105.171 - }
105.172 - mainImports.add(stmt);
105.173 - } else if (foundFirst) {
105.174 - break;
105.175 - }
105.176 - }
105.177 - }
105.178 - }
105.179 -
105.180 - beginScope("<file-top>", TOPSCOPE, node, null);
105.181 -
105.182 - PythonTree oldParent = parent;
105.183 - parent = node;
105.184 - suite(node.getInternalBody());
105.185 - parent = oldParent;
105.186 -
105.187 - endScope();
105.188 - return null;
105.189 - }
105.190 -
105.191 - @Override
105.192 - public Object visitExpression(Expression node) throws Exception {
105.193 - beginScope("<eval-top>", TOPSCOPE, node, null);
105.194 - visit(new Return(node, node.getInternalBody()));
105.195 - endScope();
105.196 - return null;
105.197 - }
105.198 -
105.199 - private void def(String name, int extraFlags, PythonTree node) {
105.200 - SymInfo info = cur.addBound(name, node);
105.201 - // <netbeans>
105.202 - info.flags |= (DEF | extraFlags);
105.203 - info.node = node;
105.204 - // </netbeans>
105.205 - }
105.206 -
105.207 - @Override
105.208 - public Object visitAssign(Assign node) throws Exception {
105.209 - List<expr> targets = node.getInternalTargets();
105.210 - if (targets != null && targets.size() == 1 && targets.get(0) instanceof Name) {
105.211 - Name lhs = (Name)targets.get(0);
105.212 - if ("__all__".equals(lhs.getInternalId())) { // NOI18N
105.213 - expr nodeValue = node.getInternalValue();
105.214 - if (!invalidPublicSymbols && nodeValue instanceof org.python.antlr.ast.List) {
105.215 - org.python.antlr.ast.List allList = (org.python.antlr.ast.List)nodeValue;
105.216 - if (allList != null) {
105.217 - for (expr expr : allList.getInternalElts()) {
105.218 - if (expr instanceof Str) {
105.219 - Str str = (Str)expr;
105.220 - if (publicSymbols == null) {
105.221 - publicSymbols = new ArrayList<>();
105.222 - }
105.223 - publicSymbols.add(str);
105.224 - } else {
105.225 - invalidPublicSymbols = true;
105.226 - }
105.227 - }
105.228 - }
105.229 - } else {
105.230 - invalidPublicSymbols = true;
105.231 - }
105.232 - }
105.233 - }
105.234 -
105.235 - if (targets.size() > 0) {
105.236 - List<Name> names = new ArrayList<>(targets.size());
105.237 - boolean valid = true;
105.238 - for (expr et : targets) {
105.239 - if (et instanceof Name) {
105.240 - Name name = (Name)et;
105.241 - names.add(name);
105.242 - } else {
105.243 - valid = false;
105.244 - }
105.245 - }
105.246 - if (valid) {
105.247 - expr nodeValue = node.getInternalValue();
105.248 - if (nodeValue instanceof Name) {
105.249 - Name value = (Name)nodeValue;
105.250 -
105.251 - SymInfo rhsSym = cur.tbl.get(value.getInternalId());
105.252 - if (rhsSym != null && rhsSym.isDef()) {
105.253 - for (Name name : names) {
105.254 - visitName(name);
105.255 - SymInfo sym = cur.tbl.get(name.getInternalId());
105.256 - if (sym != null) {
105.257 - sym.flags |= ALIAS;
105.258 - sym.flags |= (rhsSym.flags & (CLASS | FUNCTION));
105.259 - sym.node = rhsSym.node;
105.260 - }
105.261 - }
105.262 - }
105.263 - }
105.264 - }
105.265 - }
105.266 -
105.267 - return super.visitAssign(node);
105.268 - }
105.269 -
105.270 - @Override
105.271 - public Object visitFunctionDef(FunctionDef node) throws Exception {
105.272 - def(node.getInternalName(), FUNCTION, node);
105.273 - ArgListCompiler ac = new ArgListCompiler(symbolTable);
105.274 - ac.visitArgs(node.getInternalArgs());
105.275 -
105.276 - List<expr> defaults = ac.getDefaults();
105.277 - for (int i = 0; i < defaults.size(); i++) {
105.278 - visit(defaults.get(i));
105.279 - }
105.280 -
105.281 - List<expr> decs = node.getInternalDecorator_list();
105.282 - for (int i = decs.size() - 1; i >= 0; i--) {
105.283 - visit(decs.get(i));
105.284 - }
105.285 -
105.286 - ScopeInfo parentScope = cur;
105.287 - beginScope(node.getInternalName(), FUNCSCOPE, node, ac);
105.288 - cur.nested = parentScope;
105.289 -
105.290 - int n = ac.names.size();
105.291 - for (int i = 0; i < n; i++) {
105.292 - cur.addParam(ac.names.get(i), ac.nodes.get(i));
105.293 - }
105.294 - for (int i = 0; i < ac.init_code.size(); i++) {
105.295 - visit(ac.init_code.get(i));
105.296 - }
105.297 - cur.markFromParam();
105.298 -
105.299 - PythonTree oldParent = parent;
105.300 - parent = node;
105.301 - suite(node.getInternalBody());
105.302 - parent = oldParent;
105.303 -
105.304 - endScope();
105.305 - return null;
105.306 - }
105.307 -
105.308 - @Override
105.309 - public Object visitLambda(Lambda node) throws Exception {
105.310 - ArgListCompiler ac = new ArgListCompiler(symbolTable);
105.311 - ac.visitArgs(node.getInternalArgs());
105.312 -
105.313 - List<expr> defaults = ac.getDefaults();
105.314 - for (expr expr : defaults) {
105.315 - visit(expr);
105.316 - }
105.317 -
105.318 - beginScope("<lambda>", FUNCSCOPE, node, ac);
105.319 - assert ac.names.size() == ac.nodes.size();
105.320 - for (int i = 0; i < ac.names.size(); i++) {
105.321 - cur.addParam(ac.names.get(i), ac.nodes.get(i));
105.322 - }
105.323 - for (Object o : ac.init_code) {
105.324 - visit((stmt)o);
105.325 - }
105.326 - cur.markFromParam();
105.327 - visit(node.getInternalBody());
105.328 - endScope();
105.329 - return null;
105.330 - }
105.331 -
105.332 - public void suite(List<stmt> stmts) throws Exception {
105.333 - if (stmts != null) {
105.334 - for (int i = 0; i < stmts.size(); i++) {
105.335 - stmt s = stmts.get(i);
105.336 - path.descend(s);
105.337 - visit(s);
105.338 - path.ascend();
105.339 - }
105.340 - }
105.341 - }
105.342 -
105.343 - @Override
105.344 - public Object visitImport(Import node) throws Exception {
105.345 - if (parent == root) {
105.346 - topLevelImports.add(node);
105.347 - }
105.348 - imports.add(node);
105.349 -
105.350 - List<alias> names = node.getInternalNames();
105.351 - if (names != null) {
105.352 - for (alias alias : names) {
105.353 - String asname = alias.getInternalAsname();
105.354 - if (asname != null) {
105.355 - SymInfo entry = cur.addBound(asname, node);
105.356 - entry.flags |= IMPORTED;
105.357 - } else {
105.358 - String name = alias.getInternalName();
105.359 - if (name.indexOf('.') > 0) {
105.360 - name = name.substring(0, name.indexOf('.'));
105.361 - }
105.362 - SymInfo entry = cur.addBound(name, node);
105.363 - entry.flags |= IMPORTED;
105.364 - }
105.365 - }
105.366 - }
105.367 - return null;
105.368 - }
105.369 -
105.370 - @Override
105.371 - public Object visitImportFrom(ImportFrom node) throws Exception {
105.372 - if (parent == root) {
105.373 - topLevelImports.add(node);
105.374 - }
105.375 - importsFrom.add(node);
105.376 -
105.377 - //Future.checkFromFuture(node); // future stmt support
105.378 - List<alias> names = node.getInternalNames();
105.379 - if (names == null || names.size() == 0) {
105.380 - cur.from_import_star = true;
105.381 - return null;
105.382 - }
105.383 - for (alias alias : names) {
105.384 - String asname = alias.getInternalAsname();
105.385 - if (asname != null) {
105.386 - SymInfo entry = cur.addBound(asname, node);
105.387 - entry.flags |= IMPORTED;
105.388 - } else {
105.389 - SymInfo entry = cur.addBound(alias.getInternalName(), node);
105.390 - entry.flags |= IMPORTED;
105.391 - }
105.392 - }
105.393 - return null;
105.394 - }
105.395 -
105.396 - @Override
105.397 - public Object visitGlobal(Global node) throws Exception {
105.398 - List<String> names = node.getInternalNames();
105.399 - for (String name : names) {
105.400 - int prev = cur.addGlobal(name, node);
105.401 - if (prev >= 0) {
105.402 - if ((prev & FROM_PARAM) != 0) {
105.403 - symbolTable.error("name '" + name + "' is local and global", true, node);
105.404 - }
105.405 - if ((prev & GLOBAL) != 0) {
105.406 - continue;
105.407 - }
105.408 - String what;
105.409 - if ((prev & BOUND) != 0) {
105.410 - what = "assignment";
105.411 - } else {
105.412 - what = "use";
105.413 - }
105.414 - symbolTable.error("name '" + name + "' declared global after " + what, false, node);
105.415 - }
105.416 - }
105.417 - return null;
105.418 - }
105.419 -
105.420 - @Override
105.421 - public Object visitExec(Exec node) throws Exception {
105.422 - cur.exec = true;
105.423 - if (node.getInternalGlobals() == null && node.getInternalLocals() == null) {
105.424 - cur.unqual_exec = true;
105.425 - }
105.426 - traverse(node);
105.427 - return null;
105.428 - }
105.429 -
105.430 - @Override
105.431 - public Object visitClassDef(ClassDef node) throws Exception {
105.432 - String name = node.getInternalName();
105.433 - def(name, CLASS, node);
105.434 - List<expr> bases = node.getInternalBases();
105.435 - if (bases != null) {
105.436 - for (expr expr : bases) {
105.437 - visit(expr);
105.438 - }
105.439 - }
105.440 - ScopeInfo parentScope = cur;
105.441 - beginScope(name, CLASSSCOPE, node, null);
105.442 - cur.nested = parentScope;
105.443 - PythonTree oldParent = parent;
105.444 - parent = node;
105.445 - suite(node.getInternalBody());
105.446 - parent = oldParent;
105.447 - endScope();
105.448 - return null;
105.449 - }
105.450 -
105.451 - @Override
105.452 - public Object visitName(Name node) throws Exception {
105.453 - // Jython's parser doesn't always initialize the parent references correctly;
105.454 - // try to correct that here.
105.455 - node.setParent(parent);
105.456 -
105.457 - String name = node.getInternalId();
105.458 - if (node.getInternalCtx() != expr_contextType.Load) {
105.459 - if (name.equals("__debug__")) {
105.460 - symbolTable.error("can not assign to __debug__", true, node);
105.461 - }
105.462 - cur.addBound(name, node);
105.463 - } else {
105.464 - cur.addUsed(name, node);
105.465 - }
105.466 - return null;
105.467 - }
105.468 -
105.469 - // <netbeans>
105.470 - @Override
105.471 - public Object visitCall(Call node) throws Exception {
105.472 - Object ret = super.visitCall(node);
105.473 -
105.474 - expr func = node.getInternalFunc();
105.475 - if (func instanceof Name) {
105.476 - Name name = (Name)func;
105.477 - cur.markCall(name.getInternalId());
105.478 - } else if (func instanceof Attribute) {
105.479 - Attribute attr = (Attribute)func;
105.480 - if (cur.attributes != null) {
105.481 - SymInfo funcSymbol = cur.attributes.get(attr.getInternalAttr());
105.482 - if (funcSymbol != null) {
105.483 - funcSymbol.flags |= FUNCTION | CALLED; // mark as func/method call
105.484 - }
105.485 - }
105.486 -
105.487 - }
105.488 -
105.489 - return ret;
105.490 - }
105.491 -
105.492 - @Override
105.493 - public Object visitDelete(Delete node) throws Exception {
105.494 - for (expr et : node.getInternalTargets()) {
105.495 - if (et instanceof Name) {
105.496 - String name = ((Name)et).getInternalId();
105.497 - cur.addUsed(name, node);
105.498 - }
105.499 - }
105.500 -
105.501 - return super.visitDelete(node);
105.502 - }
105.503 -
105.504 - @Override
105.505 - public Object visitAttribute(Attribute node) throws Exception {
105.506 - if (parent instanceof Call && node.getInternalValue() instanceof Name &&
105.507 - ("__all__".equals(((Name)node.getInternalValue()).getInternalId()))) {
105.508 - // If you for example call
105.509 - // __all__.extend("foo")
105.510 - // or
105.511 - // __all__.append("bar")
105.512 - // then I don't want to try to analyze __all__
105.513 - String nodeAttr = node.getInternalAttr();
105.514 - if ("extend".equals(nodeAttr) || "append".equals(nodeAttr)) { // NOI18N
105.515 - Call call = (Call)parent;
105.516 - List<expr> callArgs = call.getInternalArgs();
105.517 - if (callArgs != null) {
105.518 - for (expr expr : callArgs) {
105.519 - if (expr instanceof Str) {
105.520 - if (publicSymbols == null) {
105.521 - publicSymbols = new ArrayList<>();
105.522 - }
105.523 - publicSymbols.add((Str)expr);
105.524 - } else if (expr instanceof org.python.antlr.ast.List) {
105.525 - org.python.antlr.ast.List list = (org.python.antlr.ast.List)expr;
105.526 - if (list != null) {
105.527 - List<expr> elts = list.getInternalElts();
105.528 - if (elts != null) {
105.529 - for (expr ex : elts) {
105.530 - if (ex instanceof Str) {
105.531 - Str str = (Str)ex;
105.532 - if (publicSymbols == null) {
105.533 - publicSymbols = new ArrayList<>();
105.534 - }
105.535 - publicSymbols.add(str);
105.536 - } else {
105.537 - invalidPublicSymbols = true;
105.538 - }
105.539 - }
105.540 - }
105.541 - }
105.542 - } else {
105.543 - invalidPublicSymbols = true;
105.544 - break;
105.545 - }
105.546 - }
105.547 - }
105.548 - } else {
105.549 - invalidPublicSymbols = true;
105.550 - }
105.551 - } else {
105.552 - String nodeAttr = node.getInternalAttr();
105.553 - if (nodeAttr != null) {
105.554 - cur.addAttribute(path, nodeAttr, node);
105.555 - }
105.556 - }
105.557 - return super.visitAttribute(node);
105.558 - }
105.559 - // </netbeans>
105.560 -
105.561 - @Override
105.562 - public Object visitListComp(ListComp node) throws Exception {
105.563 - String tmp = "_[" + node.getLine() + "_" + node.getCharPositionInLine() + "]";
105.564 - cur.addBound(tmp, node);
105.565 - traverse(node);
105.566 - return null;
105.567 - }
105.568 -
105.569 - @Override
105.570 - public Object visitYield(Yield node) throws Exception {
105.571 - cur.defineAsGenerator(node);
105.572 - cur.yield_count++;
105.573 - traverse(node);
105.574 - return null;
105.575 - }
105.576 -
105.577 - @Override
105.578 - public Object visitReturn(Return node) throws Exception {
105.579 - if (node.getInternalValue() != null) {
105.580 - cur.noteReturnValue(node);
105.581 - }
105.582 - traverse(node);
105.583 - return null;
105.584 - }
105.585 -
105.586 - @Override
105.587 - public Object visitGeneratorExp(GeneratorExp node) throws Exception {
105.588 - // The first iterator is evaluated in the outer scope
105.589 - if (node.getInternalGenerators() != null && node.getInternalGenerators().size() > 0) {
105.590 - visit(node.getInternalGenerators().get(0).getInternalIter());
105.591 - }
105.592 - String bound_exp = "_(x)";
105.593 - String tmp = "_(" + node.getLine() + "_" + node.getCharPositionInLine() + ")";
105.594 - def(tmp, GENERATOR, node);
105.595 - ArgListCompiler ac = new ArgListCompiler(symbolTable);
105.596 - List<expr> args = new ArrayList<>();
105.597 - Name argsName = new Name(node.getToken(), bound_exp, expr_contextType.Param);
105.598 - args.add(argsName);
105.599 - ac.visitArgs(new arguments(node, args, null, null, new ArrayList<expr>()));
105.600 - beginScope(tmp, FUNCSCOPE, node, ac);
105.601 - cur.addParam(bound_exp, argsName);
105.602 - cur.markFromParam();
105.603 -
105.604 - cur.defineAsGenerator(node);
105.605 - cur.yield_count++;
105.606 - // The reset of the iterators are evaluated in the inner scope
105.607 - if (node.getInternalElt() != null) {
105.608 - visit(node.getInternalElt());
105.609 - }
105.610 - if (node.getInternalGenerators() != null) {
105.611 - for (int i = 0; i < node.getInternalGenerators().size(); i++) {
105.612 - if (node.getInternalGenerators().get(i) != null) {
105.613 - if (i == 0) {
105.614 - visit(node.getInternalGenerators().get(i).getInternalTarget());
105.615 - if (node.getInternalGenerators().get(i).getInternalIfs() != null) {
105.616 - for (expr cond : node.getInternalGenerators().get(i).getInternalIfs()) {
105.617 - if (cond != null) {
105.618 - visit(cond);
105.619 - }
105.620 - }
105.621 - }
105.622 - } else {
105.623 - visit(node.getInternalGenerators().get(i));
105.624 - }
105.625 - }
105.626 - }
105.627 - }
105.628 -
105.629 - endScope();
105.630 - return null;
105.631 - }
105.632 -
105.633 - @Override
105.634 - public Object visitWith(With node) throws Exception {
105.635 - cur.max_with_count++;
105.636 - traverse(node);
105.637 -
105.638 - return null;
105.639 - }
105.640 -
105.641 - public List<Str> getPublicSymbols() {
105.642 - return invalidPublicSymbols ? null : publicSymbols;
105.643 - }
105.644 -}
106.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/SymInfo.java Mon Aug 31 12:40:19 2015 +0200
106.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
106.3 @@ -1,207 +0,0 @@
106.4 -package org.netbeans.modules.python.editor.scopes;
106.5 -
106.6 -import org.python.antlr.PythonTree;
106.7 -import static org.netbeans.modules.python.editor.scopes.ScopeConstants.*;
106.8 -
106.9 -public class SymInfo extends Object {
106.10 - public SymInfo(int flags) {
106.11 - this.flags = flags;
106.12 - }
106.13 -
106.14 - public SymInfo(int flags, int locals_index) {
106.15 - this.flags = flags;
106.16 - this.locals_index = locals_index;
106.17 - }
106.18 - public int flags;
106.19 - public int locals_index;
106.20 - public int env_index;
106.21 - public PythonTree node;
106.22 -
106.23 - @Override
106.24 - public String toString() {
106.25 - return "SymInfo[" + flags + " " + locals_index + " " +
106.26 - env_index + "]" + dumpFlags(null);
106.27 - }
106.28 -
106.29 - public String dumpFlags(ScopeInfo info) {
106.30 - StringBuilder sb = new StringBuilder();
106.31 - if ((flags & BOUND) != 0) {
106.32 - sb.append("[bound]");
106.33 - }
106.34 - // func scope global (affect nested scopes)
106.35 - // vs. class scope global
106.36 - if ((flags & NGLOBAL) != 0) {
106.37 - sb.append("[func-global]");
106.38 - } else if ((flags & CLASS_GLOBAL) != 0) {
106.39 - sb.append("[class-global]");
106.40 - }
106.41 - if ((flags & PARAM) != 0) {
106.42 - sb.append("[param]");
106.43 - } else if ((flags & FROM_PARAM) != 0) {
106.44 - sb.append("[from-param]");
106.45 - }
106.46 - if ((flags & CELL) != 0) {
106.47 - sb.append("[cell]");
106.48 - }
106.49 - if ((flags & FREE) != 0) {
106.50 - sb.append("[free]");
106.51 - }
106.52 - if (isImported()) {
106.53 - sb.append("[imported]");
106.54 - }
106.55 - if (isPrivate()) {
106.56 - sb.append("[private]");
106.57 - }
106.58 - if (isClass()) {
106.59 - sb.append("[class]");
106.60 - }
106.61 - if (isFunction()) {
106.62 - sb.append("[function]");
106.63 - }
106.64 - if (isData()) {
106.65 - sb.append("[data]");
106.66 - }
106.67 - if (isMember()) {
106.68 - sb.append("[member]");
106.69 - }
106.70 - if (isDef()) {
106.71 - sb.append("[def]");
106.72 - }
106.73 - if (isRead()) {
106.74 - sb.append("[read]");
106.75 - }
106.76 - if (isAlias()) {
106.77 - sb.append("[alias]");
106.78 - }
106.79 - if (isGeneratorExp()) {
106.80 - sb.append("[generator]");
106.81 - }
106.82 - if (isCalled()) {
106.83 - sb.append("[called]");
106.84 - }
106.85 - if (isProtected()) {
106.86 - sb.append("[protected]");
106.87 - }
106.88 - if (isBoundInConstructor()) {
106.89 - sb.append("[bound-in-constructor]");
106.90 - }
106.91 - if (isUnused(info)) {
106.92 - sb.append("[unused]");
106.93 - }
106.94 - if (isUnresolved()) {
106.95 - sb.append("[UNRESOLVED]");
106.96 - }
106.97 - sb.append("[node=");
106.98 - if (node != null) {
106.99 - sb.append(node.getClass().getSimpleName());
106.100 - } else {
106.101 - sb.append("null");
106.102 - }
106.103 - sb.append("]");
106.104 -
106.105 - return sb.toString();
106.106 - }
106.107 -
106.108 - public boolean isUnused(ScopeInfo info) {
106.109 - return (info == null || info.kind == FUNCSCOPE) && (flags & (READ | BOUND | DEF)) == BOUND;
106.110 - }
106.111 -
106.112 - public boolean isParameter() {
106.113 - return (flags & (PARAM | FROM_PARAM)) != 0;
106.114 - }
106.115 -
106.116 - public boolean isUnresolved() {
106.117 - return (flags & (BOUND | FREE)) == 0;
106.118 - }
106.119 -
106.120 - public boolean isImported() {
106.121 - return (flags & IMPORTED) != 0;
106.122 - }
106.123 -
106.124 - public boolean isData() {
106.125 - return (flags & (BOUND | DEF | CLASS | FUNCTION)) == (BOUND);
106.126 - }
106.127 -
106.128 - public boolean isClass() {
106.129 - return (flags & CLASS) != 0;
106.130 - }
106.131 -
106.132 - public boolean isDef() {
106.133 - return (flags & DEF) != 0;
106.134 - }
106.135 -
106.136 - public boolean isFunction() {
106.137 - return (flags & FUNCTION) != 0;
106.138 - }
106.139 -
106.140 - public boolean isBound() {
106.141 - return (flags & BOUND) != 0;
106.142 - }
106.143 -
106.144 - public boolean isMember() {
106.145 - return (flags & MEMBER) != 0;
106.146 - }
106.147 -
106.148 - public boolean isCalled() {
106.149 - return (flags & CALLED) != 0;
106.150 - }
106.151 -
106.152 - public boolean isRead() {
106.153 - return (flags & READ) != 0;
106.154 - }
106.155 -
106.156 - public boolean isGeneratorExp() {
106.157 - return (flags & GENERATOR) != 0;
106.158 - }
106.159 -
106.160 - public boolean isFree() {
106.161 - return (flags & FREE) != 0;
106.162 - }
106.163 -
106.164 - public boolean isPrivate() {
106.165 - return (flags & PRIVATE) != 0;
106.166 - }
106.167 -
106.168 - public boolean isProtected() {
106.169 - return (flags & PROTECTED) != 0;
106.170 - }
106.171 -
106.172 - public boolean isBoundInConstructor() {
106.173 - return (flags & BOUND_IN_CONSTRUCTOR) != 0;
106.174 - }
106.175 -
106.176 - public boolean isAlias() {
106.177 - return (flags & ALIAS) != 0;
106.178 - }
106.179 -
106.180 - public boolean isVariable(boolean mustBeBound) {
106.181 - int mask = mustBeBound ? BOUND : 0;
106.182 - return (flags & (BOUND | CALLED | DEF | IMPORTED | CLASS | FUNCTION | MEMBER | GENERATOR)) == mask;
106.183 - }
106.184 -
106.185 - public static boolean isPrivateName(String name) {
106.186 - // Private variables: start with __ but doesn't end with __
106.187 - // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
106.188 - if (name.startsWith("__") && !name.endsWith("__")) { // NOI18N
106.189 - return true;
106.190 - } else if (name != null && name.startsWith("_") && !name.endsWith("_")) { // NOI18N
106.191 - // From PEP8: Single_leading_underscore: weak "internal use" indicator
106.192 - // (e.g. "from M import *" does not import objects whose name
106.193 - // starts with an underscore).
106.194 - return true;
106.195 - }
106.196 -
106.197 - return false;
106.198 - }
106.199 -
106.200 - public static boolean isProtectedName(String name) {
106.201 - // Protected variable starts with a single _
106.202 - // this is a convention only
106.203 - if (!name.startsWith("__")) { // NOI18N
106.204 - if (name.startsWith("_")) { // NOI18N
106.205 - return true;
106.206 - }
106.207 - }
106.208 - return false;
106.209 - }
106.210 -}
107.1 --- a/python.editor/src/org/netbeans/modules/python/editor/scopes/SymbolTable.java Mon Aug 31 12:40:19 2015 +0200
107.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
107.3 @@ -1,1249 +0,0 @@
107.4 -/*
107.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
107.6 - *
107.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
107.8 - *
107.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
107.10 - * Other names may be trademarks of their respective owners.
107.11 - *
107.12 - * The contents of this file are subject to the terms of either the GNU
107.13 - * General Public License Version 2 only ("GPL") or the Common
107.14 - * Development and Distribution License("CDDL") (collectively, the
107.15 - * "License"). You may not use this file except in compliance with the
107.16 - * License. You can obtain a copy of the License at
107.17 - * http://www.netbeans.org/cddl-gplv2.html
107.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
107.19 - * specific language governing permissions and limitations under the
107.20 - * License. When distributing the software, include this License Header
107.21 - * Notice in each file and include the License file at
107.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
107.23 - * particular file as subject to the "Classpath" exception as provided
107.24 - * by Oracle in the GPL Version 2 section of the License file that
107.25 - * accompanied this code. If applicable, add the following below the
107.26 - * License Header, with the fields enclosed by brackets [] replaced by
107.27 - * your own identifying information:
107.28 - * "Portions Copyrighted [year] [name of copyright owner]"
107.29 - *
107.30 - * If you wish your version of this file to be governed by only the CDDL
107.31 - * or only the GPL Version 2, indicate your decision by adding
107.32 - * "[Contributor] elects to include this software in this distribution
107.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
107.34 - * single choice of license, a recipient has the option to distribute
107.35 - * your version of this file under either the CDDL, the GPL Version 2 or
107.36 - * to extend the choice of license to its licensees as provided above.
107.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
107.38 - * Version 2 license, then the option applies only if the new code is
107.39 - * made subject to such option by the copyright holder.
107.40 - *
107.41 - * Contributor(s):
107.42 - *
107.43 - * Portions Copyrighted 2008 Sun Microsystems, Inc.
107.44 - */
107.45 -package org.netbeans.modules.python.editor.scopes;
107.46 -
107.47 -import java.util.ArrayList;
107.48 -import java.util.Collections;
107.49 -import java.util.HashMap;
107.50 -import java.util.HashSet;
107.51 -import java.util.List;
107.52 -import java.util.Map;
107.53 -import java.util.Set;
107.54 -import org.netbeans.modules.csl.api.ElementKind;
107.55 -import org.netbeans.modules.csl.api.OffsetRange;
107.56 -import org.netbeans.modules.csl.api.Severity;
107.57 -import org.netbeans.modules.csl.api.Error;
107.58 -import org.netbeans.modules.csl.spi.DefaultError;
107.59 -import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
107.60 -import org.netbeans.modules.python.editor.PythonAstUtils;
107.61 -import org.netbeans.modules.python.editor.PythonIndex;
107.62 -import org.netbeans.modules.python.editor.PythonIndexer;
107.63 -import org.netbeans.modules.python.editor.PythonParserResult;
107.64 -import org.netbeans.modules.python.editor.PythonUtils;
107.65 -import org.netbeans.modules.python.editor.elements.AstElement;
107.66 -import org.netbeans.modules.python.editor.elements.Element;
107.67 -import org.netbeans.modules.python.editor.elements.IndexedElement;
107.68 -import org.netbeans.modules.python.editor.imports.ImportEntry;
107.69 -import org.netbeans.modules.python.editor.imports.ImportManager;
107.70 -import org.netbeans.modules.python.editor.lexer.PythonTokenId;
107.71 -import org.openide.filesystems.FileObject;
107.72 -import org.openide.filesystems.FileStateInvalidException;
107.73 -import org.openide.filesystems.FileUtil;
107.74 -import org.openide.util.Exceptions;
107.75 -import org.python.antlr.PythonTree;
107.76 -import org.python.antlr.Visitor;
107.77 -import org.python.antlr.ast.Attribute;
107.78 -import org.python.antlr.ast.ClassDef;
107.79 -import org.python.antlr.ast.Expression;
107.80 -import org.python.antlr.ast.FunctionDef;
107.81 -import org.python.antlr.ast.GeneratorExp;
107.82 -import org.python.antlr.ast.Import;
107.83 -import org.python.antlr.ast.ImportFrom;
107.84 -import org.python.antlr.ast.Interactive;
107.85 -import org.python.antlr.ast.Lambda;
107.86 -import org.python.antlr.ast.Name;
107.87 -import org.python.antlr.ast.Str;
107.88 -import org.python.antlr.ast.alias;
107.89 -import org.python.antlr.base.expr;
107.90 -import static org.netbeans.modules.python.editor.scopes.ScopeConstants.*;
107.91 -
107.92 -/**
107.93 - * A symbol table tracks a bunch of scopes and can answer questions about defined
107.94 - * symbols.
107.95 - *
107.96 - * Based on Jython's ScopeManager.
107.97 - *
107.98 - * @author Tor Norbye
107.99 - */
107.100 -public class SymbolTable {
107.101 - private final static int YES = 1;
107.102 - private final static int NO = 0;
107.103 - private final static int CIRCULAR = -1;
107.104 - private Map<PythonTree, ScopeInfo> scopes = new HashMap<>();
107.105 - private PythonTree root;
107.106 - private FileObject fileObject;
107.107 - private List<Import> imports = new ArrayList<>();
107.108 - private List<ImportFrom> importsFrom = new ArrayList<>();
107.109 - private List<PythonTree> mainImports = new ArrayList<>();
107.110 - private Set<PythonTree> topLevelImports = new HashSet<>();
107.111 - private List<Error> errors;
107.112 - /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
107.113 - private List<Str> publicSymbols;
107.114 - private final static HashMap<String, String> classAttributes = new HashMap<String, String>() {
107.115 - {
107.116 - put("__class__", "__class__");
107.117 - put("__bases__", "__bases__");
107.118 - put("__dict__", "__dict__");
107.119 - put("__doc__", "__doc__");
107.120 - put("__name__", "__bases");
107.121 - }
107.122 - };
107.123 - private HashMap<String, ClassDef> classes = new HashMap<>();
107.124 - // TODO - use WeakHashMap?
107.125 - static Map<String, Set<IndexedElement>> importedElements = new HashMap<>();
107.126 -
107.127 - private HashMap<String, ClassDef> buildLocalClasses() {
107.128 - HashMap<String, ClassDef> localClasses = new HashMap<>();
107.129 - for (PythonTree cur : scopes.keySet()) {
107.130 - if (cur instanceof ClassDef) {
107.131 - ClassDef curClass = (ClassDef)cur;
107.132 - localClasses.put(curClass.getInternalName(), curClass);
107.133 - }
107.134 - }
107.135 - return localClasses;
107.136 - }
107.137 -
107.138 - public SymbolTable(PythonTree root, FileObject fileObject) {
107.139 - this.root = root;
107.140 - this.fileObject = fileObject;
107.141 -
107.142 - if (root != null) {
107.143 - try {
107.144 - ScopesCompiler compiler = new ScopesCompiler(this, scopes, root, imports, importsFrom, mainImports, topLevelImports);
107.145 - compiler.parse();
107.146 - publicSymbols = compiler.getPublicSymbols();
107.147 - classes = buildLocalClasses();
107.148 - if (publicSymbols != null) {
107.149 - // Mark all other symbols private!
107.150 - Set<String> names = new HashSet<>(publicSymbols.size() + 1);
107.151 - names.add("__all__"); // __all__ itself is exported!
107.152 - for (Str str : publicSymbols) {
107.153 - String name = PythonAstUtils.getStrContent(str);
107.154 - if (name != null) {
107.155 - names.add(name);
107.156 - }
107.157 - }
107.158 -
107.159 - ScopeInfo topScope = scopes.get(root);
107.160 - if (topScope != null) {
107.161 - for (Map.Entry<String, SymInfo> entry : topScope.tbl.entrySet()) {
107.162 - String name = entry.getKey();
107.163 - if (!names.contains(name)) {
107.164 - SymInfo sym = entry.getValue();
107.165 - sym.flags |= PRIVATE;
107.166 - if (sym.isDef() && sym.node != null) {
107.167 - ScopeInfo scope = scopes.get(sym.node);
107.168 - scope.hidden = true;
107.169 - }
107.170 - }
107.171 - }
107.172 - }
107.173 -
107.174 - for (Map.Entry<PythonTree, ScopeInfo> entry : scopes.entrySet()) {
107.175 - ScopeInfo scope = entry.getValue();
107.176 - boolean isHidden = false;
107.177 - ScopeInfo curr = scope;
107.178 - while (curr != null) {
107.179 - if (curr.hidden) {
107.180 - isHidden = true;
107.181 - break;
107.182 - }
107.183 - if (curr.nested != null) {
107.184 - curr = curr.nested;
107.185 - } else {
107.186 - curr = curr.up;
107.187 - }
107.188 -
107.189 - }
107.190 - if (isHidden) {
107.191 - scope.hidden = true;
107.192 - }
107.193 - }
107.194 -
107.195 - // Mark all symbols private, unless the scope is a direct descendant
107.196 - // of a public symbol
107.197 - for (ScopeInfo scope : scopes.values()) {
107.198 - if (scope.hidden) {
107.199 - for (SymInfo sym : scope.tbl.values()) {
107.200 - sym.flags |= PRIVATE;
107.201 - }
107.202 - }
107.203 - }
107.204 - }
107.205 - } catch (Exception ex) {
107.206 - Exceptions.printStackTrace(ex);
107.207 - }
107.208 - }
107.209 - }
107.210 -
107.211 - public boolean isPrivate(PythonTree node, String name) {
107.212 - ScopeInfo scope = scopes.get(node);
107.213 - if (scope == null) {
107.214 - scope = scopes.get(root);
107.215 - }
107.216 - if (scope != null) {
107.217 - if (scope.up != null) {
107.218 - if (scope.hidden) {
107.219 - return true;
107.220 - }
107.221 - // Look in parent's scope table
107.222 - if (scope.nested != null) {
107.223 - scope = scope.nested;
107.224 - } else {
107.225 - scope = scope.up;
107.226 - }
107.227 - if (scope != null) {
107.228 - SymInfo sym = scope.tbl.get(name);
107.229 - if (sym != null) {
107.230 - return sym.isPrivate();
107.231 - }
107.232 - }
107.233 - } else {
107.234 - SymInfo sym = scope.tbl.get(name);
107.235 - if (sym != null) {
107.236 - return sym.isPrivate();
107.237 - }
107.238 - }
107.239 - }
107.240 -
107.241 - return false;
107.242 - }
107.243 -
107.244 - public SymInfo findDeclaration(PythonTree scope, String name, boolean allowFree) {
107.245 - ScopeInfo scopeInfo = getScopeInfo(scope);
107.246 - if (scopeInfo != null) {
107.247 - SymInfo sym = scopeInfo.tbl.get(name);
107.248 - SymInfo orig = sym;
107.249 - while (sym != null && sym.isFree()) {
107.250 - scopeInfo = scopeInfo.up;
107.251 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
107.252 - scopeInfo = scopeInfo.up;
107.253 - }
107.254 - sym = scopeInfo.tbl.get(name);
107.255 - }
107.256 -
107.257 - if (allowFree && sym == null && orig != null) {
107.258 - // Free variable -- might have to resolve it
107.259 - return orig;
107.260 - }
107.261 -
107.262 - // Look for attributes too
107.263 - if (sym == null) {
107.264 - sym = scopeInfo.attributes.get(name);
107.265 - orig = sym;
107.266 - while (sym != null && sym.isFree()) {
107.267 - scopeInfo = scopeInfo.up;
107.268 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
107.269 - scopeInfo = scopeInfo.up;
107.270 - }
107.271 - sym = scopeInfo.tbl.get(name);
107.272 - }
107.273 -
107.274 - if (allowFree && sym == null && orig != null) {
107.275 - // Free variable -- might have to resolve it
107.276 - return orig;
107.277 - }
107.278 - }
107.279 -
107.280 - return sym;
107.281 - }
107.282 -
107.283 - return null;
107.284 - }
107.285 -
107.286 - public ScopeInfo getScopeInfo(PythonTree node) {
107.287 - return scopes.get(node);
107.288 - }
107.289 -
107.290 - public List<Error> getErrors() {
107.291 - return errors != null ? errors : Collections.<Error>emptyList();
107.292 - }
107.293 -
107.294 - public SymInfo findBySignature(ElementKind kind, String signature) {
107.295 - PythonTree scope = root;
107.296 - String name = signature;
107.297 - int dot = signature.lastIndexOf('.');
107.298 - if (dot != -1) {
107.299 - String clz = signature.substring(0, dot);
107.300 - name = signature.substring(dot + 1);
107.301 - SymInfo sym = findDeclaration(root, clz, true);
107.302 - if (sym != null && sym.node != null) {
107.303 - scope = sym.node;
107.304 - }
107.305 - }
107.306 - SymInfo sym = findDeclaration(scope, name, true);
107.307 -
107.308 - return sym;
107.309 - }
107.310 -
107.311 - private List<String> getModulesToStarImport() {
107.312 - List<String> modules = new ArrayList<>();
107.313 -
107.314 - for (ImportFrom from : importsFrom) {
107.315 - List<alias> names = from.getInternalNames();
107.316 - if (names != null) {
107.317 - for (alias at : names) {
107.318 - if ("*".equals(at.getInternalName())) { // NOI18N
107.319 - modules.add(from.getInternalModule());
107.320 - }
107.321 - }
107.322 - }
107.323 - }
107.324 -
107.325 - modules.addAll(PythonIndex.BUILTIN_MODULES);
107.326 -
107.327 - return modules;
107.328 - }
107.329 -
107.330 - private void addSymbolsFromModule(PythonParserResult info, String module, String prefix, QuerySupport.Kind kind, Set<? super IndexedElement> result) {
107.331 - if (PythonIndex.isBuiltinModule(module)) {
107.332 - Set<IndexedElement> all = getAllSymbolsFromModule(info, module);
107.333 - for (IndexedElement e : all) {
107.334 - if (kind == QuerySupport.Kind.PREFIX) {
107.335 - if (e.getName().startsWith(prefix)) {
107.336 - result.add(e);
107.337 - }
107.338 - } else if (kind == QuerySupport.Kind.EXACT) {
107.339 - if (prefix.equals(e.getName())) {
107.340 - result.add(e);
107.341 - }
107.342 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
107.343 - if (e.getName().regionMatches(true, 0, prefix, 0, prefix.length())) {
107.344 - result.add(e);
107.345 - }
107.346 - }
107.347 - }
107.348 - } else {
107.349 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
107.350 - Set<IndexedElement> elements = index.getImportedElements(prefix, kind, Collections.singleton(module), null);
107.351 - for (IndexedElement e : elements) {
107.352 - result.add(e);
107.353 - }
107.354 - }
107.355 - }
107.356 -
107.357 - private Set<IndexedElement> getAllSymbolsFromModule(PythonParserResult info, String module) {
107.358 - Set<IndexedElement> elements = importedElements.get(module);
107.359 - if (elements == null) {
107.360 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
107.361 - Set<String> systemHolder = new HashSet<>(3);
107.362 - elements = index.getImportedElements("", QuerySupport.Kind.PREFIX, Collections.singleton(module), systemHolder);
107.363 - // Cache system modules - don't cache local modules
107.364 - if (!systemHolder.isEmpty()) {
107.365 - importedElements.put(module, elements);
107.366 - }
107.367 - }
107.368 -
107.369 - return elements;
107.370 - }
107.371 -
107.372 - public Set<Element> getDefinedElements(PythonParserResult info, PythonTree scope, String prefix, QuerySupport.Kind kind) {
107.373 - Set<Element> elements = new HashSet<>(300);
107.374 - ScopeInfo scopeInfo = scopes.get(scope);
107.375 - String module = PythonUtils.getModuleName(fileObject);
107.376 - String url = fileObject.toURL().toExternalForm();
107.377 -
107.378 - // Get builtin symbols
107.379 - for (String mod : getModulesToStarImport()) {
107.380 - addSymbolsFromModule(info, mod, prefix, kind, elements);
107.381 - }
107.382 -
107.383 - // I can't just search the scope table for all variables in scope because this
107.384 - // will only include the local -bound- variables and the -used- free variables.
107.385 - // I need to find potential free variables as well. This means I should walk up
107.386 - // the scope chain and compute all eligible names. By keep track of the ones I've
107.387 - // already added I avoid adding references to variables I have re-bound in closer
107.388 - // scopes.
107.389 -
107.390 - Set<String> added = new HashSet<>();
107.391 -
107.392 - while (scopeInfo != null) {
107.393 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
107.394 - String name = entry.getKey();
107.395 - if (added.contains(name)) {
107.396 - // Something in narrower scope already processed this one
107.397 - continue;
107.398 - }
107.399 - if (kind == QuerySupport.Kind.EXACT) {
107.400 - if (!(name.equals(prefix))) {
107.401 - continue;
107.402 - }
107.403 - } else if (kind == QuerySupport.Kind.PREFIX) {
107.404 - if (!name.startsWith(prefix)) {
107.405 - continue;
107.406 - }
107.407 - } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
107.408 - if (!name.regionMatches(true, 0, prefix, 0, prefix.length())) {
107.409 - continue;
107.410 - }
107.411 - }
107.412 - SymInfo sym = entry.getValue();
107.413 -
107.414 - ScopeInfo curr = scopeInfo;
107.415 - while (sym != null && sym.isFree()) {
107.416 - curr = curr.up;
107.417 - while (curr != null && curr.kind == CLASSSCOPE) {
107.418 - curr = curr.up;
107.419 - }
107.420 - if (curr == null) {
107.421 - sym = null;
107.422 - break;
107.423 - }
107.424 - sym = scopeInfo.tbl.get(name);
107.425 - }
107.426 - if (sym == null) {
107.427 - continue;
107.428 - }
107.429 - if (sym.isUnresolved()) {
107.430 - // Don't add completion items for stuff we're not sure about
107.431 - continue;
107.432 - }
107.433 -
107.434 - PythonTree node = sym.node;
107.435 - if (node == null) {
107.436 - continue;
107.437 - }
107.438 -
107.439 -
107.440 - if (sym.isImported()) {
107.441 - Element element = new AstElement(this, node, name, Character.isUpperCase(name.charAt(0)) ? ElementKind.CLASS : ElementKind.MODULE);
107.442 - elements.add(element);
107.443 - } else if (sym.isDef()) {
107.444 - String signature;
107.445 - if (sym.isClass() && node instanceof ClassDef) {
107.446 - signature = PythonIndexer.computeClassSig((ClassDef)node, sym);
107.447 - } else if (sym.isFunction() && node instanceof FunctionDef) {
107.448 - assert sym.isFunction() && node instanceof FunctionDef : name + ";" + sym + " in " + module;
107.449 - signature = PythonIndexer.computeFunctionSig(name, (FunctionDef)node, sym);
107.450 - } else {
107.451 - // Probably a generator expression
107.452 - continue;
107.453 - }
107.454 - //Element element = AstElement.create(null, node);
107.455 - IndexedElement element = IndexedElement.create(signature, module, url, null);
107.456 - element.setSmart(true);
107.457 - elements.add(element);
107.458 - } else {
107.459 - // TODO - class attributes?
107.460 - Element element = new AstElement(this, node, name, ElementKind.VARIABLE);
107.461 - elements.add(element);
107.462 - }
107.463 -
107.464 - added.add(name);
107.465 - }
107.466 -
107.467 - scopeInfo = scopeInfo.up;
107.468 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
107.469 - scopeInfo = scopeInfo.up;
107.470 - }
107.471 - }
107.472 -
107.473 - return elements;
107.474 - }
107.475 -
107.476 - // Return all node references to the given name
107.477 - // This will include imports, calls, definitions, etc.
107.478 - public List<PythonTree> getOccurrences(PythonTree scope, String name, boolean abortOnFree) {
107.479 - ScopeInfo scopeInfo = scopes.get(scope);
107.480 - if (scopeInfo != null) {
107.481 - SymInfo sym = scopeInfo.tbl.get(name);
107.482 - while (sym != null && sym.isFree()) {
107.483 - if (abortOnFree) {
107.484 - return null;
107.485 - }
107.486 - scopeInfo = scopeInfo.up;
107.487 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
107.488 - scopeInfo = scopeInfo.up;
107.489 - }
107.490 - sym = scopeInfo.tbl.get(name);
107.491 - }
107.492 -
107.493 - if (sym != null) {
107.494 - NameNodeFinder finder = new NameNodeFinder(name, scopeInfo.scope_node);
107.495 - finder.run();
107.496 - return finder.getNodes();
107.497 - }
107.498 - }
107.499 -
107.500 - return Collections.emptyList();
107.501 - }
107.502 -
107.503 - /** Return a list of the variables visible from a given scope */
107.504 - public Set<String> getVarNames(PythonTree scope, boolean mustBeBound) {
107.505 - ScopeInfo scopeInfo = scopes.get(scope);
107.506 - Set<String> names = new HashSet<>();
107.507 - while (scopeInfo != null) {
107.508 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
107.509 - String name = entry.getKey();
107.510 - SymInfo sym = entry.getValue();
107.511 - if (sym.isVariable(mustBeBound)) {
107.512 - names.add(name);
107.513 - }
107.514 - }
107.515 - scopeInfo = scopeInfo.up;
107.516 - while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
107.517 - scopeInfo = scopeInfo.up;
107.518 - }
107.519 - }
107.520 -
107.521 - return names;
107.522 - }
107.523 -
107.524 - public List<ImportEntry> getUnusedImports() {
107.525 - List<ImportEntry> unused = new ArrayList<>();
107.526 - ScopeInfo scopeInfo = scopes.get(root);
107.527 - for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
107.528 - SymInfo sym = entry.getValue();
107.529 - if (sym.isImported() && !sym.isRead()) {
107.530 - String name = entry.getKey();
107.531 - if (name.equals("*")) { // NOI18N
107.532 - // Not detecting usages of wildcard imports yet...
107.533 - continue;
107.534 - }
107.535 - PythonTree node = sym.node;
107.536 - if (node instanceof Import) {
107.537 - Import imp = (Import)node;
107.538 - int ordinal = 0;
107.539 - String module = null;
107.540 - String asName = null;
107.541 - List<alias> names = imp.getInternalNames();
107.542 - if (names != null) {
107.543 - for (alias at : names) {
107.544 - if (name.equals(at.getInternalAsname())) {
107.545 - module = at.getInternalName();
107.546 - asName = at.getInternalAsname();
107.547 - break;
107.548 - } else if (name.equals(at.getInternalName())) {
107.549 - module = at.getInternalName();
107.550 - break;
107.551 - }
107.552 - }
107.553 - if (module == null) {
107.554 - // For imports with dotted names, like wsgiref.handlers,
107.555 - // the symbol table entry is just "wsgiref", yet I have to match
107.556 - // the symbols, so try again more carefully
107.557 - for (alias at : names) {
107.558 - if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
107.559 - at.getInternalAsname().charAt(name.length()) == '.') {
107.560 - module = at.getInternalName();
107.561 - asName = at.getInternalAsname();
107.562 - break;
107.563 - } else if (at.getInternalName().startsWith(name) &&
107.564 - at.getInternalName().charAt(name.length()) == '.') {
107.565 - module = at.getInternalName();
107.566 - break;
107.567 - }
107.568 - }
107.569 - }
107.570 - }
107.571 - unused.add(new ImportEntry(module, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
107.572 - } else if (node instanceof ImportFrom) {
107.573 - ImportFrom imp = (ImportFrom)node;
107.574 - if (ImportManager.isFutureImport(imp)) {
107.575 - continue;
107.576 - }
107.577 - String module = imp.getInternalModule();
107.578 - String origName = null;
107.579 - String asName = null;
107.580 - int ordinal = 0;
107.581 - List<alias> names = imp.getInternalNames();
107.582 - if (names != null) {
107.583 - for (alias at : names) {
107.584 - if (name.equals(at.getInternalAsname())) {
107.585 - origName = at.getInternalName();
107.586 - asName = at.getInternalAsname();
107.587 - break;
107.588 - } else if (name.equals(at.getInternalName())) {
107.589 - origName = at.getInternalName();
107.590 - break;
107.591 - }
107.592 - }
107.593 - if (origName == null) {
107.594 - // For imports with dotted names, like wsgiref.handlers,
107.595 - // the symbol table entry is just "wsgiref", yet I have to match
107.596 - // the symbols, so try again more carefully
107.597 - for (alias at : names) {
107.598 - if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
107.599 - at.getInternalAsname().charAt(name.length()) == '.') {
107.600 - origName = at.getInternalName();
107.601 - asName = at.getInternalAsname();
107.602 - break;
107.603 - } else if (at.getInternalName().startsWith(name) &&
107.604 - at.getInternalName().charAt(name.length()) == '.') {
107.605 - origName = at.getInternalName();
107.606 - break;
107.607 - }
107.608 - }
107.609 - }
107.610 - }
107.611 - unused.add(new ImportEntry(module, origName, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
107.612 - }
107.613 - }
107.614 - }
107.615 -
107.616 - return unused;
107.617 - }
107.618 -
107.619 - private class NameNodeFinder extends Visitor {
107.620 - private List<PythonTree> nodes = new ArrayList<>();
107.621 - private PythonTree startScope;
107.622 - private String name;
107.623 -
107.624 - public NameNodeFinder(String name, PythonTree startScope) {
107.625 - this.name = name;
107.626 - this.startScope = startScope;
107.627 - }
107.628 -
107.629 - public void run() {
107.630 - try {
107.631 - visit(startScope);
107.632 - } catch (Exception ex) {
107.633 - Exceptions.printStackTrace(ex);
107.634 - }
107.635 - }
107.636 -
107.637 - @Override
107.638 - public Object visitImport(Import imp) throws Exception {
107.639 - List<alias> names = imp.getInternalNames();
107.640 - if (names != null && names.size() > 0) {
107.641 - boolean found = false;
107.642 - for (alias at : names) {
107.643 - String asName = at.getInternalAsname();
107.644 - if (asName != null) {
107.645 - if (name.equals(asName)) {
107.646 - found = true;
107.647 - break;
107.648 - }
107.649 - } else if (name.equals(at.getInternalName())) {
107.650 - found = true;
107.651 - break;
107.652 - }
107.653 - }
107.654 - if (found) {
107.655 - nodes.add(imp);
107.656 - }
107.657 - }
107.658 - return super.visitImport(imp);
107.659 - }
107.660 -
107.661 - @Override
107.662 - public Object visitImportFrom(ImportFrom imp) throws Exception {
107.663 - List<alias> names = imp.getInternalNames();
107.664 - if (names != null && names.size() > 0) {
107.665 - boolean found = false;
107.666 - for (alias at : names) {
107.667 - String asName = at.getInternalAsname();
107.668 - if (asName != null) {
107.669 - if (name.equals(asName)) {
107.670 - found = true;
107.671 - break;
107.672 - }
107.673 - } else if (name.equals(at.getInternalName())) {
107.674 - found = true;
107.675 - break;
107.676 - }
107.677 - }
107.678 - if (found) {
107.679 - nodes.add(imp);
107.680 - }
107.681 - }
107.682 -
107.683 - return super.visitImportFrom(imp);
107.684 - }
107.685 -
107.686 - @Override
107.687 - public Object visitName(Name node) throws Exception {
107.688 - if (node.getInternalId().equals(name)) {
107.689 - nodes.add(node);
107.690 - }
107.691 - return super.visitName(node);
107.692 - }
107.693 -
107.694 - @Override
107.695 - public Object visitFunctionDef(FunctionDef node) throws Exception {
107.696 - if (name.equals(node.getInternalName())) {
107.697 - nodes.add(node);
107.698 - }
107.699 -
107.700 - if (isIncludedScope(node)) {
107.701 - return super.visitFunctionDef(node);
107.702 - } else {
107.703 - return null;
107.704 - }
107.705 - }
107.706 -
107.707 - @Override
107.708 - public Object visitClassDef(ClassDef node) throws Exception {
107.709 - if (name.equals(node.getInternalName())) {
107.710 - nodes.add(node);
107.711 - }
107.712 -
107.713 - if (isIncludedScope(node)) {
107.714 - return super.visitClassDef(node);
107.715 - } else {
107.716 - return null;
107.717 - }
107.718 - }
107.719 -
107.720 - @Override
107.721 - public Object visitExpression(Expression node) throws Exception {
107.722 - if (isIncludedScope(node)) {
107.723 - return super.visitExpression(node);
107.724 - } else {
107.725 - return null;
107.726 - }
107.727 - }
107.728 -
107.729 - @Override
107.730 - public Object visitInteractive(Interactive node) throws Exception {
107.731 - if (isIncludedScope(node)) {
107.732 - return super.visitInteractive(node);
107.733 - } else {
107.734 - return null;
107.735 - }
107.736 - }
107.737 -
107.738 - @Override
107.739 - public Object visitLambda(Lambda node) throws Exception {
107.740 - if (isIncludedScope(node)) {
107.741 - return super.visitLambda(node);
107.742 - } else {
107.743 - return null;
107.744 - }
107.745 - }
107.746 -
107.747 - @Override
107.748 - public Object visitGeneratorExp(GeneratorExp node) throws Exception {
107.749 - if (isIncludedScope(node)) {
107.750 - return super.visitGeneratorExp(node);
107.751 - } else {
107.752 - return null;
107.753 - }
107.754 - }
107.755 -
107.756 - private boolean isIncludedScope(PythonTree node) {
107.757 - if (node == startScope) {
107.758 - return true;
107.759 - }
107.760 -
107.761 - ScopeInfo info = scopes.get(node);
107.762 - if (info == null) {
107.763 - return false;
107.764 - }
107.765 -
107.766 - SymInfo sym = info.tbl.get(name);
107.767 - // Skip scopes that redefine the variable
107.768 - if (sym != null && sym.isBound()) {
107.769 - return false;
107.770 - }
107.771 -
107.772 - return true;
107.773 - }
107.774 -
107.775 - public List<PythonTree> getNodes() {
107.776 - return nodes;
107.777 - }
107.778 - }
107.779 -
107.780 - public Map<String, SymInfo> getUnresolvedNames(PythonParserResult info) {
107.781 - Map<String, SymInfo> unresolved = new HashMap<>();
107.782 - Set<String> builtin = getBuiltin(info);
107.783 -
107.784 - for (ScopeInfo scopeInfo : scopes.values()) {
107.785 - Map<String, SymInfo> tbl = scopeInfo.tbl;
107.786 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
107.787 - SymInfo symInfo = entry.getValue();
107.788 - boolean isUnresolved = symInfo.isUnresolved();
107.789 - if (!isUnresolved && symInfo.isFree()) {
107.790 - // Peek up scope stack
107.791 - String name = entry.getKey();
107.792 - SymInfo sym = symInfo;
107.793 - ScopeInfo scope = scopeInfo;
107.794 - while (sym != null && sym.isFree()) {
107.795 - scope = scope.up;
107.796 - while (scope != null && scope.kind == CLASSSCOPE) {
107.797 - scope = scope.up;
107.798 - }
107.799 - sym = scope.tbl.get(name);
107.800 - }
107.801 - if (sym == null) {
107.802 - isUnresolved = true;
107.803 - } else {
107.804 - isUnresolved = sym.isUnresolved();
107.805 - }
107.806 - }
107.807 - if (isUnresolved) {
107.808 - String key = entry.getKey();
107.809 - if (!builtin.contains(key)) {
107.810 - unresolved.put(key, symInfo);
107.811 - }
107.812 - }
107.813 - }
107.814 - }
107.815 -
107.816 - return unresolved;
107.817 - }
107.818 -
107.819 - public List<Attribute> getNotInInitAttributes(PythonParserResult info) {
107.820 - List<Attribute> notInInitAttribs = new ArrayList<>();
107.821 - for (ScopeInfo scopeInfo : scopes.values()) {
107.822 - if (scopeInfo.scope_node instanceof ClassDef) {
107.823 - if (scopeInfo.attributes != null) {
107.824 - for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
107.825 - SymInfo symInfo = entry.getValue();
107.826 - if (!symInfo.isBoundInConstructor()) {
107.827 - notInInitAttribs.add((Attribute)symInfo.node);
107.828 - }
107.829 - }
107.830 - }
107.831 - }
107.832 - }
107.833 - return notInInitAttribs;
107.834 - }
107.835 -
107.836 - private ScopeInfo getClassScope(String className) {
107.837 - for (ScopeInfo scopeInfo : scopes.values()) {
107.838 - if (scopeInfo.scope_node instanceof ClassDef) {
107.839 - ClassDef curClass = (ClassDef)scopeInfo.scope_node;
107.840 - if (curClass.getInternalName().equals(className)) {
107.841 - return scopeInfo;
107.842 - }
107.843 - }
107.844 - }
107.845 - return null;
107.846 - }
107.847 -
107.848 - private int belongsToParents(ClassDef cls, String name, HashMap<String, String> cycling) {
107.849 - List<expr> bases = cls.getInternalBases();
107.850 - if (bases == null || bases.size() == 0) {
107.851 - return NO; // no parents
107.852 - }
107.853 - for (expr base : bases) {
107.854 - String className = null;
107.855 - if (base instanceof Name) {
107.856 - className = ((Name)base).getInternalId();
107.857 - } else {
107.858 - // should be Attribute here( module.className form )
107.859 - // which imply imported from external scope
107.860 - // So we give up on scope returning optimistaically True
107.861 - return YES;
107.862 - }
107.863 - assert (className != null);
107.864 - if (cycling.get(className) != null) {
107.865 - cycling.clear();
107.866 - // put parent child conficting back in cycling
107.867 - cycling.put(className, cls.getInternalName());
107.868 - return CIRCULAR;
107.869 - }
107.870 - cycling.put(className, className);
107.871 - ScopeInfo localClassScope = getClassScope(className);
107.872 - if (localClassScope == null) {
107.873 - // return true (success) when at least one parent is outside module scope
107.874 - // just to notify caller to be optimistic and assume that
107.875 - // name is resolved by imported classes inheritance
107.876 - // scanning imported classed from here is discouraged for
107.877 - // performances reasons
107.878 - return YES;
107.879 - } else {
107.880 - if ((name != null) &&
107.881 - (localClassScope.attributes.get(name) != null)) {
107.882 - return YES;
107.883 - }
107.884 - // try recurse parentage to resolve attribute
107.885 - ClassDef parentClass = (ClassDef)localClassScope.scope_node;
107.886 - int recResult = belongsToParents(parentClass, name, cycling);
107.887 - if (recResult != NO) // stop on FOUND(YES) or CIRCULAR error
107.888 - {
107.889 - return recResult;
107.890 - }
107.891 - }
107.892 - }
107.893 - return NO;
107.894 - }
107.895 -
107.896 - private boolean isImported(String moduleName) {
107.897 - for (Import imported : imports) {
107.898 - List<alias> names = imported.getInternalNames();
107.899 - if (names != null) {
107.900 - for (alias cur : names) {
107.901 - String name = cur.getInternalName();
107.902 - String asName = cur.getInternalAsname();
107.903 - if (((name != null) && (name.equals(moduleName))) ||
107.904 - ((asName != null) && (asName.equals(moduleName)))) {
107.905 - return true;
107.906 - }
107.907 - }
107.908 - }
107.909 - }
107.910 - return false;
107.911 - }
107.912 -
107.913 - private boolean isImportedFrom(String className) {
107.914 - for (ImportFrom importedFrom : importsFrom) {
107.915 - List<alias> names = importedFrom.getInternalNames();
107.916 - if (names != null) {
107.917 - for (alias cur : names) {
107.918 - String name = cur.getInternalName();
107.919 - String asName = cur.getInternalAsname();
107.920 - if (((name != null) && (name.equals(className))) ||
107.921 - ((asName != null) && (asName.equals(className)))) {
107.922 - return true;
107.923 - }
107.924 - }
107.925 - }
107.926 - }
107.927 - return false;
107.928 - }
107.929 -
107.930 - public List<PythonTree> getUnresolvedParents(PythonParserResult info) {
107.931 - // deal with unresolved parents in inherit trees
107.932 - List<PythonTree> unresolvedParents = new ArrayList<>();
107.933 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
107.934 -
107.935 - for (String cur : classes.keySet()) {
107.936 - ClassDef cls = classes.get(cur);
107.937 - List<expr> bases = cls.getInternalBases();
107.938 - if (bases == null || bases.size() > 0) {
107.939 - // has parents
107.940 - for (expr base : bases) {
107.941 - if (base instanceof Name) {
107.942 - String className = ((Name)base).getInternalId();
107.943 - Set<String> builtin = getBuiltin(info);
107.944 - if ((!classes.containsKey(className)) &&
107.945 - (!builtin.contains(className))) {
107.946 - // check in from imports
107.947 - if (!isImportedFrom(className)) {
107.948 - unresolvedParents.add(base);
107.949 - }
107.950 - }
107.951 - } else {
107.952 - // should be Attribute here( module.className form )
107.953 - // which imply imported from external scope
107.954 - Attribute attr = (Attribute)base;
107.955 - String clsName = attr.getInternalAttr();
107.956 - if (attr.getInternalValue() instanceof Name) {
107.957 - String moduleName = ((Name)(attr.getInternalValue())).getInternalId();
107.958 - // check that import is resolved first
107.959 - if (!isImported(moduleName)) {
107.960 - unresolvedParents.add(base);
107.961 - } else {
107.962 - Set<IndexedElement> found = index.getImportedElements(clsName, QuerySupport.Kind.EXACT, Collections.<String>singleton(moduleName), null);
107.963 - if (found.size() == 0) {
107.964 - unresolvedParents.add(base);
107.965 - }
107.966 - }
107.967 - } else {
107.968 - unresolvedParents.add(base);
107.969 - }
107.970 - }
107.971 - }
107.972 - }
107.973 - }
107.974 - return unresolvedParents;
107.975 - }
107.976 -
107.977 - public HashMap<ClassDef, String> getClassesCyclingRedundancies(PythonParserResult info) {
107.978 - HashMap<ClassDef, String> cyclingRedundancies = new HashMap<>();
107.979 - for (String cur : classes.keySet()) {
107.980 - HashMap<String, String> returned = new HashMap<>();
107.981 - ClassDef curClass = classes.get(cur);
107.982 - if (!cyclingRedundancies.containsKey(curClass)) {
107.983 - if (belongsToParents(curClass, null, returned) == CIRCULAR) {
107.984 - // store hashMap returned
107.985 - Map.Entry<String, String> cycling = returned.entrySet().iterator().next();
107.986 - cyclingRedundancies.put(curClass, cycling.getKey());
107.987 - }
107.988 - }
107.989 - }
107.990 - return cyclingRedundancies;
107.991 - }
107.992 -
107.993 - public List<PythonTree> getUnresolvedAttributes(PythonParserResult info) {
107.994 - List<PythonTree> unresolvedNodes = new ArrayList<>();
107.995 - for (ScopeInfo scopeInfo : scopes.values()) {
107.996 - Set<String> unresolved = new HashSet<>();
107.997 - Map<String, SymInfo> tbl = scopeInfo.tbl;
107.998 - // unresolved attributes in local classes
107.999 - Map<String, SymInfo> attribs = scopeInfo.attributes;
107.1000 - for (Map.Entry<String, SymInfo> curAttr : attribs.entrySet()) {
107.1001 - SymInfo symInfo = curAttr.getValue();
107.1002 - if (symInfo.isRead()) {
107.1003 - // check for builtin attribs first
107.1004 - if (classAttributes.get(curAttr.getKey()) == null) {
107.1005 - // not a builtin attribute
107.1006 - ScopeInfo parentScope = scopeInfo.getClassScope();
107.1007 - if (parentScope != null) {
107.1008 - // limit scope to Classes for self and inherited
107.1009 - Map<String, SymInfo> parentattribs = parentScope.attributes;
107.1010 - SymInfo classAttr = parentattribs.get(curAttr.getKey());
107.1011 - tbl = parentScope.tbl;
107.1012 - if (classAttr == null) {
107.1013 - // may be also a reference to a method
107.1014 - classAttr = tbl.get(curAttr.getKey());
107.1015 - }
107.1016 - if (classAttr == null) {
107.1017 - // do not bother with method since they are
107.1018 - // managed by completion
107.1019 - ClassDef curClass = (ClassDef)parentScope.scope_node;
107.1020 - if (belongsToParents(curClass, curAttr.getKey(), new HashMap()) == NO) {
107.1021 - if (!symInfo.isCalled()) {
107.1022 - // no corresponding attributes
107.1023 - //PythonTree tree = symInfo.node ;
107.1024 - Attribute attr = (Attribute)symInfo.node;
107.1025 - // Name name = new Name(tree.getToken(),attr.getInternalAttr(),attr.ctx) ;
107.1026 - unresolvedNodes.add(attr);
107.1027 - }
107.1028 - }
107.1029 - }
107.1030 - }
107.1031 - }
107.1032 - }
107.1033 - }
107.1034 - if (unresolved.size() > 0) {
107.1035 - NameFinder finder = new NameFinder(unresolved);
107.1036 - List<Name> nodes = finder.run(scopeInfo.scope_node);
107.1037 - unresolvedNodes.addAll(nodes);
107.1038 - }
107.1039 -
107.1040 - }
107.1041 -
107.1042 - if (unresolvedNodes.size() > 1) {
107.1043 - Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
107.1044 - //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
107.1045 - }
107.1046 -
107.1047 - return unresolvedNodes;
107.1048 - }
107.1049 -
107.1050 - public List<PythonTree> getUnresolved(PythonParserResult info) {
107.1051 - List<PythonTree> unresolvedNodes = new ArrayList<>();
107.1052 - Set<String> builtin = getBuiltin(info);
107.1053 -
107.1054 - for (ScopeInfo scopeInfo : scopes.values()) {
107.1055 - Set<String> unresolved = new HashSet<>();
107.1056 - Map<String, SymInfo> tbl = scopeInfo.tbl;
107.1057 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
107.1058 - SymInfo symInfo = entry.getValue();
107.1059 - boolean isUnresolved = symInfo.isUnresolved();
107.1060 - if (!isUnresolved && symInfo.isFree()) {
107.1061 - // Peek up scope stack
107.1062 - String name = entry.getKey();
107.1063 - SymInfo sym = symInfo;
107.1064 - ScopeInfo scope = scopeInfo;
107.1065 - while (sym != null && sym.isFree()) {
107.1066 - scope = scope.up;
107.1067 - while (scope != null && scope.kind == CLASSSCOPE) {
107.1068 - scope = scope.up;
107.1069 - }
107.1070 - sym = scope.tbl.get(name);
107.1071 - }
107.1072 - if (sym == null) {
107.1073 - isUnresolved = true;
107.1074 - } else {
107.1075 - isUnresolved = sym.isUnresolved();
107.1076 - }
107.1077 - }
107.1078 - if (isUnresolved) {
107.1079 - String key = entry.getKey();
107.1080 - if (!builtin.contains(key)) {
107.1081 - unresolved.add(key);
107.1082 - }
107.1083 - }
107.1084 - }
107.1085 -
107.1086 -
107.1087 - if (unresolved.size() > 0) {
107.1088 - // Check imports and see if it's resolved by existing imports
107.1089 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
107.1090 - // TODO - cache system libraries!
107.1091 - // TODO - make method which doesn't create elements for these guys!
107.1092 -// Set<IndexedElement> elements = index.getImportedElements("", NameKind.PREFIX, PythonIndex.ALL_SCOPE, imports, importsFrom);
107.1093 -// for (IndexedElement e : elements) {
107.1094 -// unresolved.remove(e.getName());
107.1095 -// }
107.1096 - Set<String> wildcarded = index.getImportedFromWildcards(importsFrom);
107.1097 - unresolved.removeAll(wildcarded);
107.1098 -
107.1099 - if (unresolved.size() > 0) {
107.1100 - NameFinder finder = new NameFinder(unresolved);
107.1101 - List<Name> nodes = finder.run(scopeInfo.scope_node);
107.1102 - unresolvedNodes.addAll(nodes);
107.1103 - }
107.1104 - }
107.1105 - }
107.1106 -
107.1107 - if (unresolvedNodes.size() > 1) {
107.1108 - Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
107.1109 - //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
107.1110 - }
107.1111 -
107.1112 - return unresolvedNodes;
107.1113 - }
107.1114 -
107.1115 - public List<PythonTree> getUnused(boolean skipSelf, boolean skipParams) { // not used for unused imports, see separate method
107.1116 - List<PythonTree> unusedNodes = new ArrayList<>();
107.1117 -
107.1118 - for (ScopeInfo scopeInfo : scopes.values()) {
107.1119 - if (scopeInfo.kind != FUNCSCOPE) {
107.1120 - continue;
107.1121 - }
107.1122 - Set<String> unused = new HashSet<>();
107.1123 - Map<String, SymInfo> tbl = scopeInfo.tbl;
107.1124 - for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
107.1125 - SymInfo symInfo = entry.getValue();
107.1126 - if (symInfo.isUnused(scopeInfo) && (!skipParams || !symInfo.isParameter())) {
107.1127 - String key = entry.getKey();
107.1128 - if (skipSelf && "self".equals(key)) { // NOI18N
107.1129 - continue;
107.1130 - }
107.1131 - unused.add(key);
107.1132 - }
107.1133 - }
107.1134 -
107.1135 - if (unused.size() > 0) {
107.1136 - NameFinder finder = new NameFinder(unused);
107.1137 - List<Name> nodes = finder.run(scopeInfo.scope_node);
107.1138 - unusedNodes.addAll(nodes);
107.1139 - }
107.1140 - }
107.1141 -
107.1142 - if (unusedNodes.size() > 1) {
107.1143 - Collections.sort(unusedNodes, PythonUtils.NAME_NODE_COMPARATOR);
107.1144 - //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
107.1145 - }
107.1146 -
107.1147 - return unusedNodes;
107.1148 - }
107.1149 -
107.1150 - private static class NameFinder extends Visitor {
107.1151 - private Set<String> names;
107.1152 - private List<Name> nodes = new ArrayList<>();
107.1153 - private PythonTree acceptDef;
107.1154 -
107.1155 - private NameFinder(Set<String> names) {
107.1156 - this.names = names;
107.1157 - }
107.1158 -
107.1159 - @Override
107.1160 - public Object visitClassDef(ClassDef node) throws Exception {
107.1161 - // Don't look in nested scopes
107.1162 - if (node != acceptDef) {
107.1163 - return null;
107.1164 - }
107.1165 - return super.visitClassDef(node);
107.1166 - }
107.1167 -
107.1168 - @Override
107.1169 - public Object visitFunctionDef(FunctionDef node) throws Exception {
107.1170 - // Don't look in nested scopes
107.1171 - if (node != acceptDef) {
107.1172 - return null;
107.1173 - }
107.1174 - return super.visitFunctionDef(node);
107.1175 - }
107.1176 -
107.1177 - @Override
107.1178 - public Object visitName(Name node) throws Exception {
107.1179 - String name = node.getInternalId();
107.1180 - if (names.contains(name)) {
107.1181 - nodes.add(node);
107.1182 - }
107.1183 -
107.1184 - return super.visitName(node);
107.1185 - }
107.1186 -
107.1187 - public List<Name> run(PythonTree node) {
107.1188 - this.acceptDef = node;
107.1189 - try {
107.1190 - visit(node);
107.1191 - } catch (Exception ex) {
107.1192 - Exceptions.printStackTrace(ex);
107.1193 - }
107.1194 -
107.1195 - return nodes;
107.1196 - }
107.1197 - }
107.1198 - private static Set<String> builtinSymbols;
107.1199 -
107.1200 - private Set<String> getBuiltin(PythonParserResult info) {
107.1201 - if (builtinSymbols == null) {
107.1202 - PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
107.1203 - builtinSymbols = index.getBuiltinSymbols();
107.1204 - }
107.1205 -
107.1206 - return builtinSymbols;
107.1207 - }
107.1208 -
107.1209 - public void error(String msg, boolean err, PythonTree node) throws Exception {
107.1210 - assert node != null;
107.1211 - // TODO - record and register with the hints manager?
107.1212 - OffsetRange range = PythonAstUtils.getRange(node);
107.1213 -
107.1214 - if (errors == null) {
107.1215 - errors = new ArrayList<>();
107.1216 - }
107.1217 - Error error = new DefaultError(null, msg, null, fileObject, range.getStart(), range.getEnd(), err ? Severity.ERROR : Severity.WARNING);
107.1218 - errors.add(error);
107.1219 - }
107.1220 -
107.1221 - public String getFilename() {
107.1222 - return FileUtil.getFileDisplayName(fileObject);
107.1223 - }
107.1224 -
107.1225 - public Map<PythonTree, ScopeInfo> getScopes() {
107.1226 - return scopes;
107.1227 - }
107.1228 -
107.1229 - public List<Import> getImports() {
107.1230 - return imports;
107.1231 - }
107.1232 -
107.1233 - public List<ImportFrom> getImportsFrom() {
107.1234 - return importsFrom;
107.1235 - }
107.1236 -
107.1237 - public boolean isTopLevel(PythonTree node) {
107.1238 - return topLevelImports.contains(node);
107.1239 - }
107.1240 -
107.1241 - public List<PythonTree> getMainImports() {
107.1242 - return mainImports;
107.1243 - }
107.1244 -
107.1245 - public Set<PythonTree> getTopLevelImports() {
107.1246 - return topLevelImports;
107.1247 - }
107.1248 -
107.1249 - public List<Str> getPublicSymbols() {
107.1250 - return publicSymbols;
107.1251 - }
107.1252 -}
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
108.2 +++ b/python.hints/build.xml Wed Sep 02 20:31:18 2015 +0200
108.3 @@ -0,0 +1,5 @@
108.4 +<?xml version="1.0" encoding="UTF-8"?>
108.5 +<project basedir="." default="netbeans" name="contrib/python.hints">
108.6 + <description>Builds, tests, and runs the project org.netbeans.modules.python.hints</description>
108.7 + <import file="../../nbbuild/templates/projectized.xml"/>
108.8 +</project>
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
109.2 +++ b/python.hints/manifest.mf Wed Sep 02 20:31:18 2015 +0200
109.3 @@ -0,0 +1,7 @@
109.4 +Manifest-Version: 1.0
109.5 +AutoUpdate-Show-In-Client: true
109.6 +OpenIDE-Module: org.netbeans.modules.python.hints
109.7 +OpenIDE-Module-Layer: org/netbeans/modules/python/hints/layer.xml
109.8 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/python/hints/Bundle.properties
109.9 +OpenIDE-Module-Specification-Version: 1.0
109.10 +
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
110.2 +++ b/python.hints/nbproject/project.properties Wed Sep 02 20:31:18 2015 +0200
110.3 @@ -0,0 +1,2 @@
110.4 +javac.source=1.7
110.5 +javac.compilerargs=-Xlint -Xlint:-serial
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
111.2 +++ b/python.hints/nbproject/project.xml Wed Sep 02 20:31:18 2015 +0200
111.3 @@ -0,0 +1,157 @@
111.4 +<?xml version="1.0" encoding="UTF-8"?>
111.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
111.6 + <type>org.netbeans.modules.apisupport.project</type>
111.7 + <configuration>
111.8 + <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
111.9 + <code-name-base>org.netbeans.modules.python.hints</code-name-base>
111.10 + <module-dependencies>
111.11 + <dependency>
111.12 + <code-name-base>org.jython</code-name-base>
111.13 + <build-prerequisite/>
111.14 + <compile-dependency/>
111.15 + <run-dependency>
111.16 + <release-version>2</release-version>
111.17 + <specification-version>2.12</specification-version>
111.18 + </run-dependency>
111.19 + </dependency>
111.20 + <dependency>
111.21 + <code-name-base>org.netbeans.modules.csl.api</code-name-base>
111.22 + <build-prerequisite/>
111.23 + <compile-dependency/>
111.24 + <run-dependency>
111.25 + <release-version>2</release-version>
111.26 + <specification-version>2.51</specification-version>
111.27 + </run-dependency>
111.28 + </dependency>
111.29 + <dependency>
111.30 + <code-name-base>org.netbeans.modules.editor.codetemplates</code-name-base>
111.31 + <build-prerequisite/>
111.32 + <compile-dependency/>
111.33 + <run-dependency>
111.34 + <release-version>1</release-version>
111.35 + <specification-version>1.41</specification-version>
111.36 + </run-dependency>
111.37 + </dependency>
111.38 + <dependency>
111.39 + <code-name-base>org.netbeans.modules.editor.document</code-name-base>
111.40 + <build-prerequisite/>
111.41 + <compile-dependency/>
111.42 + <run-dependency>
111.43 + <specification-version>1.5</specification-version>
111.44 + </run-dependency>
111.45 + </dependency>
111.46 + <dependency>
111.47 + <code-name-base>org.netbeans.modules.editor.indent</code-name-base>
111.48 + <build-prerequisite/>
111.49 + <compile-dependency/>
111.50 + <run-dependency>
111.51 + <release-version>2</release-version>
111.52 + <specification-version>1.42</specification-version>
111.53 + </run-dependency>
111.54 + </dependency>
111.55 + <dependency>
111.56 + <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
111.57 + <build-prerequisite/>
111.58 + <compile-dependency/>
111.59 + <run-dependency>
111.60 + <release-version>3</release-version>
111.61 + <specification-version>4.3</specification-version>
111.62 + </run-dependency>
111.63 + </dependency>
111.64 + <dependency>
111.65 + <code-name-base>org.netbeans.modules.lexer</code-name-base>
111.66 + <build-prerequisite/>
111.67 + <compile-dependency/>
111.68 + <run-dependency>
111.69 + <release-version>2</release-version>
111.70 + <specification-version>1.62</specification-version>
111.71 + </run-dependency>
111.72 + </dependency>
111.73 + <dependency>
111.74 + <code-name-base>org.netbeans.modules.options.api</code-name-base>
111.75 + <build-prerequisite/>
111.76 + <compile-dependency/>
111.77 + <run-dependency>
111.78 + <release-version>1</release-version>
111.79 + <specification-version>1.44</specification-version>
111.80 + </run-dependency>
111.81 + </dependency>
111.82 + <dependency>
111.83 + <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
111.84 + <build-prerequisite/>
111.85 + <compile-dependency/>
111.86 + <run-dependency>
111.87 + <release-version>1</release-version>
111.88 + <specification-version>9.5</specification-version>
111.89 + </run-dependency>
111.90 + </dependency>
111.91 + <dependency>
111.92 + <code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
111.93 + <build-prerequisite/>
111.94 + <compile-dependency/>
111.95 + <run-dependency>
111.96 + <specification-version>9.7</specification-version>
111.97 + </run-dependency>
111.98 + </dependency>
111.99 + <dependency>
111.100 + <code-name-base>org.netbeans.modules.projectapi</code-name-base>
111.101 + <build-prerequisite/>
111.102 + <compile-dependency/>
111.103 + <run-dependency>
111.104 + <release-version>1</release-version>
111.105 + <specification-version>1.65</specification-version>
111.106 + </run-dependency>
111.107 + </dependency>
111.108 + <dependency>
111.109 + <code-name-base>org.netbeans.modules.python.core</code-name-base>
111.110 + <build-prerequisite/>
111.111 + <compile-dependency/>
111.112 + <run-dependency>
111.113 + <specification-version>1.4</specification-version>
111.114 + </run-dependency>
111.115 + </dependency>
111.116 + <dependency>
111.117 + <code-name-base>org.netbeans.modules.python.editor</code-name-base>
111.118 + <build-prerequisite/>
111.119 + <compile-dependency/>
111.120 + <run-dependency>
111.121 + <specification-version>1.8.2</specification-version>
111.122 + </run-dependency>
111.123 + </dependency>
111.124 + <dependency>
111.125 + <code-name-base>org.netbeans.modules.python.source</code-name-base>
111.126 + <build-prerequisite/>
111.127 + <compile-dependency/>
111.128 + <run-dependency>
111.129 + <specification-version>1.1</specification-version>
111.130 + </run-dependency>
111.131 + </dependency>
111.132 + <dependency>
111.133 + <code-name-base>org.openide.filesystems</code-name-base>
111.134 + <build-prerequisite/>
111.135 + <compile-dependency/>
111.136 + <run-dependency>
111.137 + <specification-version>9.8</specification-version>
111.138 + </run-dependency>
111.139 + </dependency>
111.140 + <dependency>
111.141 + <code-name-base>org.openide.util</code-name-base>
111.142 + <build-prerequisite/>
111.143 + <compile-dependency/>
111.144 + <run-dependency>
111.145 + <specification-version>9.5</specification-version>
111.146 + </run-dependency>
111.147 + </dependency>
111.148 + <dependency>
111.149 + <code-name-base>org.openide.util.lookup</code-name-base>
111.150 + <build-prerequisite/>
111.151 + <compile-dependency/>
111.152 + <run-dependency>
111.153 + <specification-version>8.32</specification-version>
111.154 + </run-dependency>
111.155 + </dependency>
111.156 + </module-dependencies>
111.157 + <public-packages/>
111.158 + </data>
111.159 + </configuration>
111.160 +</project>
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
112.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AccessToProtected.java Wed Sep 02 20:31:18 2015 +0200
112.3 @@ -0,0 +1,150 @@
112.4 +/*
112.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
112.6 + *
112.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
112.8 + *
112.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
112.10 + * Other names may be trademarks of their respective owners.
112.11 + *
112.12 + * The contents of this file are subject to the terms of either the GNU
112.13 + * General Public License Version 2 only ("GPL") or the Common
112.14 + * Development and Distribution License("CDDL") (collectively, the
112.15 + * "License"). You may not use this file except in compliance with the
112.16 + * License. You can obtain a copy of the License at
112.17 + * http://www.netbeans.org/cddl-gplv2.html
112.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
112.19 + * specific language governing permissions and limitations under the
112.20 + * License. When distributing the software, include this License Header
112.21 + * Notice in each file and include the License file at
112.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
112.23 + * particular file as subject to the "Classpath" exception as provided
112.24 + * by Oracle in the GPL Version 2 section of the License file that
112.25 + * accompanied this code. If applicable, add the following below the
112.26 + * License Header, with the fields enclosed by brackets [] replaced by
112.27 + * your own identifying information:
112.28 + * "Portions Copyrighted [year] [name of copyright owner]"
112.29 + *
112.30 + * If you wish your version of this file to be governed by only the CDDL
112.31 + * or only the GPL Version 2, indicate your decision by adding
112.32 + * "[Contributor] elects to include this software in this distribution
112.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
112.34 + * single choice of license, a recipient has the option to distribute
112.35 + * your version of this file under either the CDDL, the GPL Version 2 or
112.36 + * to extend the choice of license to its licensees as provided above.
112.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
112.38 + * Version 2 license, then the option applies only if the new code is
112.39 + * made subject to such option by the copyright holder.
112.40 + *
112.41 + * Contributor(s):
112.42 + *
112.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
112.44 + */
112.45 +package org.netbeans.modules.python.hints;
112.46 +
112.47 +import java.util.Collections;
112.48 +import java.util.List;
112.49 +import java.util.Set;
112.50 +import java.util.prefs.Preferences;
112.51 +import javax.swing.JComponent;
112.52 +import org.netbeans.modules.csl.api.Hint;
112.53 +import org.netbeans.modules.csl.api.HintFix;
112.54 +import org.netbeans.modules.csl.api.HintSeverity;
112.55 +import org.netbeans.modules.csl.api.OffsetRange;
112.56 +import org.netbeans.modules.csl.api.RuleContext;
112.57 +import org.netbeans.modules.python.source.PythonAstUtils;
112.58 +import org.netbeans.modules.python.source.PythonParserResult;
112.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
112.60 +import org.netbeans.modules.python.source.NameStyle;
112.61 +import org.openide.util.NbBundle;
112.62 +import org.python.antlr.ast.Attribute;
112.63 +import org.python.antlr.ast.Name;
112.64 +import org.python.antlr.base.expr;
112.65 +
112.66 +/**
112.67 + * Check direct acces to parent protected variables or methods
112.68 + * @author jean-yves Mengant
112.69 + */
112.70 +public class AccessToProtected extends PythonAstRule {
112.71 + private final static String ACCESS_PROTECTED_ID = "AccessProtected"; // NOI18N
112.72 + private final static String ACCESS_PROTECTED_VARIABLE = "AccessProtectedVariable"; // NOI18N
112.73 + private final static String ACCESS_PROTECTED_DESC = "AccessProtectedDesc"; // NOI18N
112.74 +
112.75 + @Override
112.76 + public Set<Class> getKinds() {
112.77 + return Collections.<Class>singleton(Attribute.class);
112.78 + }
112.79 +
112.80 + @Override
112.81 + public void run(PythonRuleContext context, List<Hint> result) {
112.82 + PythonParserResult info = (PythonParserResult) context.parserResult;
112.83 + Attribute cur = (Attribute)context.node;
112.84 + String curAttr = cur.getInternalAttr();
112.85 + if (curAttr == null) {
112.86 + return;
112.87 + }
112.88 +
112.89 + if (NameStyle.isProtectedName(curAttr)) {
112.90 + expr curValue = cur.getInternalValue();
112.91 + if (curValue instanceof Name) {
112.92 + Name nam = (Name)curValue;
112.93 + String id = nam.getInternalId();
112.94 + if (id.equals("self")) { // NOI18N
112.95 + return; // normal access from class instance
112.96 + }
112.97 + if (PythonAstUtils.getParentClassFromNode(context.path, null, id) != null) {
112.98 + return; // parent access
112.99 + }
112.100 + // we should warn here : Access to protected Attributes from non child
112.101 + // classes
112.102 + OffsetRange range = PythonAstUtils.getRange(cur);
112.103 + range = PythonLexerUtils.getLexerOffsets(info, range);
112.104 + if (range != OffsetRange.NONE) {
112.105 + List<HintFix> fixList = Collections.emptyList();
112.106 + String message = NbBundle.getMessage(NameRule.class, ACCESS_PROTECTED_VARIABLE, curAttr);
112.107 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
112.108 + result.add(desc);
112.109 + }
112.110 + }
112.111 + }
112.112 + }
112.113 +
112.114 + @Override
112.115 + public String getId() {
112.116 + return ACCESS_PROTECTED_ID;
112.117 + }
112.118 +
112.119 + @Override
112.120 + public String getDescription() {
112.121 + return NbBundle.getMessage(RelativeImports.class, ACCESS_PROTECTED_DESC);
112.122 + }
112.123 +
112.124 + @Override
112.125 + public boolean getDefaultEnabled() {
112.126 + return false;
112.127 + }
112.128 +
112.129 + @Override
112.130 + public JComponent getCustomizer(Preferences node) {
112.131 + return null;
112.132 + }
112.133 +
112.134 + @Override
112.135 + public boolean appliesTo(RuleContext context) {
112.136 + return true;
112.137 + }
112.138 +
112.139 + @Override
112.140 + public String getDisplayName() {
112.141 + return NbBundle.getMessage(AccessToProtected.class, ACCESS_PROTECTED_ID);
112.142 + }
112.143 +
112.144 + @Override
112.145 + public boolean showInTasklist() {
112.146 + return true;
112.147 + }
112.148 +
112.149 + @Override
112.150 + public HintSeverity getDefaultSeverity() {
112.151 + return HintSeverity.WARNING;
112.152 + }
112.153 +}
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
113.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AllAssignExists.java Wed Sep 02 20:31:18 2015 +0200
113.3 @@ -0,0 +1,148 @@
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.scopes.ScopeInfo;
113.61 +import org.netbeans.modules.python.source.scopes.SymbolTable;
113.62 +import org.netbeans.modules.python.source.scopes.SymInfo;
113.63 +import org.openide.util.NbBundle;
113.64 +import org.python.antlr.ast.Module;
113.65 +import org.python.antlr.ast.Str;
113.66 +
113.67 +/**
113.68 + *
113.69 + * @author Tor Norbye
113.70 + */
113.71 +public class AllAssignExists extends PythonAstRule {
113.72 + @Override
113.73 + public Set<Class> getKinds() {
113.74 + return Collections.<Class>singleton(Module.class);
113.75 + }
113.76 +
113.77 + @Override
113.78 + public void run(PythonRuleContext context, List<Hint> result) {
113.79 + PythonParserResult ppr = (PythonParserResult)context.parserResult;
113.80 + SymbolTable symbolTable = ppr.getSymbolTable();
113.81 + List<Str> publicSymbols = symbolTable.getPublicSymbols();
113.82 + if (publicSymbols != null) {
113.83 + // Check that we actually have all the symbols called for
113.84 + // by the all-list
113.85 +
113.86 + ScopeInfo topScope = symbolTable.getScopeInfo(context.node);
113.87 + assert topScope != null;
113.88 +
113.89 + // Mark all other symbols private!
113.90 + for (Str str : publicSymbols) {
113.91 + //String name = PythonAstUtils.getExprName(expr);
113.92 + String name = PythonAstUtils.getStrContent(str);
113.93 + if (name != null) {
113.94 + SymInfo sym = topScope.tbl.get(name);
113.95 + if (sym == null) {
113.96 + // Uh oh -- missing!
113.97 + PythonParserResult info = (PythonParserResult) context.parserResult;
113.98 + OffsetRange range = PythonAstUtils.getNameRange(info, str);
113.99 + range = PythonLexerUtils.getLexerOffsets(info, range);
113.100 + if (range != OffsetRange.NONE) {
113.101 + List<HintFix> fixList = Collections.emptyList();
113.102 + String message = NbBundle.getMessage(AllAssignExists.class, "AllAssignExistsMsg", name);
113.103 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 205);
113.104 + result.add(desc);
113.105 + }
113.106 + }
113.107 + }
113.108 + }
113.109 + }
113.110 + }
113.111 +
113.112 + @Override
113.113 + public String getId() {
113.114 + return "AllAssignExists"; // NOI18N
113.115 + }
113.116 +
113.117 + @Override
113.118 + public String getDescription() {
113.119 + return NbBundle.getMessage(AllAssignExists.class, "AllAssignExistsDesc");
113.120 + }
113.121 +
113.122 + @Override
113.123 + public boolean getDefaultEnabled() {
113.124 + return true;
113.125 + }
113.126 +
113.127 + @Override
113.128 + public JComponent getCustomizer(Preferences node) {
113.129 + return null;
113.130 + }
113.131 +
113.132 + @Override
113.133 + public boolean appliesTo(RuleContext context) {
113.134 + return true;
113.135 + }
113.136 +
113.137 + @Override
113.138 + public String getDisplayName() {
113.139 + return NbBundle.getMessage(AllAssignExists.class, "AllAssignExists");
113.140 + }
113.141 +
113.142 + @Override
113.143 + public boolean showInTasklist() {
113.144 + return true;
113.145 + }
113.146 +
113.147 + @Override
113.148 + public HintSeverity getDefaultSeverity() {
113.149 + return HintSeverity.ERROR;
113.150 + }
113.151 +}
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
114.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AssignToVariable.java Wed Sep 02 20:31:18 2015 +0200
114.3 @@ -0,0 +1,245 @@
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.ArrayList;
114.48 +import java.util.Collections;
114.49 +import java.util.List;
114.50 +import java.util.Set;
114.51 +import java.util.prefs.Preferences;
114.52 +import javax.swing.JComponent;
114.53 +import javax.swing.text.BadLocationException;
114.54 +import javax.swing.text.JTextComponent;
114.55 +import javax.swing.text.Position;
114.56 +import org.netbeans.modules.python.source.PythonAstUtils;
114.57 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
114.58 +import org.netbeans.editor.BaseDocument;
114.59 +import org.netbeans.editor.Utilities;
114.60 +import org.netbeans.modules.csl.api.EditList;
114.61 +import org.netbeans.modules.csl.api.Hint;
114.62 +import org.netbeans.modules.csl.api.HintFix;
114.63 +import org.netbeans.modules.csl.api.HintSeverity;
114.64 +import org.netbeans.modules.csl.api.OffsetRange;
114.65 +import org.netbeans.modules.csl.api.PreviewableFix;
114.66 +import org.netbeans.modules.csl.api.RuleContext;
114.67 +import org.netbeans.modules.csl.spi.GsfUtilities;
114.68 +import org.netbeans.modules.python.source.PythonParserResult;
114.69 +import org.openide.util.Exceptions;
114.70 +import org.openide.util.NbBundle;
114.71 +import org.python.antlr.PythonTree;
114.72 +import org.python.antlr.ast.Call;
114.73 +import org.python.antlr.ast.Expr;
114.74 +import org.python.antlr.ast.FunctionDef;
114.75 +import org.python.antlr.ast.Str;
114.76 +import org.python.antlr.base.expr;
114.77 +import org.python.antlr.base.stmt;
114.78 +
114.79 +/**
114.80 + * Assign an expression to a variable
114.81 + *
114.82 + * @author Tor Norbye
114.83 + */
114.84 +public class AssignToVariable extends PythonAstRule {
114.85 + @Override
114.86 + public Set<Class> getKinds() {
114.87 + return Collections.singleton((Class)Expr.class);
114.88 + }
114.89 +
114.90 + @Override
114.91 + public void run(PythonRuleContext context, List<Hint> result) {
114.92 + PythonTree node = context.node;
114.93 + Expr expr = (Expr)node;
114.94 + expr exprValue = expr.getInternalValue();
114.95 + if (exprValue instanceof Str) {
114.96 + // Skip triple-quoted strings (typically doc strings)
114.97 + Str str = (Str)exprValue;
114.98 + String s = str.getText();
114.99 + if (s.startsWith("'''") || s.startsWith("\"\"\"")) { // NOI18N
114.100 + return;
114.101 + }
114.102 + PythonTree grandParent = context.path.leafGrandParent();
114.103 + if (grandParent instanceof FunctionDef) {
114.104 + FunctionDef def = (FunctionDef)grandParent;
114.105 + List<stmt> body = def.getInternalBody();
114.106 + if (body != null && body.size() > 0 && body.get(0) == expr) {
114.107 + // First string in a function -- it's a docstring
114.108 + return;
114.109 + }
114.110 + }
114.111 + }
114.112 + if (exprValue instanceof Call) {
114.113 + // Skip calls - they may have side effects
114.114 + // ...unless it looks like a "getter" style Python method
114.115 + Call call = (Call)exprValue;
114.116 + if (!PythonAstUtils.isGetter(call, false)) {
114.117 + return;
114.118 + }
114.119 + }
114.120 + PythonParserResult info = (PythonParserResult) context.parserResult;
114.121 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
114.122 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
114.123 + BaseDocument doc = context.doc;
114.124 + try {
114.125 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
114.126 + (context.caretOffset == -1 ||
114.127 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
114.128 + List<HintFix> fixList = new ArrayList<>();
114.129 + fixList.add(new AssignToVariableFix(context, node));
114.130 + String displayName = getDisplayName();
114.131 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
114.132 + result.add(desc);
114.133 + }
114.134 + } catch (BadLocationException ex) {
114.135 + Exceptions.printStackTrace(ex);
114.136 + }
114.137 + }
114.138 +
114.139 + @Override
114.140 + public String getId() {
114.141 + return "AssignToVariable"; // NOI18N
114.142 + }
114.143 +
114.144 + @Override
114.145 + public String getDisplayName() {
114.146 + return NbBundle.getMessage(AssignToVariable.class, "AssignToVariable");
114.147 + }
114.148 +
114.149 + @Override
114.150 + public String getDescription() {
114.151 + return NbBundle.getMessage(AssignToVariable.class, "AssignToVariableDesc");
114.152 + }
114.153 +
114.154 + @Override
114.155 + public boolean getDefaultEnabled() {
114.156 + return true;
114.157 + }
114.158 +
114.159 + @Override
114.160 + public JComponent getCustomizer(Preferences node) {
114.161 + return null;
114.162 + }
114.163 +
114.164 + @Override
114.165 + public boolean appliesTo(RuleContext context) {
114.166 + return true;
114.167 + }
114.168 +
114.169 + @Override
114.170 + public boolean showInTasklist() {
114.171 + return false;
114.172 + }
114.173 +
114.174 + @Override
114.175 + public HintSeverity getDefaultSeverity() {
114.176 + return HintSeverity.CURRENT_LINE_WARNING;
114.177 + }
114.178 +
114.179 + private static class AssignToVariableFix implements PreviewableFix {
114.180 + private final PythonRuleContext context;
114.181 + private final PythonTree node;
114.182 + private int varOffset;
114.183 + private String varName;
114.184 +
114.185 + private AssignToVariableFix(PythonRuleContext context, PythonTree node) {
114.186 + this.context = context;
114.187 + this.node = node;
114.188 + }
114.189 +
114.190 + @Override
114.191 + public String getDescription() {
114.192 + return NbBundle.getMessage(AssignToVariable.class, "AssignToVariableFix");
114.193 + }
114.194 +
114.195 + @Override
114.196 + public boolean canPreview() {
114.197 + return true;
114.198 + }
114.199 +
114.200 + @Override
114.201 + public EditList getEditList() throws Exception {
114.202 + BaseDocument doc = context.doc;
114.203 + EditList edits = new EditList(doc);
114.204 +
114.205 + OffsetRange astRange = PythonAstUtils.getRange(node);
114.206 + if (astRange != OffsetRange.NONE) {
114.207 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
114.208 + if (lexRange != OffsetRange.NONE) {
114.209 + int offset = lexRange.getStart();
114.210 + StringBuilder sb = new StringBuilder();
114.211 + varName = NbBundle.getMessage(AssignToVariable.class, "VarName");
114.212 + sb.append(varName);
114.213 + sb.append(" = "); // NOI18N
114.214 + varOffset = offset;
114.215 + edits.replace(offset, 0, sb.toString(), false, 0);
114.216 + }
114.217 + }
114.218 +
114.219 + return edits;
114.220 + }
114.221 +
114.222 + @Override
114.223 + public void implement() throws Exception {
114.224 + EditList edits = getEditList();
114.225 +
114.226 + Position pos = edits.createPosition(varOffset);
114.227 + edits.apply();
114.228 + if (pos != null && pos.getOffset() != -1) {
114.229 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
114.230 + if (target != null) {
114.231 + int start = pos.getOffset();
114.232 + int end = start + varName.length();
114.233 + target.select(start, end);
114.234 + }
114.235 + }
114.236 + }
114.237 +
114.238 + @Override
114.239 + public boolean isSafe() {
114.240 + return true;
114.241 + }
114.242 +
114.243 + @Override
114.244 + public boolean isInteractive() {
114.245 + return false;
114.246 + }
114.247 + }
114.248 +}
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
115.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/AttributeDefinedOutsideInit.java Wed Sep 02 20:31:18 2015 +0200
115.3 @@ -0,0 +1,140 @@
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.Collections;
115.48 +import java.util.List;
115.49 +import java.util.Set;
115.50 +import java.util.prefs.Preferences;
115.51 +import javax.swing.JComponent;
115.52 +import org.netbeans.modules.csl.api.Hint;
115.53 +import org.netbeans.modules.csl.api.HintFix;
115.54 +import org.netbeans.modules.csl.api.HintSeverity;
115.55 +import org.netbeans.modules.csl.api.OffsetRange;
115.56 +import org.netbeans.modules.csl.api.RuleContext;
115.57 +import org.netbeans.modules.python.source.PythonAstUtils;
115.58 +import org.netbeans.modules.python.source.PythonParserResult;
115.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
115.60 +import org.netbeans.modules.python.source.scopes.SymbolTable;
115.61 +import org.openide.util.NbBundle;
115.62 +import org.python.antlr.ast.Attribute;
115.63 +import org.python.antlr.ast.Module;
115.64 +
115.65 +/**
115.66 + *
115.67 + * @author Jean-Yves Mengant
115.68 + */
115.69 +public class AttributeDefinedOutsideInit extends PythonAstRule {
115.70 + private final static String ATTRIBUTE_DEFINED_OUTSIDE_INIT = "AttributeDefinedOutsideInit";
115.71 + private final static String ATTRIBUTE_DEFINED_OUTSITE_INIT_VAR = "AttributeDefinedOutsideInitVariable";
115.72 + private final static String ATTRIBUTE_DEFINED_OUTSIDE_INIT_DESC = "AttributeDefinedOutsideInitDesc";
115.73 +
115.74 + @Override
115.75 + public Set<Class> getKinds() {
115.76 + return Collections.<Class>singleton(Module.class);
115.77 + }
115.78 +
115.79 + @Override
115.80 + public void run(PythonRuleContext context, List<Hint> result) {
115.81 + PythonParserResult info = (PythonParserResult) context.parserResult;
115.82 + PythonParserResult pr = PythonAstUtils.getParseResult(info);
115.83 + SymbolTable symbolTable = pr.getSymbolTable();
115.84 +
115.85 +
115.86 + List<Attribute> notInIntBound = symbolTable.getNotInInitAttributes(info);
115.87 + if (notInIntBound.size() > 0) {
115.88 + for (Attribute cur : notInIntBound) {
115.89 + OffsetRange range = PythonAstUtils.getRange(cur);
115.90 + range = PythonLexerUtils.getLexerOffsets(info, range);
115.91 + if (range != OffsetRange.NONE) {
115.92 + List<HintFix> fixList = Collections.emptyList();
115.93 + String message = NbBundle.getMessage(NameRule.class,
115.94 + ATTRIBUTE_DEFINED_OUTSITE_INIT_VAR,
115.95 + cur.getInternalAttr());
115.96 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
115.97 + result.add(desc);
115.98 + }
115.99 + }
115.100 + }
115.101 +
115.102 + }
115.103 +
115.104 + @Override
115.105 + public String getId() {
115.106 + return ATTRIBUTE_DEFINED_OUTSIDE_INIT;
115.107 + }
115.108 +
115.109 + @Override
115.110 + public String getDescription() {
115.111 + return NbBundle.getMessage(RelativeImports.class, ATTRIBUTE_DEFINED_OUTSIDE_INIT_DESC);
115.112 + }
115.113 +
115.114 + @Override
115.115 + public boolean getDefaultEnabled() {
115.116 + return false;
115.117 + }
115.118 +
115.119 + @Override
115.120 + public JComponent getCustomizer(Preferences node) {
115.121 + return null;
115.122 + }
115.123 +
115.124 + @Override
115.125 + public boolean appliesTo(RuleContext context) {
115.126 + return true;
115.127 + }
115.128 +
115.129 + @Override
115.130 + public String getDisplayName() {
115.131 + return NbBundle.getMessage(AccessToProtected.class, ATTRIBUTE_DEFINED_OUTSIDE_INIT);
115.132 + }
115.133 +
115.134 + @Override
115.135 + public boolean showInTasklist() {
115.136 + return true;
115.137 + }
115.138 +
115.139 + @Override
115.140 + public HintSeverity getDefaultSeverity() {
115.141 + return HintSeverity.WARNING;
115.142 + }
115.143 +}
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
116.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/Bundle.properties Wed Sep 02 20:31:18 2015 +0200
116.3 @@ -0,0 +1,147 @@
116.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
116.5 +#
116.6 +# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
116.7 +#
116.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
116.9 +# Other names may be trademarks of their respective owners.
116.10 +#
116.11 +# The contents of this file are subject to the terms of either the GNU
116.12 +# General Public License Version 2 only ("GPL") or the Common
116.13 +# Development and Distribution License("CDDL") (collectively, the
116.14 +# "License"). You may not use this file except in compliance with the
116.15 +# License. You can obtain a copy of the License at
116.16 +# http://www.netbeans.org/cddl-gplv2.html
116.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
116.18 +# specific language governing permissions and limitations under the
116.19 +# License. When distributing the software, include this License Header
116.20 +# Notice in each file and include the License file at
116.21 +# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
116.22 +# particular file as subject to the "Classpath" exception as provided
116.23 +# by Oracle in the GPL Version 2 section of the License file that
116.24 +# accompanied this code. If applicable, add the following below the
116.25 +# License Header, with the fields enclosed by brackets [] replaced by
116.26 +# your own identifying information:
116.27 +# "Portions Copyrighted [year] [name of copyright owner]"
116.28 +#
116.29 +# Contributor(s):
116.30 +#
116.31 +# The Original Software is NetBeans. The Initial Developer of the Original
116.32 +# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
116.33 +# Microsystems, Inc. All Rights Reserved.
116.34 +#
116.35 +# If you wish your version of this file to be governed by only the CDDL
116.36 +# or only the GPL Version 2, indicate your decision by adding
116.37 +# "[Contributor] elects to include this software in this distribution
116.38 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
116.39 +# single choice of license, a recipient has the option to distribute
116.40 +# your version of this file under either the CDDL, the GPL Version 2 or
116.41 +# to extend the choice of license to its licensees as provided above.
116.42 +# However, if you add GPL Version 2 code and therefore, elected the GPL
116.43 +# Version 2 license, then the option applies only if the new code is
116.44 +# made subject to such option by the copyright holder.
116.45 +
116.46 +# Category descriptions in the Options Panel
116.47 +gsf-hints/text/x-python/hints/general=General
116.48 +
116.49 +# NameRule
116.50 +NameRule=Naming Conventions
116.51 +NameRuleDesc=Check class, function and variable names for style guide compliance (see http://www.python.org/dev/peps/pep-0008/ for rules)
116.52 +NameRuleWrongNoArg=First argument should be 'self' or 'cls'
116.53 +NameRuleWrongArg=First argument ({0}) should be 'self' or 'cls'
116.54 +WrongStyle=Name "{0}" is not a valid {1} name according to your code style ({2})
116.55 +Module=module
116.56 +Function=function
116.57 +Class=class
116.58 +Variable=variable
116.59 +ChangeStyle=Change preferred {0} name style to {1}
116.60 +ChangeNoStyle=Turn off {0} name style checks
116.61 +IgnoreWord=Ignore name violations for "{0}"
116.62 +NameRulePrefs.selfCb.text=First method params should be "self" or "cls"
116.63 +NameRulePrefs.moduleLabel.text=Modules:
116.64 +NameRulePrefs.classLabel.text=Classes:
116.65 +NameRulePrefs.functionLabel.text=Functions:
116.66 +NameRulePrefs.parameterLabel.text=Parameters:
116.67 +NameRulePrefs.variableLabel.text=Variables:
116.68 +NameRulePrefs.ignoreLabel.text=Ignored:
116.69 +
116.70 +CreateDocString=Create document comment
116.71 +CreateDocStringDesc=Offer to create a documentation comment for the current function, class or module
116.72 +CreateDocStringFix=Add a one-liner docstring
116.73 +CreateDocStringFixMulti=Add a multi-line docstring
116.74 +
116.75 +AssignToVariable=Assign expression to a variable
116.76 +AssignToVariableDesc=Assign expression under the caret to a variable
116.77 +AssignToVariableFix=Assign expression to a variable
116.78 +VarName=name
116.79 +
116.80 +SplitImports=Multiple imports per import statement is discouraged
116.81 +SplitImportsDesc=Split an import which imports multiple modules into individual import statements as recommended by the Python styleguide
116.82 +SplitImportsFix=Split import into individual import statements
116.83 +
116.84 +RelativeImports=Relative imports for intra-package imports are actively discouraged (as per PEP-008)
116.85 +RelativeImportsDesc=Relative imports for intra-package imports are actively discouraged (as per PEP-008) and this rule warns about usages of relative imports
116.86 +RelativeImportsFix=Replace with absolute import
116.87 +
116.88 +Deprecations=Deprecated
116.89 +DeprecationsMsg={0} is deprecated
116.90 +DeprecationsMsgDetail={0} is deprecated. {1}
116.91 +DeprecationsDesc=Check for deprecated modules
116.92 +
116.93 +SurroundWith=Surround With...
116.94 +#SurroundWithDesc=Offer to surround selected code with try/catch, etc
116.95 +SurroundWithTE=Surround With Try/Except
116.96 +SurroundWithTEF=Surround With Try/Except/Finally
116.97 +SurroundWithTF=Surround With Try/Finally
116.98 +InsertSelf=Insert a new first parameter "self"
116.99 +RenameSelf=Rename first parameter "{0}" to self
116.100 +
116.101 +ExtractCode=Extract Code
116.102 +IntroduceMethod=Extract Method
116.103 +IntroduceVariable=Introduce Variable
116.104 +IntroduceConstant=Introduce Constant
116.105 +IntroduceField=Introduce Field
116.106 +
116.107 +UnusedImport=Unused Import
116.108 +UnusedImportSymbols=Some symbols are unused ({0})
116.109 +UnusedImports=Find Unused Imports
116.110 +UnusedImportsDesc=Find imports that aren't used in this module and can be removed
116.111 +UnusedFix=Remove Unused Import
116.112 +UnusedFixSymbols=Remove {0} from import
116.113 +OrganizeImports=Clean up and Organize Imports
116.114 +DeleteAllUnused=Remove All Unused Imports
116.115 +
116.116 +Unused=Find Unused Variables
116.117 +UnusedDesc=Find variables that are defined but never used
116.118 +UnusedVariable=Unused Variable {0}
116.119 +
116.120 +Unresolved=Find Undefined Names
116.121 +UnresolvedDesc=Find names that are used but have not been bound
116.122 +UnresolvedVariable=Undefined name "{0}"
116.123 +UnresolvedVariableMaybe=Undefined name "{0}" - did you mean "{1}" ?
116.124 +FixImport=Import {0}
116.125 +
116.126 +UnresolvedAttributes=Find Unresolved classes attributes and parentages
116.127 +UnresolvedAttributesDesc=Find class attributes that are used but have not been bound and undefined inherited classes
116.128 +UnresolvedAttributesVariable=Undefined attribute "{0}"
116.129 +UnresolvedInheritanceVariable=Inheriting from undefined parent class "{0}"
116.130 +
116.131 +AccessProtected=Access Protected Attributes
116.132 +AccessProtectedDesc=Find access to protected variables/methods of non parent classes
116.133 +AccessProtectedVariable=Access to protected variable "{0}"
116.134 +
116.135 +AttributeDefinedOutsideInit=Attribute Defined Outside __init__
116.136 +AttributeDefinedOutsideInitDesc=Class Attribute defined outside __init__ constructor
116.137 +AttributeDefinedOutsideInitVariable=Attribute Defined Outside __init__ "{0}"
116.138 +
116.139 +ClassCircularRedundancy=Parent Child circular redundancy
116.140 +ClassCircularRedundancyDesc=Parent Child circular redundancy = A inherits B and B inherits A
116.141 +ClassCircularRedundancyVariable=Parent/child {0} inheritance circular redundancy
116.142 +
116.143 +AllAssignExists=Symbol defined in __all__ does not exist
116.144 +AllAssignExistsDesc=Checks that all symbols listed in __all__ actually exist
116.145 +AllAssignExistsMsg="{0}" defined in __all__ does not exist!
116.146 +UnusedDetectorPrefs.skipParams.text=Ignore unused function parameters
116.147 +UnusedDetectorPrefs.ignoredLabel.text=Ignored names:
116.148 +UnusedDetectorPrefs.skipTupleAssignments.text=Ignore unused variables in tuple-assignments
116.149 +
116.150 +OpenIDE-Module-Name=Python Hints
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
117.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/ClassCircularRedundancy.java Wed Sep 02 20:31:18 2015 +0200
117.3 @@ -0,0 +1,140 @@
117.4 +/*
117.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
117.6 + *
117.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
117.8 + *
117.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
117.10 + * Other names may be trademarks of their respective owners.
117.11 + *
117.12 + * The contents of this file are subject to the terms of either the GNU
117.13 + * General Public License Version 2 only ("GPL") or the Common
117.14 + * Development and Distribution License("CDDL") (collectively, the
117.15 + * "License"). You may not use this file except in compliance with the
117.16 + * License. You can obtain a copy of the License at
117.17 + * http://www.netbeans.org/cddl-gplv2.html
117.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
117.19 + * specific language governing permissions and limitations under the
117.20 + * License. When distributing the software, include this License Header
117.21 + * Notice in each file and include the License file at
117.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
117.23 + * particular file as subject to the "Classpath" exception as provided
117.24 + * by Oracle in the GPL Version 2 section of the License file that
117.25 + * accompanied this code. If applicable, add the following below the
117.26 + * License Header, with the fields enclosed by brackets [] replaced by
117.27 + * your own identifying information:
117.28 + * "Portions Copyrighted [year] [name of copyright owner]"
117.29 + *
117.30 + * If you wish your version of this file to be governed by only the CDDL
117.31 + * or only the GPL Version 2, indicate your decision by adding
117.32 + * "[Contributor] elects to include this software in this distribution
117.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
117.34 + * single choice of license, a recipient has the option to distribute
117.35 + * your version of this file under either the CDDL, the GPL Version 2 or
117.36 + * to extend the choice of license to its licensees as provided above.
117.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
117.38 + * Version 2 license, then the option applies only if the new code is
117.39 + * made subject to such option by the copyright holder.
117.40 + *
117.41 + * Contributor(s):
117.42 + *
117.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
117.44 + */
117.45 +package org.netbeans.modules.python.hints;
117.46 +
117.47 +import java.util.Collections;
117.48 +import java.util.HashMap;
117.49 +import java.util.List;
117.50 +import java.util.Map.Entry;
117.51 +import java.util.Set;
117.52 +import java.util.prefs.Preferences;
117.53 +import javax.swing.JComponent;
117.54 +import org.netbeans.modules.csl.api.Hint;
117.55 +import org.netbeans.modules.csl.api.HintFix;
117.56 +import org.netbeans.modules.csl.api.HintSeverity;
117.57 +import org.netbeans.modules.csl.api.OffsetRange;
117.58 +import org.netbeans.modules.csl.api.RuleContext;
117.59 +import org.netbeans.modules.python.source.PythonAstUtils;
117.60 +import org.netbeans.modules.python.source.PythonParserResult;
117.61 +import org.netbeans.modules.python.source.scopes.SymbolTable;
117.62 +import org.openide.util.NbBundle;
117.63 +import org.python.antlr.ast.ClassDef;
117.64 +import org.python.antlr.ast.Module;
117.65 +
117.66 +/**
117.67 + * check for redundancy cycling in parent child
117.68 + * @author Jean-Yves Mengant
117.69 + */
117.70 +public class ClassCircularRedundancy extends PythonAstRule {
117.71 + private final static String CLASS_CIRCULAR_REDUNDANCY = "ClassCircularRedundancy";
117.72 + private final static String CLASS_CIRCULAR_REDUNDANCY_VAR = "ClassCircularRedundancyVariable";
117.73 + private final static String CLASS_CIRCULAR_REDUNDANCY_DESC = "ClassCircularRedundancyDesc";
117.74 +
117.75 + @Override
117.76 + public Set<Class> getKinds() {
117.77 + return Collections.<Class>singleton(Module.class);
117.78 + }
117.79 +
117.80 + @Override
117.81 + public void run(PythonRuleContext context, List<Hint> result) {
117.82 + PythonParserResult info = (PythonParserResult) context.parserResult;
117.83 + SymbolTable symbolTable = info.getSymbolTable();
117.84 +
117.85 +
117.86 + HashMap<ClassDef, String> cyclingRedundancies = symbolTable.getClassesCyclingRedundancies(info);
117.87 + if (cyclingRedundancies.size() > 0) {
117.88 + Set<Entry<ClassDef, String>> wk = cyclingRedundancies.entrySet();
117.89 + for (Entry<ClassDef, String> cur : wk) {
117.90 + ClassDef curClass = cur.getKey();
117.91 + String curCyclingMsg = curClass.getInternalName() + "/" + cur.getValue(); // NOI18N
117.92 + OffsetRange range = PythonAstUtils.getNameRange(info, curClass);
117.93 + // range = PythonLexerUtils.getLexerOffsets(info, range);
117.94 + if (range != OffsetRange.NONE) {
117.95 + List<HintFix> fixList = Collections.emptyList();
117.96 + String message = NbBundle.getMessage(NameRule.class, CLASS_CIRCULAR_REDUNDANCY_VAR, curCyclingMsg);
117.97 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
117.98 + result.add(desc);
117.99 + }
117.100 + }
117.101 + }
117.102 + }
117.103 +
117.104 + @Override
117.105 + public String getId() {
117.106 + return CLASS_CIRCULAR_REDUNDANCY;
117.107 + }
117.108 +
117.109 + @Override
117.110 + public String getDescription() {
117.111 + return NbBundle.getMessage(RelativeImports.class, CLASS_CIRCULAR_REDUNDANCY_DESC);
117.112 + }
117.113 +
117.114 + @Override
117.115 + public boolean getDefaultEnabled() {
117.116 + return false;
117.117 + }
117.118 +
117.119 + @Override
117.120 + public JComponent getCustomizer(Preferences node) {
117.121 + return null;
117.122 + }
117.123 +
117.124 + @Override
117.125 + public boolean appliesTo(RuleContext context) {
117.126 + return true;
117.127 + }
117.128 +
117.129 + @Override
117.130 + public String getDisplayName() {
117.131 + return NbBundle.getMessage(AccessToProtected.class, CLASS_CIRCULAR_REDUNDANCY);
117.132 + }
117.133 +
117.134 + @Override
117.135 + public boolean showInTasklist() {
117.136 + return true;
117.137 + }
117.138 +
117.139 + @Override
117.140 + public HintSeverity getDefaultSeverity() {
117.141 + return HintSeverity.ERROR;
117.142 + }
117.143 +}
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/CreateDocString.java Wed Sep 02 20:31:18 2015 +0200
118.3 @@ -0,0 +1,241 @@
118.4 +/*
118.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
118.6 + *
118.7 + * Copyright 1997-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 + * Contributor(s):
118.31 + *
118.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
118.33 + */
118.34 +package org.netbeans.modules.python.hints;
118.35 +
118.36 +import java.util.ArrayList;
118.37 +import java.util.Collections;
118.38 +import java.util.HashSet;
118.39 +import java.util.List;
118.40 +import java.util.Set;
118.41 +import java.util.prefs.Preferences;
118.42 +import javax.swing.JComponent;
118.43 +import javax.swing.text.BadLocationException;
118.44 +import javax.swing.text.JTextComponent;
118.45 +import javax.swing.text.Position;
118.46 +import org.netbeans.modules.python.source.PythonAstUtils;
118.47 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
118.48 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
118.49 +import org.netbeans.api.lexer.Token;
118.50 +import org.netbeans.api.lexer.TokenSequence;
118.51 +import org.netbeans.editor.BaseDocument;
118.52 +import org.netbeans.editor.Utilities;
118.53 +import org.netbeans.modules.csl.api.EditList;
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.PreviewableFix;
118.59 +import org.netbeans.modules.csl.api.RuleContext;
118.60 +import org.netbeans.modules.csl.spi.GsfUtilities;
118.61 +import org.netbeans.modules.editor.indent.api.IndentUtils;
118.62 +import org.netbeans.modules.python.source.PythonParserResult;
118.63 +import org.openide.util.Exceptions;
118.64 +import org.openide.util.NbBundle;
118.65 +import org.python.antlr.PythonTree;
118.66 +import org.python.antlr.ast.ClassDef;
118.67 +import org.python.antlr.ast.FunctionDef;
118.68 +
118.69 +/**
118.70 + * Offer to create docstrings.
118.71 + * @todo Handle modules?
118.72 + * @todo Handle parameter tags (for epydoc etc)
118.73 + *
118.74 + * @author Tor Norbye
118.75 + */
118.76 +public class CreateDocString extends PythonAstRule {
118.77 + @Override
118.78 + public Set<Class> getKinds() {
118.79 + Set<Class> classes = new HashSet<>();
118.80 + classes.add(FunctionDef.class);
118.81 + classes.add(ClassDef.class);
118.82 +
118.83 + return classes;
118.84 + }
118.85 +
118.86 + @Override
118.87 + public void run(PythonRuleContext context, List<Hint> result) {
118.88 +
118.89 + PythonTree node = context.node;
118.90 + if (PythonAstUtils.getDocumentationNode(node) != null) {
118.91 + return;
118.92 + }
118.93 +
118.94 + // Create new fix
118.95 + PythonParserResult info = (PythonParserResult) context.parserResult;
118.96 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
118.97 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
118.98 + BaseDocument doc = context.doc;
118.99 + try {
118.100 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
118.101 + (context.caretOffset == -1 ||
118.102 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
118.103 + List<HintFix> fixList = new ArrayList<>();
118.104 + boolean singleIsDefault = node.getClass() == FunctionDef.class;
118.105 + fixList.add(new CreateDocStringFix(context, node, !singleIsDefault));
118.106 + fixList.add(new CreateDocStringFix(context, node, singleIsDefault));
118.107 + String displayName = getDisplayName();
118.108 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
118.109 + result.add(desc);
118.110 + }
118.111 + } catch (BadLocationException ex) {
118.112 + Exceptions.printStackTrace(ex);
118.113 + }
118.114 + }
118.115 +
118.116 + @Override
118.117 + public String getId() {
118.118 + return "CreateDocString"; // NOI18N
118.119 + }
118.120 +
118.121 + @Override
118.122 + public String getDisplayName() {
118.123 + return NbBundle.getMessage(CreateDocString.class, "CreateDocString");
118.124 + }
118.125 +
118.126 + @Override
118.127 + public String getDescription() {
118.128 + return NbBundle.getMessage(CreateDocString.class, "CreateDocStringDesc");
118.129 + }
118.130 +
118.131 + @Override
118.132 + public boolean getDefaultEnabled() {
118.133 + return true;
118.134 + }
118.135 +
118.136 + @Override
118.137 + public JComponent getCustomizer(Preferences node) {
118.138 + return null;
118.139 + }
118.140 +
118.141 + @Override
118.142 + public boolean appliesTo(RuleContext context) {
118.143 + return true;
118.144 + }
118.145 +
118.146 + @Override
118.147 + public boolean showInTasklist() {
118.148 + return false;
118.149 + }
118.150 +
118.151 + @Override
118.152 + public HintSeverity getDefaultSeverity() {
118.153 + return HintSeverity.CURRENT_LINE_WARNING;
118.154 + }
118.155 +
118.156 + private static class CreateDocStringFix implements PreviewableFix {
118.157 + private final PythonRuleContext context;
118.158 + private final PythonTree node;
118.159 + private final boolean multiLine;
118.160 + private int editListPosition;
118.161 +
118.162 + private CreateDocStringFix(PythonRuleContext context, PythonTree node, boolean multiLine) {
118.163 + this.context = context;
118.164 + this.node = node;
118.165 + this.multiLine = multiLine;
118.166 + }
118.167 +
118.168 + @Override
118.169 + public String getDescription() {
118.170 + return multiLine ? NbBundle.getMessage(CreateDocString.class, "CreateDocStringFixMulti") : NbBundle.getMessage(CreateDocString.class, "CreateDocStringFix");
118.171 + }
118.172 +
118.173 + @Override
118.174 + public boolean canPreview() {
118.175 + return true;
118.176 + }
118.177 +
118.178 + @Override
118.179 + public EditList getEditList() throws Exception {
118.180 + BaseDocument doc = context.doc;
118.181 + EditList edits = new EditList(doc);
118.182 +
118.183 + OffsetRange astRange = PythonAstUtils.getRange(node);
118.184 + if (astRange != OffsetRange.NONE) {
118.185 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
118.186 + if (lexRange != OffsetRange.NONE) {
118.187 + // Find the colon
118.188 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPositionedSequence(doc, lexRange.getStart());
118.189 + if (ts != null) {
118.190 + Token<? extends PythonTokenId> token = PythonLexerUtils.findNextIncluding(ts, Collections.singletonList(PythonTokenId.COLON));
118.191 + if (token != null) {
118.192 + int offset = ts.offset();
118.193 + if (offset < lexRange.getEnd()) {
118.194 + int indent = GsfUtilities.getLineIndent(doc, lexRange.getStart()) +
118.195 + IndentUtils.indentLevelSize(doc);
118.196 + StringBuilder sb = new StringBuilder();
118.197 + sb.append(IndentUtils.createIndentString(doc, indent));
118.198 + int rowEnd = Utilities.getRowEnd(doc, offset) + 1;
118.199 + sb.append("\"\"\""); // NOI18N
118.200 + if (multiLine) {
118.201 + sb.append("\n"); // NOI18N
118.202 + sb.append(IndentUtils.createIndentString(doc, indent));
118.203 + }
118.204 + editListPosition = rowEnd + sb.length();
118.205 + if (multiLine) {
118.206 + sb.append("\n"); // NOI18N
118.207 + sb.append(IndentUtils.createIndentString(doc, indent));
118.208 + }
118.209 + sb.append("\"\"\"\n"); // NOI18N
118.210 + edits.replace(rowEnd, 0, sb.toString(), false, 0);
118.211 + }
118.212 + }
118.213 + }
118.214 + }
118.215 + }
118.216 +
118.217 + return edits;
118.218 + }
118.219 +
118.220 + @Override
118.221 + public void implement() throws Exception {
118.222 + EditList edits = getEditList();
118.223 +
118.224 + Position pos = edits.createPosition(editListPosition);
118.225 + edits.apply();
118.226 + if (pos != null && pos.getOffset() != -1) {
118.227 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
118.228 + if (target != null) {
118.229 + target.setCaretPosition(pos.getOffset());
118.230 + }
118.231 + }
118.232 + }
118.233 +
118.234 + @Override
118.235 + public boolean isSafe() {
118.236 + return true;
118.237 + }
118.238 +
118.239 + @Override
118.240 + public boolean isInteractive() {
118.241 + return false;
118.242 + }
118.243 + }
118.244 +}
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
119.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/Deprecations.java Wed Sep 02 20:31:18 2015 +0200
119.3 @@ -0,0 +1,184 @@
119.4 +/*
119.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
119.6 + *
119.7 + * Copyright 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 + * If you wish your version of this file to be governed by only the CDDL
119.31 + * or only the GPL Version 2, indicate your decision by adding
119.32 + * "[Contributor] elects to include this software in this distribution
119.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
119.34 + * single choice of license, a recipient has the option to distribute
119.35 + * your version of this file under either the CDDL, the GPL Version 2 or
119.36 + * to extend the choice of license to its licensees as provided above.
119.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
119.38 + * Version 2 license, then the option applies only if the new code is
119.39 + * made subject to such option by the copyright holder.
119.40 + *
119.41 + * Contributor(s):
119.42 + *
119.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
119.44 + */
119.45 +package org.netbeans.modules.python.hints;
119.46 +
119.47 +import java.util.Collections;
119.48 +import java.util.HashMap;
119.49 +import java.util.HashSet;
119.50 +import java.util.List;
119.51 +import java.util.Map;
119.52 +import java.util.Set;
119.53 +import java.util.prefs.Preferences;
119.54 +import javax.swing.JComponent;
119.55 +import javax.swing.text.BadLocationException;
119.56 +import org.netbeans.modules.python.source.PythonAstUtils;
119.57 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
119.58 +import org.netbeans.editor.BaseDocument;
119.59 +import org.netbeans.editor.Utilities;
119.60 +import org.netbeans.modules.csl.api.Hint;
119.61 +import org.netbeans.modules.csl.api.HintFix;
119.62 +import org.netbeans.modules.csl.api.HintSeverity;
119.63 +import org.netbeans.modules.csl.api.OffsetRange;
119.64 +import org.netbeans.modules.csl.api.RuleContext;
119.65 +import org.netbeans.modules.python.source.PythonParserResult;
119.66 +import org.netbeans.modules.python.source.queries.DeprecationQuery;
119.67 +import org.openide.util.Exceptions;
119.68 +import org.openide.util.NbBundle;
119.69 +import org.python.antlr.PythonTree;
119.70 +import org.python.antlr.ast.Import;
119.71 +import org.python.antlr.ast.ImportFrom;
119.72 +import org.python.antlr.ast.alias;
119.73 +
119.74 +/**
119.75 + * Handle deprecaton warnings, for modules listed as obsolete or
119.76 + * deprecated in PEP4:
119.77 + * http://www.python.org/dev/peps/pep-0004/
119.78 + *
119.79 + * Todo: Add a hint to enforce this from PEP8:
119.80 +- Comparisons to singletons like None should always be done with
119.81 +'is' or 'is not', never the equality operators.
119.82 + * In general, see the "Programming Recommendations" list from
119.83 + * http://www.python.org/dev/peps/pep-0008/ - there are lots
119.84 + * of thins to check from there. Check the PyLint list as well.
119.85 + *
119.86 + *
119.87 + * @author Tor Norbye
119.88 + */
119.89 +public class Deprecations extends PythonAstRule {
119.90 +
119.91 + @Override
119.92 + public Set<Class> getKinds() {
119.93 + HashSet<Class> kinds = new HashSet<>();
119.94 + kinds.add(Import.class);
119.95 + kinds.add(ImportFrom.class);
119.96 +
119.97 + return kinds;
119.98 + }
119.99 +
119.100 + @Override
119.101 + public void run(PythonRuleContext context, List<Hint> result) {
119.102 + PythonTree node = context.node;
119.103 + if (node instanceof Import) {
119.104 + Import imp = (Import)node;
119.105 + List<alias> names = imp.getInternalNames();
119.106 + if (names != null) {
119.107 + for (alias alias : names) {
119.108 + String name = alias.getInternalName();
119.109 + if (DeprecationQuery.isDeprecatedModule(name)) {
119.110 + addDeprecation(name, DeprecationQuery.getDeprecatedModuleDescription(name), context, result);
119.111 + }
119.112 + }
119.113 + }
119.114 + } else {
119.115 + assert node instanceof ImportFrom;
119.116 + ImportFrom imp = (ImportFrom)node;
119.117 + String name = imp.getInternalModule();
119.118 + if (DeprecationQuery.isDeprecatedModule(name)) {
119.119 + addDeprecation(name, DeprecationQuery.getDeprecatedModuleDescription(name), context, result);
119.120 + }
119.121 + }
119.122 + }
119.123 +
119.124 + private void addDeprecation(String module, String rationale, PythonRuleContext context, List<Hint> result) {
119.125 + PythonParserResult info = (PythonParserResult) context.parserResult;
119.126 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, context.node);
119.127 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
119.128 + BaseDocument doc = context.doc;
119.129 + try {
119.130 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
119.131 + (context.caretOffset == -1 ||
119.132 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
119.133 + List<HintFix> fixList = Collections.emptyList();
119.134 + String displayName;
119.135 + if (rationale.length() > 0) {
119.136 + displayName = NbBundle.getMessage(Deprecations.class, "DeprecationsMsgDetail", module, rationale);
119.137 + } else {
119.138 + displayName = NbBundle.getMessage(Deprecations.class, "DeprecationsMsg", module);
119.139 + }
119.140 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
119.141 + result.add(desc);
119.142 + }
119.143 + } catch (BadLocationException ex) {
119.144 + Exceptions.printStackTrace(ex);
119.145 + }
119.146 + }
119.147 +
119.148 + @Override
119.149 + public String getId() {
119.150 + return "Deprecations"; // NOI18N
119.151 + }
119.152 +
119.153 + @Override
119.154 + public String getDisplayName() {
119.155 + return NbBundle.getMessage(Deprecations.class, "Deprecations");
119.156 + }
119.157 +
119.158 + @Override
119.159 + public String getDescription() {
119.160 + return NbBundle.getMessage(Deprecations.class, "DeprecationsDesc");
119.161 + }
119.162 +
119.163 + @Override
119.164 + public boolean getDefaultEnabled() {
119.165 + return true;
119.166 + }
119.167 +
119.168 + @Override
119.169 + public JComponent getCustomizer(Preferences node) {
119.170 + return null;
119.171 + }
119.172 +
119.173 + @Override
119.174 + public boolean appliesTo(RuleContext context) {
119.175 + return true;
119.176 + }
119.177 +
119.178 + @Override
119.179 + public boolean showInTasklist() {
119.180 + return true;
119.181 + }
119.182 +
119.183 + @Override
119.184 + public HintSeverity getDefaultSeverity() {
119.185 + return HintSeverity.WARNING;
119.186 + }
119.187 +}
120.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
120.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/ExtractCode.java Wed Sep 02 20:31:18 2015 +0200
120.3 @@ -0,0 +1,759 @@
120.4 +/*
120.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
120.6 + *
120.7 + * Copyright 1997-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 + * Contributor(s):
120.31 + *
120.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
120.33 + */
120.34 +package org.netbeans.modules.python.hints;
120.35 +
120.36 +import java.util.ArrayList;
120.37 +import java.util.Collections;
120.38 +import java.util.HashSet;
120.39 +import java.util.List;
120.40 +import java.util.Set;
120.41 +import java.util.prefs.Preferences;
120.42 +import javax.swing.JComponent;
120.43 +import javax.swing.text.JTextComponent;
120.44 +import org.netbeans.editor.BaseDocument;
120.45 +import org.netbeans.editor.Utilities;
120.46 +import org.netbeans.modules.csl.api.EditList;
120.47 +import org.netbeans.modules.csl.api.EditRegions;
120.48 +import org.netbeans.modules.csl.api.Hint;
120.49 +import org.netbeans.modules.csl.api.HintFix;
120.50 +import org.netbeans.modules.csl.api.HintSeverity;
120.51 +import org.netbeans.modules.csl.api.OffsetRange;
120.52 +import org.netbeans.modules.csl.api.PreviewableFix;
120.53 +import org.netbeans.modules.csl.api.RuleContext;
120.54 +import org.netbeans.modules.csl.spi.GsfUtilities;
120.55 +import org.netbeans.modules.editor.indent.api.IndentUtils;
120.56 +import org.netbeans.modules.python.source.AstPath;
120.57 +import org.netbeans.modules.python.source.PythonAstUtils;
120.58 +import org.netbeans.modules.python.source.PythonParserResult;
120.59 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
120.60 +import org.openide.util.Exceptions;
120.61 +import org.openide.util.NbBundle;
120.62 +import org.python.antlr.PythonTree;
120.63 +import org.python.antlr.Visitor;
120.64 +import org.python.antlr.ast.Assert;
120.65 +import org.python.antlr.ast.Assign;
120.66 +import org.python.antlr.ast.AugAssign;
120.67 +import org.python.antlr.ast.Break;
120.68 +import org.python.antlr.ast.Call;
120.69 +import org.python.antlr.ast.ClassDef;
120.70 +import org.python.antlr.ast.Continue;
120.71 +import org.python.antlr.ast.Delete;
120.72 +import org.python.antlr.ast.For;
120.73 +import org.python.antlr.ast.FunctionDef;
120.74 +import org.python.antlr.ast.Global;
120.75 +import org.python.antlr.ast.If;
120.76 +import org.python.antlr.ast.IfExp;
120.77 +import org.python.antlr.ast.Import;
120.78 +import org.python.antlr.ast.ImportFrom;
120.79 +import org.python.antlr.ast.Module;
120.80 +import org.python.antlr.ast.Name;
120.81 +import org.python.antlr.ast.Num;
120.82 +import org.python.antlr.ast.Pass;
120.83 +import org.python.antlr.ast.Print;
120.84 +import org.python.antlr.ast.Raise;
120.85 +import org.python.antlr.ast.Return;
120.86 +import org.python.antlr.ast.Str;
120.87 +import org.python.antlr.ast.Suite;
120.88 +import org.python.antlr.ast.TryExcept;
120.89 +import org.python.antlr.ast.TryFinally;
120.90 +import org.python.antlr.ast.Tuple;
120.91 +import org.python.antlr.ast.While;
120.92 +import org.python.antlr.ast.With;
120.93 +import org.python.antlr.ast.Yield;
120.94 +
120.95 +/**
120.96 + * Offer to introduce method/variable/constant
120.97 + * @todo There is no need to pass in class or top level constants to code fragments
120.98 + * @todo Handle flow control: If a code fragment contains an early return, figure out
120.99 + * how to pass that information back to the method callsite and do something clever,
120.100 + * for example pass back a to-return flag which returns the same value
120.101 + * @todo Unit tests must check instant rename as well!
120.102 + *
120.103 + * @author Tor Norbye
120.104 + */
120.105 +public class ExtractCode extends PythonSelectionRule {
120.106 + //private static final int NOT_APPLICABLE = 0;
120.107 + private static final int INTRODUCE_METHOD = 1;
120.108 + private static final int INTRODUCE_VARIABLE = 2;
120.109 + private static final int INTRODUCE_CONSTANT = 4;
120.110 + private static final int INTRODUCE_FIELD = 8;
120.111 + private static final int NON_EXPRESSIONS = INTRODUCE_VARIABLE | INTRODUCE_FIELD | INTRODUCE_CONSTANT;
120.112 + private static final int ALL = ~0;
120.113 +
120.114 + @Override
120.115 + protected int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange) {
120.116 + return ApplicabilityVisitor.getType(root, astRange);
120.117 + }
120.118 +
120.119 + @Override
120.120 + public void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability) {
120.121 + int start = range.getStart();
120.122 + int end = range.getEnd();
120.123 +
120.124 +// HACK: Only extract method works at this point
120.125 + applicability = applicability & INTRODUCE_METHOD;
120.126 +
120.127 +
120.128 + // Adjust the fix range to be right around the dot so that the light bulb ends up
120.129 + // on the same line as the caret and alt-enter works
120.130 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
120.131 + if (target != null) {
120.132 + int dot = target.getCaret().getDot();
120.133 + range = new OffsetRange(dot, dot);
120.134 + }
120.135 +
120.136 + List<HintFix> fixList = new ArrayList<>(3);
120.137 + if ((applicability & INTRODUCE_METHOD) != 0) {
120.138 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_METHOD));
120.139 + }
120.140 + if ((applicability & INTRODUCE_VARIABLE) != 0) {
120.141 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_VARIABLE));
120.142 + }
120.143 + if ((applicability & INTRODUCE_CONSTANT) != 0) {
120.144 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_CONSTANT));
120.145 + }
120.146 + if ((applicability & INTRODUCE_FIELD) != 0) {
120.147 + fixList.add(new ExtractCodeFix(context, start, end, INTRODUCE_FIELD));
120.148 + }
120.149 + if (fixList.size() > 0) {
120.150 + String displayName = getDisplayName();
120.151 + Hint desc = new Hint(this, displayName, context.parserResult.getSnapshot().getSource().getFileObject(),
120.152 + range, fixList, 490);
120.153 + result.add(desc);
120.154 + }
120.155 + }
120.156 +
120.157 + @Override
120.158 + public boolean appliesTo(RuleContext context) {
120.159 + return true;
120.160 + }
120.161 +
120.162 + @Override
120.163 + public String getDisplayName() {
120.164 + return NbBundle.getMessage(ExtractCode.class, "ExtractCode");
120.165 + }
120.166 +
120.167 + @Override
120.168 + public String getId() {
120.169 + return "ExtractCode"; // NOI18N
120.170 + }
120.171 +
120.172 + @Override
120.173 + public String getDescription() {
120.174 + return "";
120.175 + }
120.176 +
120.177 + @Override
120.178 + public boolean getDefaultEnabled() {
120.179 + return true;
120.180 + }
120.181 +
120.182 + @Override
120.183 + public JComponent getCustomizer(Preferences node) {
120.184 + return null;
120.185 + }
120.186 +
120.187 + @Override
120.188 + public boolean showInTasklist() {
120.189 + return false;
120.190 + }
120.191 +
120.192 + @Override
120.193 + public HintSeverity getDefaultSeverity() {
120.194 + return HintSeverity.CURRENT_LINE_WARNING;
120.195 + }
120.196 +
120.197 + private static class ExtractCodeFix implements PreviewableFix {
120.198 + private final PythonRuleContext context;
120.199 + //private Position callSitePos;
120.200 + //private Position extractedPos;
120.201 + private int finalCallSiteOffset;
120.202 + private int finalExtractedSiteOffset;
120.203 + ;
120.204 + private final int type;
120.205 + private final int start;
120.206 + private final int end;
120.207 + private String newName;
120.208 +
120.209 + private ExtractCodeFix(PythonRuleContext context,
120.210 + int start, int end, int type) {
120.211 + this.context = context;
120.212 +
120.213 + OffsetRange range = PythonLexerUtils.narrow(context.doc, new OffsetRange(start, end), false);
120.214 + this.start = range.getStart();
120.215 + this.end = range.getEnd();
120.216 +
120.217 + this.type = type;
120.218 + }
120.219 +
120.220 + @Override
120.221 + public String getDescription() {
120.222 + switch (type) {
120.223 + case INTRODUCE_VARIABLE:
120.224 + return NbBundle.getMessage(CreateDocString.class, "IntroduceVariable");
120.225 + case INTRODUCE_CONSTANT:
120.226 + return NbBundle.getMessage(CreateDocString.class, "IntroduceConstant");
120.227 + case INTRODUCE_METHOD:
120.228 + return NbBundle.getMessage(CreateDocString.class, "IntroduceMethod");
120.229 + case INTRODUCE_FIELD:
120.230 + return NbBundle.getMessage(CreateDocString.class, "IntroduceField");
120.231 + default:
120.232 + throw new IllegalArgumentException();
120.233 + }
120.234 + }
120.235 +
120.236 + @Override
120.237 + public boolean canPreview() {
120.238 + return true;
120.239 + }
120.240 +
120.241 + @Override
120.242 + public EditList getEditList() throws Exception {
120.243 + BaseDocument doc = context.doc;
120.244 + PythonParserResult info = (PythonParserResult) context.parserResult;
120.245 + EditList edits = new EditList(doc);
120.246 +
120.247 + int extractedOffset = doc.getLength();
120.248 + int prevFunctionOffset = 0;
120.249 + PythonTree root = PythonAstUtils.getRoot(info);
120.250 +
120.251 + OffsetRange narrowed = PythonLexerUtils.narrow(doc, new OffsetRange(start, end), true);
120.252 +
120.253 + int astStart = PythonAstUtils.getAstOffset(info, narrowed != OffsetRange.NONE ? narrowed.getStart() : start);
120.254 + int astEnd = PythonAstUtils.getAstOffset(info, narrowed != OffsetRange.NONE ? narrowed.getEnd() : end);
120.255 + if (astStart == -1 || astEnd == -1) {
120.256 + return edits;
120.257 + }
120.258 + AstPath startPath = AstPath.get(root, astStart);
120.259 + AstPath endPath = AstPath.get(root, astEnd);
120.260 + PythonTree localScope = PythonAstUtils.getLocalScope(startPath);
120.261 + if (localScope != null) {
120.262 + OffsetRange astRange = PythonAstUtils.getRange(localScope);
120.263 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
120.264 + if (lexRange != OffsetRange.NONE) {
120.265 + extractedOffset = lexRange.getEnd();
120.266 +
120.267 + // Function end offsets are a bit sloppy so try to deal with that
120.268 + int firstNonWhite = Utilities.getRowFirstNonWhite(doc, Math.min(extractedOffset, doc.getLength()));
120.269 + if (firstNonWhite == -1 || extractedOffset <= firstNonWhite) {
120.270 + extractedOffset = Utilities.getRowStart(doc, extractedOffset);
120.271 + }
120.272 +
120.273 + prevFunctionOffset = lexRange.getStart();
120.274 + if (extractedOffset > doc.getLength()) {
120.275 + extractedOffset = doc.getLength();
120.276 + }
120.277 + }
120.278 + }
120.279 + int callSiteOffset = start;
120.280 + int callSiteReplaceLength = end - start;
120.281 +
120.282 + int indentSize = IndentUtils.indentLevelSize(doc);
120.283 + int lineStart = Utilities.getRowStart(doc, prevFunctionOffset);
120.284 + int initialIndent = IndentUtils.lineIndent(doc, lineStart);
120.285 + String initialIndentStr = IndentUtils.createIndentString(doc, initialIndent);
120.286 +
120.287 + newName = "new_name"; // TODO - localize!
120.288 +
120.289 + // Compute input/output arguments
120.290 + PythonTree startNode = startPath.leaf();
120.291 + PythonTree endNode = endPath.leaf();
120.292 +
120.293 + InputOutputFinder finder = new InputOutputFinder(startNode, endNode, Collections.<PythonTree>emptyList());
120.294 + finder.traverse(localScope);
120.295 + List<String> inParams = new ArrayList<>(finder.getInputVars());
120.296 + List<String> outParams = new ArrayList<>(finder.getOutputVars());
120.297 + Collections.sort(inParams);
120.298 + Collections.sort(outParams);
120.299 +
120.300 + ClassDef cls = PythonAstUtils.getClassDef(startPath);
120.301 +
120.302 + // Adjust the insert location in case we are at the top level
120.303 + if (cls == null && PythonAstUtils.getFuncDef(startPath) == null) {
120.304 + extractedOffset = -1;
120.305 + PythonTree top = startPath.topModuleLevel();
120.306 + if (top != null) {
120.307 + OffsetRange astRange = PythonAstUtils.getRange(top);
120.308 + extractedOffset = PythonLexerUtils.getLexerOffset(info, astRange.getStart());
120.309 + }
120.310 +
120.311 + // We're at the top level - I can't insert the function -after- the current function
120.312 + // because that will result in a runtime error
120.313 + if (extractedOffset == -1) {
120.314 + extractedOffset = Utilities.getRowStart(doc, Math.min(doc.getLength(), start));
120.315 + }
120.316 + }
120.317 +
120.318 + String extractedCode = null;
120.319 + int extractedSiteDelta = 0;
120.320 + if (type == INTRODUCE_METHOD) {
120.321 + StringBuilder sb = new StringBuilder();
120.322 + if (Utilities.getRowStart(doc, Math.min(extractedOffset, doc.getLength())) < extractedOffset) {
120.323 + sb.append("\n"); // NOI18N
120.324 + }
120.325 + sb.append("\n"); // NOI18N
120.326 + sb.append(initialIndentStr);
120.327 + sb.append("def "); // NOI18N
120.328 + extractedSiteDelta = sb.length();
120.329 + sb.append(newName);
120.330 + sb.append("("); // NOI18N
120.331 + if (cls != null) {
120.332 + sb.append("self"); // NOI18N
120.333 + if (inParams.size() > 0) {
120.334 + sb.append(", "); // NOI18N
120.335 + }
120.336 + }
120.337 + boolean first = true;
120.338 + for (String param : inParams) {
120.339 + if (first) {
120.340 + first = false;
120.341 + } else {
120.342 + sb.append(", "); // NOI18N
120.343 + }
120.344 + sb.append(param);
120.345 + }
120.346 + sb.append("):\n"); // NOI18N
120.347 +
120.348 + // Copy in the extracted code
120.349 + int firstIndent = IndentUtils.lineIndent(doc, Utilities.getRowStart(doc, start));
120.350 + for (int offset = start; offset < end; offset = Utilities.getRowEnd(doc, offset) + 1) {
120.351 + // TODO - handle multiline literal strings correctly!!!
120.352 + if (!(Utilities.isRowEmpty(doc, offset) || Utilities.isRowWhite(doc, offset))) {
120.353 + int lineIndent = IndentUtils.lineIndent(doc, Utilities.getRowStart(doc, offset));
120.354 + int newIndent = (lineIndent - firstIndent) + initialIndent + indentSize;
120.355 + if (newIndent > 0) {
120.356 + sb.append(IndentUtils.createIndentString(doc, newIndent));
120.357 + }
120.358 + int rowFirstNonWhite = Utilities.getRowFirstNonWhite(doc, offset);
120.359 + int rowLastNonWhite = Utilities.getRowLastNonWhite(doc, offset) + 1; // +1: doesn't include last char
120.360 + sb.append(doc.getText(rowFirstNonWhite, rowLastNonWhite - rowFirstNonWhite));
120.361 + }
120.362 + sb.append("\n"); // NOI18N
120.363 + }
120.364 + sb.append("\n");
120.365 +
120.366 + if (outParams.size() > 0) {
120.367 + sb.append(IndentUtils.createIndentString(doc, initialIndent + indentSize));
120.368 + sb.append("return "); // NOI18N
120.369 + first = true;
120.370 + for (String param : outParams) {
120.371 + if (first) {
120.372 + first = false;
120.373 + } else {
120.374 + // No spaces in the comma list for return tuples
120.375 + sb.append(","); // NOI18N
120.376 + }
120.377 + sb.append(param);
120.378 + }
120.379 + sb.append("\n\n"); // NOI18N
120.380 + }
120.381 +
120.382 + // Insert the extracted code at the end
120.383 + extractedCode = sb.toString();
120.384 + } else {
120.385 + assert (type == INTRODUCE_FIELD || type == INTRODUCE_CONSTANT || type == INTRODUCE_VARIABLE);
120.386 + throw new RuntimeException("Not yet implemented");
120.387 + }
120.388 +
120.389 + // Replace the code at the extract site with just the call
120.390 + StringBuilder sb = new StringBuilder();
120.391 + if (type == INTRODUCE_METHOD) {
120.392 + // Assign to the output variables if any
120.393 + if (outParams.size() > 0) {
120.394 + boolean first = true;
120.395 + for (String param : outParams) {
120.396 + if (first) {
120.397 + first = false;
120.398 + } else {
120.399 + // No spaces in the comma list for return tuples
120.400 + sb.append(","); // NOI18N
120.401 + }
120.402 + sb.append(param);
120.403 + }
120.404 +
120.405 + sb.append(" = ");
120.406 + }
120.407 + } else {
120.408 + assert (type == INTRODUCE_FIELD || type == INTRODUCE_CONSTANT || type == INTRODUCE_VARIABLE);
120.409 + }
120.410 +
120.411 + int callSiteDelta = sb.length();
120.412 + sb.append(newName);
120.413 + if (type == INTRODUCE_METHOD) {
120.414 + sb.append('(');
120.415 + if (cls != null) {
120.416 + sb.append("self"); // NOI18N
120.417 + if (inParams.size() > 0) {
120.418 + sb.append(", "); // NOI18N
120.419 + }
120.420 + }
120.421 + boolean first = true;
120.422 + for (String param : inParams) {
120.423 + if (first) {
120.424 + first = false;
120.425 + } else {
120.426 + sb.append(", "); // NOI18N
120.427 + }
120.428 + sb.append(param);
120.429 + }
120.430 + sb.append(')');
120.431 + }
120.432 + String callSiteCode = sb.toString();
120.433 +
120.434 +
120.435 + // Apply changes
120.436 + if (extractedOffset >= callSiteOffset && extractedOffset <= callSiteOffset + callSiteReplaceLength) {
120.437 + if (extractedOffset > callSiteOffset) {
120.438 + // We're trying to insert the extracted code segment after the call - that must mean we're
120.439 + // in something like a function
120.440 + edits.replace(callSiteOffset, callSiteReplaceLength, callSiteCode + extractedCode, false, 0);
120.441 +
120.442 + // Work around bug in Document.Position
120.443 + //extractedPos = edits.createPosition(callSiteOffset+callSiteCode.length()+extractedSiteDelta, Bias.Forward);
120.444 + //callSitePos = edits.createPosition(callSiteOffset+callSiteDelta, Bias.Forward);
120.445 + finalCallSiteOffset = callSiteOffset + callSiteDelta;
120.446 + finalExtractedSiteOffset = callSiteOffset + callSiteCode.length() + extractedSiteDelta;
120.447 + } else {
120.448 + edits.replace(callSiteOffset, callSiteReplaceLength, extractedCode + callSiteCode, false, 0);
120.449 +
120.450 + // Work around bug in Document.Position
120.451 + //extractedPos = edits.createPosition(callSiteOffset+extractedSiteDelta, Bias.Forward);
120.452 + //callSitePos = edits.createPosition(callSiteOffset+extractedCode.length()+callSiteDelta, Bias.Forward);
120.453 + finalCallSiteOffset = callSiteOffset + extractedCode.length() + callSiteDelta;
120.454 + finalExtractedSiteOffset = callSiteOffset + extractedSiteDelta;
120.455 + }
120.456 + } else {
120.457 + edits.replace(extractedOffset, 0, extractedCode, false, 1);
120.458 + edits.replace(callSiteOffset, callSiteReplaceLength, callSiteCode, false, 0);
120.459 +
120.460 + // There's a bug document/editlist position code - the offsets aren't updated on my
120.461 + // edits! For now just compute the offsets directly since we know the exact edits applied
120.462 + //extractedPos = edits.createPosition(extractedOffset+extractedSiteDelta, Bias.Backward);
120.463 + //callSitePos = edits.createPosition(callSiteOffset+callSiteDelta, Bias.Backward);
120.464 + if (extractedOffset < callSiteOffset) {
120.465 + finalCallSiteOffset = callSiteOffset + callSiteDelta + extractedCode.length();
120.466 + finalExtractedSiteOffset = extractedOffset + extractedSiteDelta;
120.467 + } else {
120.468 + finalCallSiteOffset = callSiteOffset + callSiteDelta;
120.469 + finalExtractedSiteOffset = extractedOffset + extractedSiteDelta + callSiteCode.length() - callSiteReplaceLength;
120.470 + }
120.471 + }
120.472 +
120.473 + return edits;
120.474 + }
120.475 +
120.476 + @Override
120.477 + public void implement() throws Exception {
120.478 + EditList edits = getEditList();
120.479 +
120.480 + edits.apply();
120.481 +
120.482 + // Refactoring isn't necessary here since local variables and block
120.483 + // variables are limited to the local scope, so we can accurately just
120.484 + // find their positions using the AST and let the user edit them synchronously.
120.485 + Set<OffsetRange> ranges = new HashSet<>();
120.486 + int length = newName.length();
120.487 + ranges.add(new OffsetRange(finalCallSiteOffset, finalCallSiteOffset + length));
120.488 + ranges.add(new OffsetRange(finalExtractedSiteOffset, finalExtractedSiteOffset + length));
120.489 +
120.490 + // Initiate synchronous editing:
120.491 + EditRegions.getInstance().edit(context.parserResult.getSnapshot().getSource().getFileObject(), ranges, finalExtractedSiteOffset);
120.492 + }
120.493 +
120.494 + @Override
120.495 + public boolean isSafe() {
120.496 + return true;
120.497 + }
120.498 +
120.499 + @Override
120.500 + public boolean isInteractive() {
120.501 + return false;
120.502 + }
120.503 + }
120.504 +
120.505 + /** @todo Prune search in traverse, ala AstPath.
120.506 + * @todo Build up start and end AstPaths.
120.507 + */
120.508 + private static class ApplicabilityVisitor extends Visitor {
120.509 + private boolean applies = true;
120.510 + private int disabled;
120.511 + private int enabled;
120.512 + private final int start;
120.513 + private final int end;
120.514 +
120.515 + static int getType(PythonTree root, OffsetRange astRange) {
120.516 + ApplicabilityVisitor visitor = new ApplicabilityVisitor(astRange);
120.517 + try {
120.518 + visitor.visit(root);
120.519 + } catch (Exception ex) {
120.520 + Exceptions.printStackTrace(ex);
120.521 + return 0;
120.522 + }
120.523 + return visitor.getType();
120.524 + }
120.525 +
120.526 + ApplicabilityVisitor(OffsetRange astRange) {
120.527 + this.start = astRange.getStart();
120.528 + this.end = astRange.getEnd();
120.529 + }
120.530 +
120.531 + private void enable(PythonTree node, int mask) {
120.532 + if (node.getCharStartIndex() >= start && node.getCharStopIndex() <= end) {
120.533 + enabled |= mask;
120.534 + }
120.535 + }
120.536 +
120.537 + private void disable(PythonTree node, int mask) {
120.538 + if (node.getCharStartIndex() >= start && node.getCharStopIndex() <= end) {
120.539 + disabled |= mask;
120.540 + }
120.541 + }
120.542 +
120.543 + public int getType() {
120.544 + return enabled & ~disabled;
120.545 + }
120.546 +
120.547 + private void maybeBail(PythonTree node) {
120.548 + int nodeStart = node.getCharStartIndex();
120.549 + int nodeEnd = node.getCharStopIndex();
120.550 + if (nodeStart >= start && nodeStart < end) {
120.551 + applies = false;
120.552 + disable(node, ALL);
120.553 + }
120.554 + if (nodeEnd > start && nodeEnd < end) {
120.555 + applies = false;
120.556 + disable(node, ALL);
120.557 + }
120.558 + }
120.559 +
120.560 + @Override
120.561 + public void traverse(PythonTree node) throws Exception {
120.562 + if (!applies) {
120.563 + return;
120.564 + }
120.565 +
120.566 + int nodeStart = node.getCharStartIndex();
120.567 + int nodeStop = node.getCharStopIndex();
120.568 + //if (!(nodeStop < start || nodeStart > end)) {
120.569 + if (nodeStop >= start && nodeStart <= end) {
120.570 + super.traverse(node);
120.571 + }
120.572 + }
120.573 +
120.574 + @Override
120.575 + public Object visitClassDef(ClassDef node) throws Exception {
120.576 + maybeBail(node);
120.577 + return super.visitClassDef(node);
120.578 + }
120.579 +
120.580 + @Override
120.581 + public Object visitFunctionDef(FunctionDef node) throws Exception {
120.582 + maybeBail(node);
120.583 + return super.visitFunctionDef(node);
120.584 + }
120.585 +
120.586 + @Override
120.587 + public Object visitImport(Import node) throws Exception {
120.588 + disable(node, ALL);
120.589 + return super.visitImport(node);
120.590 + }
120.591 +
120.592 + @Override
120.593 + public Object visitImportFrom(ImportFrom node) throws Exception {
120.594 + disable(node, ALL);
120.595 + return super.visitImportFrom(node);
120.596 + }
120.597 +
120.598 + @Override
120.599 + public Object visitAssign(Assign node) throws Exception {
120.600 + disable(node, NON_EXPRESSIONS);
120.601 + disable(node, NON_EXPRESSIONS);
120.602 + return super.visitAssign(node);
120.603 + }
120.604 +
120.605 + @Override
120.606 + public Object visitCall(Call node) throws Exception {
120.607 + enable(node, ALL);
120.608 + disable(node, INTRODUCE_CONSTANT);
120.609 + return super.visitCall(node);
120.610 + }
120.611 +
120.612 + @Override
120.613 + public Object visitAugAssign(AugAssign node) throws Exception {
120.614 + disable(node, NON_EXPRESSIONS);
120.615 + return super.visitAugAssign(node);
120.616 + }
120.617 +
120.618 + @Override
120.619 + public Object visitBreak(Break node) throws Exception {
120.620 + disable(node, NON_EXPRESSIONS);
120.621 + return super.visitBreak(node);
120.622 + }
120.623 +
120.624 + @Override
120.625 + public Object visitContinue(Continue node) throws Exception {
120.626 + disable(node, NON_EXPRESSIONS);
120.627 + return super.visitContinue(node);
120.628 + }
120.629 +
120.630 + @Override
120.631 + public Object visitDelete(Delete node) throws Exception {
120.632 + disable(node, NON_EXPRESSIONS);
120.633 + return super.visitDelete(node);
120.634 + }
120.635 +
120.636 + @Override
120.637 + public Object visitFor(For node) throws Exception {
120.638 + disable(node, NON_EXPRESSIONS);
120.639 + return super.visitFor(node);
120.640 + }
120.641 +
120.642 + @Override
120.643 + public Object visitIf(If node) throws Exception {
120.644 + disable(node, NON_EXPRESSIONS);
120.645 + return super.visitIf(node);
120.646 + }
120.647 +
120.648 + @Override
120.649 + public Object visitIfExp(IfExp node) throws Exception {
120.650 + disable(node, NON_EXPRESSIONS);
120.651 + return super.visitIfExp(node);
120.652 + }
120.653 +
120.654 + @Override
120.655 + public Object visitPrint(Print node) throws Exception {
120.656 + disable(node, NON_EXPRESSIONS);
120.657 + return super.visitPrint(node);
120.658 + }
120.659 +
120.660 + @Override
120.661 + public Object visitYield(Yield node) throws Exception {
120.662 + disable(node, NON_EXPRESSIONS);
120.663 + return super.visitYield(node);
120.664 + }
120.665 +
120.666 + @Override
120.667 + public Object visitWith(With node) throws Exception {
120.668 + disable(node, NON_EXPRESSIONS);
120.669 + return super.visitWith(node);
120.670 + }
120.671 +
120.672 + @Override
120.673 + public Object visitWhile(While node) throws Exception {
120.674 + disable(node, NON_EXPRESSIONS);
120.675 + return super.visitWhile(node);
120.676 + }
120.677 +
120.678 + @Override
120.679 + public Object visitTryFinally(TryFinally node) throws Exception {
120.680 + disable(node, NON_EXPRESSIONS);
120.681 + return super.visitTryFinally(node);
120.682 + }
120.683 +
120.684 + @Override
120.685 + public Object visitTryExcept(TryExcept node) throws Exception {
120.686 + disable(node, NON_EXPRESSIONS);
120.687 + return super.visitTryExcept(node);
120.688 + }
120.689 +
120.690 + @Override
120.691 + public Object visitSuite(Suite node) throws Exception {
120.692 + disable(node, NON_EXPRESSIONS);
120.693 + return super.visitSuite(node);
120.694 + }
120.695 +
120.696 + @Override
120.697 + public Object visitReturn(Return node) throws Exception {
120.698 +// disable(node, NON_EXPRESSIONS);
120.699 + // TODO - handle flow control!!
120.700 + disable(node, ALL);
120.701 + return super.visitReturn(node);
120.702 + }
120.703 +
120.704 + @Override
120.705 + public Object visitModule(Module node) throws Exception {
120.706 + if (node.getCharStartIndex() > start && node.getCharStopIndex() < end) {
120.707 +// disable(node, NON_EXPRESSIONS);
120.708 + disable(node, ALL);
120.709 + }
120.710 + return super.visitModule(node);
120.711 + }
120.712 +
120.713 + @Override
120.714 + public Object visitPass(Pass node) throws Exception {
120.715 + disable(node, NON_EXPRESSIONS);
120.716 + return super.visitPass(node);
120.717 + }
120.718 +
120.719 + @Override
120.720 + public Object visitRaise(Raise node) throws Exception {
120.721 + disable(node, NON_EXPRESSIONS);
120.722 + return super.visitRaise(node);
120.723 + }
120.724 +
120.725 + @Override
120.726 + public Object visitAssert(Assert node) throws Exception {
120.727 + disable(node, NON_EXPRESSIONS);
120.728 + return super.visitAssert(node);
120.729 + }
120.730 +
120.731 + @Override
120.732 + public Object visitNum(Num node) throws Exception {
120.733 + enable(node, ALL);
120.734 + return super.visitNum(node);
120.735 + }
120.736 +
120.737 + @Override
120.738 + public Object visitName(Name node) throws Exception {
120.739 + enable(node, ALL);
120.740 + return super.visitName(node);
120.741 + }
120.742 +
120.743 + @Override
120.744 + public Object visitGlobal(Global node) throws Exception {
120.745 + enable(node, ALL);
120.746 + disable(node, INTRODUCE_CONSTANT);
120.747 + return super.visitGlobal(node);
120.748 + }
120.749 +
120.750 + @Override
120.751 + public Object visitTuple(Tuple node) throws Exception {
120.752 + enable(node, ALL);
120.753 + return super.visitTuple(node);
120.754 + }
120.755 +
120.756 + @Override
120.757 + public Object visitStr(Str node) throws Exception {
120.758 + enable(node, ALL);
120.759 + return super.visitStr(node);
120.760 + }
120.761 + }
120.762 +}
121.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
121.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/InputOutputFinder.java Wed Sep 02 20:31:18 2015 +0200
121.3 @@ -0,0 +1,304 @@
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 + * If you wish your version of this file to be governed by only the CDDL
121.31 + * or only the GPL Version 2, indicate your decision by adding
121.32 + * "[Contributor] elects to include this software in this distribution
121.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
121.34 + * single choice of license, a recipient has the option to distribute
121.35 + * your version of this file under either the CDDL, the GPL Version 2 or
121.36 + * to extend the choice of license to its licensees as provided above.
121.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
121.38 + * Version 2 license, then the option applies only if the new code is
121.39 + * made subject to such option by the copyright holder.
121.40 + *
121.41 + * Contributor(s):
121.42 + *
121.43 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
121.44 + */
121.45 +package org.netbeans.modules.python.hints;
121.46 +
121.47 +import java.util.HashMap;
121.48 +import java.util.HashSet;
121.49 +import java.util.List;
121.50 +import java.util.Map;
121.51 +import java.util.Set;
121.52 +import org.netbeans.modules.python.source.PythonAstUtils;
121.53 +import org.python.antlr.PythonTree;
121.54 +import org.python.antlr.Visitor;
121.55 +import org.python.antlr.ast.Assign;
121.56 +import org.python.antlr.ast.Call;
121.57 +import org.python.antlr.ast.FunctionDef;
121.58 +import org.python.antlr.ast.Name;
121.59 +import org.python.antlr.base.expr;
121.60 +
121.61 +/**
121.62 + * This visitor computes the set of input and output variables required by
121.63 + * a code block for extract method.
121.64 + * In particular, it tracks the local variable assignments inside the method,
121.65 + * and checks which are used outside of the method (which would make it an
121.66 + * output variable) and similarly, which variables are used inside the method
121.67 + * before getting assigned (which would make it an input variable).
121.68 + *
121.69 + * @author Tor Norbye
121.70 + */
121.71 +class InputOutputFinder extends Visitor {
121.72 + //private enum When { BEFORE, DURING, AFTER };
121.73 + private static final int WHEN_BEFORE = 0;
121.74 + private static final int WHEN_DURING = 1;
121.75 + private static final int WHEN_AFTER = 2;
121.76 + private final PythonTree startNode;
121.77 + private final PythonTree endNode;
121.78 + private final int startPos;
121.79 + private final int endPos;
121.80 + private final List<PythonTree> applicableBlocks;
121.81 + private int when = WHEN_BEFORE;
121.82 + private int ifs;
121.83 + //private PythonTree currentBlock;
121.84 + //private final List<PythonTree> blockStack = new ArrayList<PythonTree>(); // JDK16: Use Deque
121.85 + private Map<PythonTree, UsageScope> blockScopes = new HashMap<>();
121.86 + private UsageScope methodScope = new UsageScope(null);
121.87 + //private UsageScope blockScope;
121.88 + private PythonTree parent;
121.89 + private boolean isWriting;
121.90 +
121.91 + /** The node ranges are inclusive */
121.92 + InputOutputFinder(PythonTree startNode, PythonTree endNode, List<PythonTree> applicableBlocks) {
121.93 + this.startNode = startNode;
121.94 + this.endNode = endNode;
121.95 + this.applicableBlocks = applicableBlocks;
121.96 +
121.97 + startPos = startNode.getCharStartIndex();
121.98 + endPos = endNode.getCharStopIndex();
121.99 + }
121.100 +
121.101 + public Set<String> getInputVars() {
121.102 + UsageScope scope = methodScope;
121.103 + for (UsageScope s : blockScopes.values()) {
121.104 + if (s.block != null && !applicableBlocks.contains(s.block)) {
121.105 + continue;
121.106 + }
121.107 + scope.merge(s);
121.108 + }
121.109 +
121.110 + Set<String> inputs = new HashSet<>(scope.readDuring);
121.111 + // But not read before
121.112 + inputs.removeAll(scope.writtenBeforeReadDuring);
121.113 +
121.114 + // Also need to pass in any variables I'm modifying that are read after
121.115 + Set<String> outputs = new HashSet<>(scope.writtenDuring);
121.116 + outputs.retainAll(scope.readAfter);
121.117 + Set<String> extraOutputs = new HashSet<>(scope.writtenBefore);
121.118 + extraOutputs.retainAll(outputs);
121.119 + // unless they are written before read
121.120 + extraOutputs.removeAll(scope.writtenBeforeReadDuring);
121.121 + inputs.addAll(extraOutputs);
121.122 +
121.123 + return inputs;
121.124 + }
121.125 +
121.126 + public Set<String> getOutputVars() {
121.127 + UsageScope scope = methodScope;
121.128 + for (UsageScope s : blockScopes.values()) {
121.129 + if (s.block != null && !applicableBlocks.contains(s.block)) {
121.130 + continue;
121.131 + }
121.132 + scope.merge(s);
121.133 + }
121.134 +
121.135 + Set<String> outputs = new HashSet<>(scope.writtenDuring);
121.136 + outputs.retainAll(scope.readAfter);
121.137 +
121.138 + return outputs;
121.139 + }
121.140 +
121.141 + @Override
121.142 + public Object visitFunctionDef(FunctionDef node) throws Exception {
121.143 + // Record the parameters
121.144 +// assert when == WHEN_BEFORE; // Is this true when I extract a whole method? I can't do that, right?
121.145 + boolean x = true;
121.146 + assert x;
121.147 +
121.148 + for (String param : PythonAstUtils.getParameters(node)) {
121.149 + methodScope.write(param);
121.150 + }
121.151 +
121.152 + return super.visitFunctionDef(node);
121.153 + }
121.154 +
121.155 + @SuppressWarnings("unchecked")
121.156 + @Override
121.157 + public Object visitAssign(Assign node) throws Exception {
121.158 + // Visit the right hand side of the assignment first, such
121.159 + // that with for example
121.160 + // x = x + 1
121.161 + // we treat this as a read of x, before a write of x.
121.162 + // The Assign.traverse() implementation will do the targets first,
121.163 + // so we explicitly do it here in the opposite order instead...
121.164 +
121.165 + if (when == WHEN_BEFORE && node.getCharStartIndex() >= startPos) {
121.166 + when = WHEN_DURING;
121.167 + }
121.168 + int oldWhen = when;
121.169 +
121.170 + expr nodeValue = node.getInternalValue();
121.171 + if (nodeValue != null) {
121.172 + nodeValue.accept(this);
121.173 + }
121.174 + int newWhen = when;
121.175 + when = oldWhen;
121.176 +
121.177 + boolean oldWriting = isWriting;
121.178 + try {
121.179 + isWriting = true;
121.180 + List<expr> targets = node.getInternalTargets();
121.181 + if (targets != null) {
121.182 + for (expr expr : targets) {
121.183 + if (expr != null) {
121.184 + expr.accept(this);
121.185 + }
121.186 + }
121.187 + }
121.188 + } finally {
121.189 + isWriting = oldWriting;
121.190 + }
121.191 +
121.192 + when = newWhen;
121.193 +
121.194 + return node;
121.195 + }
121.196 +
121.197 + @Override
121.198 + public Object visitName(Name node) throws Exception {
121.199 + if (parent instanceof Call && ((Call)parent).getInternalFunc() == node) { // Name in a call is the call name, not a variable
121.200 + return super.visitName(node);
121.201 + }
121.202 +
121.203 + methodScope.read(node.getInternalId());
121.204 +
121.205 + return super.visitName(node);
121.206 + }
121.207 +
121.208 + @Override
121.209 + public void traverse(PythonTree node) throws Exception {
121.210 + if (node == startNode) {
121.211 + when = WHEN_DURING;
121.212 + }
121.213 +
121.214 + PythonTree oldParent = parent;
121.215 + parent = node;
121.216 + super.traverse(node);
121.217 + parent = oldParent;
121.218 +
121.219 + if (node == endNode) {
121.220 + when = WHEN_AFTER;
121.221 + }
121.222 +
121.223 + }
121.224 +
121.225 + private class UsageScope {
121.226 + UsageScope(PythonTree block) {
121.227 + this.block = block;
121.228 + }
121.229 +
121.230 + private void read(String name) {
121.231 + // No need to pass class references or constants in/out
121.232 + // TODO: Make this smarter such that what it really does
121.233 + // is ignore any variables that aren't defined locally - so
121.234 + // global variables for example aren't passed in since they
121.235 + // can -also- be accessed from the extracted method.
121.236 + if (Character.isUpperCase(name.charAt(0))) {
121.237 + return;
121.238 + }
121.239 +
121.240 + if (isWriting) {
121.241 + // A read in the AST for example on the left hand side of an
121.242 + // assignment is really a write
121.243 + write(name);
121.244 + return;
121.245 + }
121.246 +
121.247 + if (when == WHEN_DURING) {
121.248 + if (!writtenBeforeReadDuring.contains(name)) {
121.249 + readDuring.add(name);
121.250 + }
121.251 + } else if (when == WHEN_AFTER) {
121.252 + // I don't want a reassignment of the variable before it's been
121.253 + // read to count as a usage of the result from the fragment
121.254 + if (!writtenAfter.contains(name)) {
121.255 + readAfter.add(name);
121.256 + }
121.257 + }
121.258 + }
121.259 +
121.260 + private void write(String name) {
121.261 + // No need to pass class references or constants in/out
121.262 + // TODO: Make this smarter such that what it really does
121.263 + // is ignore any variables that aren't defined locally - so
121.264 + // global variables for example aren't passed in since they
121.265 + // can -also- be accessed from the extracted method.
121.266 + if (Character.isUpperCase(name.charAt(0))) {
121.267 + return;
121.268 + }
121.269 +
121.270 + if (when == WHEN_BEFORE) {
121.271 + writtenBefore.add(name);
121.272 + } else if (when == WHEN_DURING) {
121.273 + writtenDuring.add(name);
121.274 + if (ifs == 0 && !readDuring.contains(name)) {
121.275 + writtenBeforeReadDuring.add(name);
121.276 + }
121.277 + } else if (when == WHEN_AFTER) {
121.278 + if (ifs == 0 && !readAfter.contains(name)) {
121.279 + writtenAfter.add(name);
121.280 + }
121.281 + }
121.282 + }
121.283 +
121.284 + private void merge(UsageScope other) {
121.285 + writtenBefore.addAll(other.writtenBefore);
121.286 + readDuring.addAll(other.readDuring);
121.287 + writtenDuring.addAll(other.writtenDuring);
121.288 + writtenBeforeReadDuring.addAll(other.writtenBeforeReadDuring);
121.289 + writtenAfter.addAll(other.writtenAfter);
121.290 + readAfter.addAll(other.readAfter);
121.291 + }
121.292 + /** Block, or null if it's the local method */
121.293 + private PythonTree block;
121.294 + /** Variables that exist in scope before the code fragment */
121.295 + private final Set<String> writtenBefore = new HashSet<>();
121.296 + /** Variables that are read during the code fragment */
121.297 + private final Set<String> readDuring = new HashSet<>(); // rename readBeforeWrittenDuring
121.298 + /** Variables that are written to during the code fragment */
121.299 + private final Set<String> writtenDuring = new HashSet<>();
121.300 + /** Variables that are written to during the code fragment */
121.301 + private final Set<String> writtenBeforeReadDuring = new HashSet<>();
121.302 + /** Variables that are written PRIOR TO A READ OF THE SAME VAR after the code fragment */
121.303 + private final Set<String> writtenAfter = new HashSet<>(); // rename writtenBeforeReadAfter
121.304 + /** Variables that are read (prior to a write) after the code fragment */
121.305 + private final Set<String> readAfter = new HashSet<>(); // rename readBeforeWrittenAfter
121.306 + }
121.307 +}
122.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
122.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/NameRule.java Wed Sep 02 20:31:18 2015 +0200
122.3 @@ -0,0 +1,524 @@
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 + * Contributor(s):
122.31 + *
122.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
122.33 + */
122.34 +package org.netbeans.modules.python.hints;
122.35 +
122.36 +import org.netbeans.modules.python.source.NameStyle;
122.37 +import java.util.ArrayList;
122.38 +import java.util.Collections;
122.39 +import java.util.HashSet;
122.40 +import java.util.List;
122.41 +import java.util.Set;
122.42 +import java.util.prefs.Preferences;
122.43 +import javax.swing.JComponent;
122.44 +import org.netbeans.editor.BaseDocument;
122.45 +import org.netbeans.editor.Utilities;
122.46 +import org.netbeans.modules.csl.api.EditList;
122.47 +import org.netbeans.modules.csl.api.Hint;
122.48 +import org.netbeans.modules.csl.api.HintFix;
122.49 +import org.netbeans.modules.csl.api.HintSeverity;
122.50 +import org.netbeans.modules.csl.api.OffsetRange;
122.51 +import org.netbeans.modules.csl.api.PreviewableFix;
122.52 +import org.netbeans.modules.csl.api.RuleContext;
122.53 +import org.netbeans.modules.python.source.PythonAstUtils;
122.54 +import org.netbeans.modules.python.source.PythonParserResult;
122.55 +import org.netbeans.modules.python.source.PythonUtils;
122.56 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
122.57 +import org.openide.util.NbBundle;
122.58 +import org.python.antlr.PythonTree;
122.59 +import org.python.antlr.ast.ClassDef;
122.60 +import org.python.antlr.ast.FunctionDef;
122.61 +import org.python.antlr.ast.Module;
122.62 +import org.python.antlr.ast.arguments;
122.63 +
122.64 +import static org.netbeans.modules.python.source.NameStyle.*;
122.65 +
122.66 +/**
122.67 + * Check names to see if they conform to standard Python conventions.
122.68 + * These are documented here:
122.69 + * http://www.python.org/dev/peps/pep-0008/
122.70 + *
122.71 + * @todo Add fix to rename!
122.72 + * @todo Implement variable name checking!
122.73 + *
122.74 + *
122.75 + * @author Tor Norbye
122.76 + */
122.77 +public class NameRule extends PythonAstRule {
122.78 + private static final String CLASS_STYLE_NAME = "classStyle"; // NOI18N
122.79 + private static final String IGNORED_NAMES = "ignoredNames"; // NOI18N
122.80 + private static final String MODULE_STYLE_NAME = "moduleStyle"; // NOI18N
122.81 + private static final String FUNCTION_STYLE_NAME = "functionStyle"; // NOI18N
122.82 + private static final String SELF_REQUIRED_NAME = "selfRequired"; // NOI18N
122.83 + private static final String VARIABLE_STYLE_NAME = "variableStyle"; // NOI18N
122.84 + private static NameStyle moduleStyle;
122.85 + private static NameStyle functionStyle;
122.86 + private static NameStyle classStyle;
122.87 + private static NameStyle variableStyle;
122.88 + private static String ignoredNames;
122.89 + private static boolean selfRequired;
122.90 +
122.91 + public NameRule() {
122.92 + }
122.93 +
122.94 + @Override
122.95 + public boolean appliesTo(RuleContext context) {
122.96 + moduleStyle = null; // Ensure lazy init
122.97 +
122.98 + return true;
122.99 + }
122.100 +
122.101 + private static void initializeFromPrefs(PythonRuleContext context, NameRule rule) {
122.102 + Preferences pref = context.manager.getPreferences(rule);
122.103 + moduleStyle = getModuleNameStyle(pref);
122.104 + classStyle = getClassNameStyle(pref);
122.105 + functionStyle = getFunctionNameStyle(pref);
122.106 + variableStyle = getVariableNameStyle(pref);
122.107 + ignoredNames = getIgnoredNames(pref);
122.108 + selfRequired = isSelfRequired(pref);
122.109 + }
122.110 +
122.111 + @Override
122.112 + public Set<Class> getKinds() {
122.113 + Set<Class> classes = new HashSet<>();
122.114 + classes.add(Module.class);
122.115 + classes.add(FunctionDef.class);
122.116 + classes.add(ClassDef.class);
122.117 +
122.118 + return classes;
122.119 + }
122.120 +
122.121 + @Override
122.122 + public void run(PythonRuleContext context, List<Hint> result) {
122.123 + if (moduleStyle == null) {
122.124 + initializeFromPrefs(context, this);
122.125 + }
122.126 +
122.127 + // TODO - check module name!!
122.128 +
122.129 + PythonTree node = context.node;
122.130 + if (node instanceof Module) {
122.131 + if (moduleStyle != NO_PREFERENCE) {
122.132 + String moduleName = PythonUtils.getModuleName(context.parserResult.getSnapshot().getSource().getFileObject());
122.133 + if (!moduleStyle.complies(moduleName) && !moduleStyle.complies(moduleName.substring(moduleName.lastIndexOf('.') + 1))) {
122.134 + String typeKey = "Module"; // NOI18N
122.135 + String message = NbBundle.getMessage(NameRule.class, "WrongStyle", moduleName,
122.136 + NbBundle.getMessage(NameRule.class, typeKey),
122.137 + moduleStyle.getDisplayName());
122.138 + List<HintFix> hintFixes = getNameStyleFixes(moduleName, context, moduleStyle, MODULE_STYLE_NAME, typeKey);
122.139 + addError(moduleName, context, message, node, result, hintFixes);
122.140 + }
122.141 + }
122.142 + } else if (node instanceof FunctionDef) {
122.143 + FunctionDef def = (FunctionDef)node;
122.144 + if (functionStyle != NO_PREFERENCE) {
122.145 + if (!functionStyle.complies(def.getInternalName())) {
122.146 + String typeKey = "Function"; // NOI18N
122.147 + String message = NbBundle.getMessage(NameRule.class, "WrongStyle", def.getInternalName(),
122.148 + NbBundle.getMessage(NameRule.class, typeKey),
122.149 + functionStyle.getDisplayName());
122.150 + List<HintFix> hintFixes = getNameStyleFixes(def.getInternalName(), context, functionStyle, FUNCTION_STYLE_NAME, typeKey);
122.151 + addError(def.getInternalName(), context, message, def, result, hintFixes);
122.152 + }
122.153 + }
122.154 +
122.155 + // Functions should have a first argument of name "self"
122.156 + if (selfRequired && !PythonAstUtils.isStaticMethod(def)) {
122.157 + arguments args = def.getInternalArgs();
122.158 + if (args.getInternalArgs().size() > 0) {
122.159 + String name = PythonAstUtils.getName(args.getInternalArgs().get(0));
122.160 + if (!("self".equals(name) || "cls".equals(name))) { // NOI18N
122.161 + // Make sure it's a class; other methods don't have to
122.162 + if (PythonAstUtils.isClassMethod(context.path, def)) {
122.163 + String message = NbBundle.getMessage(NameRule.class,
122.164 + // TODO - determine if it should be cls or def
122.165 + "NameRuleWrongArg", // NOI18N
122.166 + name);
122.167 + List<HintFix> fixList = new ArrayList<>(2);
122.168 + fixList.add(new SelfParamFix(context, true, def, null));
122.169 + List<String> parameters = PythonAstUtils.getParameters(def);
122.170 + if (parameters.size() > 0) {
122.171 + fixList.add(new SelfParamFix(context, false, def, parameters.get(0)));
122.172 + }
122.173 + addError(null, context, message, args, result, fixList);
122.174 + }
122.175 + }
122.176 + } else if (PythonAstUtils.isClassMethod(context.path, def)) {
122.177 + String message = NbBundle.getMessage(NameRule.class,
122.178 + // TODO - determine if it should be cls or def
122.179 + "NameRuleWrongNoArg"); // NOI18N
122.180 + List<HintFix> fixList = Collections.<HintFix>singletonList(new SelfParamFix(context, true, def, null));
122.181 + addError(null, context, message, args, result, fixList);
122.182 + }
122.183 + }
122.184 + } else if (node instanceof ClassDef) {
122.185 + if (functionStyle != NO_PREFERENCE) {
122.186 + ClassDef def = (ClassDef)node;
122.187 + if (!classStyle.complies(def.getInternalName())) {
122.188 + String typeKey = "Class"; // NOI18N
122.189 + String message = NbBundle.getMessage(NameRule.class, "WrongStyle", def.getInternalName(),
122.190 + NbBundle.getMessage(NameRule.class, typeKey),
122.191 + classStyle.getDisplayName());
122.192 + List<HintFix> hintFixes = getNameStyleFixes(def.getInternalName(), context, classStyle, CLASS_STYLE_NAME, typeKey);
122.193 + addError(def.getInternalName(), context, message, def, result, hintFixes);
122.194 + }
122.195 + }
122.196 + }
122.197 + }
122.198 +
122.199 + private List<HintFix> getNameStyleFixes(String name, PythonRuleContext context, NameStyle currentStyle, String key, String type) {
122.200 + List<HintFix> fixes = new ArrayList<>(5);
122.201 +
122.202 + fixes.add(new IgnoreWordFix(name, this, context));
122.203 +
122.204 + for (NameStyle style : NameStyle.values()) {
122.205 + if (style == currentStyle || style == NO_PREFERENCE) {
122.206 + continue;
122.207 + }
122.208 +
122.209 + if (style.complies(name)) {
122.210 + ChangeStyleFix cs = new ChangeStyleFix(this, context, style, key, type);
122.211 + fixes.add(cs);
122.212 + }
122.213 + }
122.214 +
122.215 + // No preference always last
122.216 + fixes.add(new ChangeStyleFix(this, context, NO_PREFERENCE, key, type));
122.217 +
122.218 + return fixes;
122.219 + }
122.220 +
122.221 + private void addError(String name, PythonRuleContext context, String message, PythonTree node, List<Hint> result, List<HintFix> fixList) {
122.222 + if (name != null && ignoredNames.length() > 0) {
122.223 + for (String ignoredName : ignoredNames.split(",")) { // NOI18N
122.224 + ignoredName = ignoredName.trim();
122.225 + if (name.equals(ignoredName)) {
122.226 + return;
122.227 + }
122.228 + }
122.229 + }
122.230 +
122.231 + PythonParserResult info = (PythonParserResult)context.parserResult;
122.232 + OffsetRange range;
122.233 + if (node instanceof Module) {
122.234 + range = new OffsetRange(0, 0);
122.235 + } else {
122.236 +
122.237 + range = PythonAstUtils.getNameRange(info, node);
122.238 + }
122.239 + range = PythonLexerUtils.getLexerOffsets(info, range);
122.240 + if (range != OffsetRange.NONE) {
122.241 + if (fixList == null) {
122.242 + fixList = Collections.emptyList();
122.243 + }
122.244 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 1500);
122.245 + result.add(desc);
122.246 + }
122.247 + }
122.248 +
122.249 + @Override
122.250 + public String getId() {
122.251 + return "NameRule"; // NOI18N
122.252 + }
122.253 +
122.254 + @Override
122.255 + public String getDisplayName() {
122.256 + return NbBundle.getMessage(NameRule.class, "NameRule");
122.257 + }
122.258 +
122.259 + @Override
122.260 + public String getDescription() {
122.261 + return NbBundle.getMessage(NameRule.class, "NameRuleDesc");
122.262 + }
122.263 +
122.264 + @Override
122.265 + public boolean getDefaultEnabled() {
122.266 + return true;
122.267 + }
122.268 +
122.269 + @Override
122.270 + public boolean showInTasklist() {
122.271 + return true;
122.272 + }
122.273 +
122.274 + @Override
122.275 + public HintSeverity getDefaultSeverity() {
122.276 + return HintSeverity.WARNING;
122.277 + }
122.278 +
122.279 + @Override
122.280 + public JComponent getCustomizer(Preferences node) {
122.281 + moduleStyle = null; // Ensure lazy init after this
122.282 + return new NameRulePrefs(this, node);
122.283 + }
122.284 +
122.285 + static NameStyle getNameStyle(String key, NameStyle deflt, Preferences pref) {
122.286 + String value = pref.get(key, deflt.name());
122.287 +
122.288 + return NameStyle.valueOf(value);
122.289 + }
122.290 +
122.291 + static NameStyle getModuleNameStyle(Preferences pref) {
122.292 + return getNameStyle(MODULE_STYLE_NAME, NameStyle.NO_PREFERENCE, pref);
122.293 + }
122.294 +
122.295 + static NameStyle getClassNameStyle(Preferences pref) {
122.296 + return getNameStyle(CLASS_STYLE_NAME, NameStyle.CAPITALIZED_WORDS, pref);
122.297 + }
122.298 +
122.299 + static NameStyle getVariableNameStyle(Preferences pref) {
122.300 + return getNameStyle(VARIABLE_STYLE_NAME, NameStyle.LOWERCASE_WITH_UNDERSCORES, pref);
122.301 + }
122.302 +
122.303 + static NameStyle getFunctionNameStyle(Preferences pref) {
122.304 + return getNameStyle(FUNCTION_STYLE_NAME, NameStyle.LOWERCASE_WITH_UNDERSCORES, pref);
122.305 + }
122.306 +
122.307 + static boolean isSelfRequired(Preferences pref) {
122.308 + return pref.getBoolean(SELF_REQUIRED_NAME, true);
122.309 + }
122.310 +
122.311 + static String getIgnoredNames(Preferences pref) {
122.312 + return pref.get(IGNORED_NAMES, "");
122.313 + }
122.314 +
122.315 + void setModuleNameStyle(Preferences pref, NameStyle style) {
122.316 + pref.put(MODULE_STYLE_NAME, style.name());
122.317 + }
122.318 +
122.319 + void setClassNameStyle(Preferences pref, NameStyle style) {
122.320 + pref.put(CLASS_STYLE_NAME, style.name());
122.321 + }
122.322 +
122.323 + void setFunctionNameStyle(Preferences pref, NameStyle style) {
122.324 + pref.put(FUNCTION_STYLE_NAME, style.name());
122.325 + }
122.326 +
122.327 + void setVariableNameStyle(Preferences pref, NameStyle style) {
122.328 + pref.put(VARIABLE_STYLE_NAME, style.name());
122.329 + }
122.330 +
122.331 + void setIgnoredNames(Preferences pref, String ignoredNames) {
122.332 + pref.put(IGNORED_NAMES, ignoredNames);
122.333 + }
122.334 +
122.335 + void setSelfRequired(Preferences pref, boolean requireSelf) {
122.336 + pref.putBoolean(SELF_REQUIRED_NAME, requireSelf);
122.337 + }
122.338 +
122.339 + private static class IgnoreWordFix implements HintFix {
122.340 + private String name;
122.341 + private NameRule rule;
122.342 + private PythonRuleContext context;
122.343 +
122.344 + public IgnoreWordFix(String name, NameRule rule, PythonRuleContext context) {
122.345 + this.name = name;
122.346 + this.rule = rule;
122.347 + this.context = context;
122.348 + }
122.349 +
122.350 + @Override
122.351 + public String getDescription() {
122.352 + return NbBundle.getMessage(NameRule.class, "IgnoreWord", name);
122.353 + }
122.354 +
122.355 + @Override
122.356 + public void implement() throws Exception {
122.357 + Preferences pref = context.manager.getPreferences(rule);
122.358 + String ignored = getIgnoredNames(pref);
122.359 + if (ignored.length() > 0) {
122.360 + ignored = ignored + "," + name; // NOI18N
122.361 + } else {
122.362 + ignored = name;
122.363 + }
122.364 + pref.put(IGNORED_NAMES, ignored);
122.365 +
122.366 + context.manager.refreshHints(context);
122.367 + }
122.368 +
122.369 + @Override
122.370 + public boolean isSafe() {
122.371 + return true;
122.372 + }
122.373 +
122.374 + @Override
122.375 + public boolean isInteractive() {
122.376 + return true;
122.377 + }
122.378 + }
122.379 +
122.380 + private static class ChangeStyleFix implements HintFix {
122.381 + private NameRule rule;
122.382 + private PythonRuleContext context;
122.383 + private NameStyle style;
122.384 + private String key;
122.385 + private String typeKey;
122.386 +
122.387 + public ChangeStyleFix(NameRule rule, PythonRuleContext context, NameStyle style, String key, String type) {
122.388 + this.rule = rule;
122.389 + this.context = context;
122.390 + this.style = style;
122.391 + this.key = key;
122.392 + this.typeKey = type;
122.393 + }
122.394 +
122.395 + @Override
122.396 + public String getDescription() {
122.397 + if (style == NO_PREFERENCE) {
122.398 + return NbBundle.getMessage(NameRule.class, "ChangeNoStyle", NbBundle.getMessage(NameRule.class, typeKey));
122.399 + } else {
122.400 + return NbBundle.getMessage(NameRule.class, "ChangeStyle", NbBundle.getMessage(NameRule.class, typeKey), style.getDisplayName());
122.401 + }
122.402 + }
122.403 +
122.404 + @Override
122.405 + public void implement() throws Exception {
122.406 + Preferences pref = context.manager.getPreferences(rule);
122.407 + pref.put(key, style.name());
122.408 +
122.409 + context.manager.refreshHints(context);
122.410 + }
122.411 +
122.412 + @Override
122.413 + public boolean isSafe() {
122.414 + return true;
122.415 + }
122.416 +
122.417 + @Override
122.418 + public boolean isInteractive() {
122.419 + return true;
122.420 + }
122.421 + }
122.422 +
122.423 + /**
122.424 + * Fix to insert self argument or rename first argument to self
122.425 + */
122.426 + private static class SelfParamFix implements PreviewableFix {
122.427 + private final PythonRuleContext context;
122.428 + private final FunctionDef func;
122.429 + private final boolean insert;
122.430 + private final String first;
122.431 +
122.432 + private SelfParamFix(PythonRuleContext context, boolean insert, FunctionDef func, String first) {
122.433 + this.context = context;
122.434 + this.insert = insert;
122.435 + this.func = func;
122.436 + this.first = first;
122.437 +
122.438 + assert insert || first != null;
122.439 + }
122.440 +
122.441 + @Override
122.442 + public String getDescription() {
122.443 + if (insert) {
122.444 + return NbBundle.getMessage(CreateDocString.class, "InsertSelf");
122.445 + } else {
122.446 + return NbBundle.getMessage(CreateDocString.class, "RenameSelf", first);
122.447 + }
122.448 + }
122.449 +
122.450 + @Override
122.451 + public boolean canPreview() {
122.452 + return true;
122.453 + }
122.454 +
122.455 + @Override
122.456 + public EditList getEditList() throws Exception {
122.457 + return getEditList(true);
122.458 + }
122.459 +
122.460 + private EditList getEditList(boolean previewOnly) throws Exception {
122.461 + BaseDocument doc = context.doc;
122.462 + EditList edits = new EditList(doc);
122.463 +
122.464 + OffsetRange astRange = PythonAstUtils.getNameRange((PythonParserResult) context.parserResult, func);
122.465 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
122.466 + if (lexRange == OffsetRange.NONE) {
122.467 + return edits;
122.468 + }
122.469 + int paramStart = lexRange.getEnd();
122.470 + if (insert) {
122.471 + String missing;
122.472 + int lineEnd = Utilities.getRowEnd(doc, paramStart);
122.473 + int offset = paramStart;
122.474 + if (lineEnd > paramStart) {
122.475 + String line = doc.getText(paramStart, lineEnd - paramStart);
122.476 + int paren = line.indexOf('(');
122.477 + int colon = line.indexOf(':');
122.478 + if (paren != -1) {
122.479 + offset = paramStart + paren + 1;
122.480 + missing = "self"; // NOI18N
122.481 + List<String> parameters = PythonAstUtils.getParameters(func);
122.482 + if (parameters.size() > 0) {
122.483 + missing = "self, "; // NOI18N
122.484 + } else {
122.485 + missing = "self"; // NOI18N
122.486 + }
122.487 + } else if (colon != -1) {
122.488 + offset = paramStart + colon;
122.489 + missing = "(self)"; // NOI18N
122.490 + } else {
122.491 + return edits;
122.492 + }
122.493 + } else {
122.494 + missing = "(self)"; // NOI18N
122.495 + }
122.496 + edits.replace(offset, 0, missing, false, 0);
122.497 + } else {
122.498 + String text = doc.getText(paramStart, doc.getLength() - paramStart);
122.499 + int offset = text.indexOf(first);
122.500 + if (offset != -1) {
122.501 + offset += paramStart;
122.502 + edits.replace(offset, first.length(), "self", false, 0); // NOI18N
122.503 + }
122.504 + }
122.505 +
122.506 +
122.507 + return edits;
122.508 + }
122.509 +
122.510 + @Override
122.511 + public void implement() throws Exception {
122.512 + EditList edits = getEditList(true);
122.513 +
122.514 + edits.apply();
122.515 + }
122.516 +
122.517 + @Override
122.518 + public boolean isSafe() {
122.519 + return true;
122.520 + }
122.521 +
122.522 + @Override
122.523 + public boolean isInteractive() {
122.524 + return false;
122.525 + }
122.526 + }
122.527 +}
123.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/NameRulePrefs.form Wed Sep 02 20:31:18 2015 +0200
123.3 @@ -0,0 +1,182 @@
123.4 +<?xml version="1.0" encoding="UTF-8" ?>
123.5 +
123.6 +<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
123.7 + <AuxValues>
123.8 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
123.9 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
123.10 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
123.11 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
123.12 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
123.13 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
123.14 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
123.15 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
123.16 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
123.17 + </AuxValues>
123.18 +
123.19 + <Layout>
123.20 + <DimensionLayout dim="0">
123.21 + <Group type="103" groupAlignment="0" attributes="0">
123.22 + <Group type="102" attributes="0">
123.23 + <Group type="103" groupAlignment="0" attributes="0">
123.24 + <Group type="102" alignment="0" attributes="0">
123.25 + <Group type="103" groupAlignment="0" attributes="0">
123.26 + <Component id="moduleLabel" alignment="0" min="-2" max="-2" attributes="0"/>
123.27 + <Component id="classLabel" alignment="0" min="-2" max="-2" attributes="0"/>
123.28 + <Component id="functionLabel" alignment="0" min="-2" max="-2" attributes="0"/>
123.29 + <Component id="variableLabel" alignment="0" min="-2" max="-2" attributes="0"/>
123.30 + </Group>
123.31 + <EmptySpace max="-2" attributes="0"/>
123.32 + <Group type="103" groupAlignment="1" max="-2" attributes="0">
123.33 + <Component id="variableCombo" alignment="0" max="32767" attributes="1"/>
123.34 + <Component id="classCombo" alignment="0" max="32767" attributes="1"/>
123.35 + <Component id="moduleCombo" alignment="0" pref="234" max="32767" attributes="1"/>
123.36 + <Component id="functionCombo" alignment="1" max="32767" attributes="1"/>
123.37 + </Group>
123.38 + </Group>
123.39 + <Component id="parameterLabel" alignment="0" min="-2" max="-2" attributes="0"/>
123.40 + <Component id="selfCb" alignment="0" min="-2" max="-2" attributes="0"/>
123.41 + <Group type="102" alignment="0" attributes="0">
123.42 + <Component id="ignoreLabel" min="-2" max="-2" attributes="0"/>
123.43 + <EmptySpace max="-2" attributes="0"/>
123.44 + <Component id="ignoredText" max="32767" attributes="0"/>
123.45 + </Group>
123.46 + </Group>
123.47 + <EmptySpace max="-2" attributes="0"/>
123.48 + </Group>
123.49 + </Group>
123.50 + </DimensionLayout>
123.51 + <DimensionLayout dim="1">
123.52 + <Group type="103" groupAlignment="0" attributes="0">
123.53 + <Group type="102" alignment="0" attributes="0">
123.54 + <Group type="103" groupAlignment="3" attributes="0">
123.55 + <Component id="moduleLabel" alignment="3" min="-2" max="-2" attributes="0"/>
123.56 + <Component id="moduleCombo" alignment="3" min="-2" max="-2" attributes="0"/>
123.57 + </Group>
123.58 + <EmptySpace max="-2" attributes="0"/>
123.59 + <Group type="103" groupAlignment="3" attributes="0">
123.60 + <Component id="classLabel" alignment="3" min="-2" max="-2" attributes="0"/>
123.61 + <Component id="classCombo" alignment="3" min="-2" max="-2" attributes="0"/>
123.62 + </Group>
123.63 + <EmptySpace max="-2" attributes="0"/>
123.64 + <Group type="103" groupAlignment="3" attributes="0">
123.65 + <Component id="functionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
123.66 + <Component id="functionCombo" alignment="3" min="-2" max="-2" attributes="0"/>
123.67 + </Group>
123.68 + <EmptySpace max="-2" attributes="0"/>
123.69 + <Group type="103" groupAlignment="3" attributes="0">
123.70 + <Component id="variableLabel" alignment="3" min="-2" max="-2" attributes="0"/>
123.71 + <Component id="variableCombo" alignment="3" min="-2" max="-2" attributes="0"/>
123.72 + </Group>
123.73 + <EmptySpace type="separate" max="-2" attributes="0"/>
123.74 + <Component id="parameterLabel" min="-2" max="-2" attributes="0"/>
123.75 + <EmptySpace max="-2" attributes="0"/>
123.76 + <Component id="selfCb" min="-2" max="-2" attributes="0"/>
123.77 + <EmptySpace type="separate" max="-2" attributes="0"/>
123.78 + <Group type="103" groupAlignment="3" attributes="0">
123.79 + <Component id="ignoreLabel" alignment="3" min="-2" max="-2" attributes="0"/>
123.80 + <Component id="ignoredText" alignment="3" min="-2" max="-2" attributes="0"/>
123.81 + </Group>
123.82 + <EmptySpace max="32767" attributes="0"/>
123.83 + </Group>
123.84 + </Group>
123.85 + </DimensionLayout>
123.86 + </Layout>
123.87 + <SubComponents>
123.88 + <Component class="javax.swing.JLabel" name="classLabel">
123.89 + <Properties>
123.90 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.91 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.classLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.92 + </Property>
123.93 + </Properties>
123.94 + </Component>
123.95 + <Component class="javax.swing.JLabel" name="functionLabel">
123.96 + <Properties>
123.97 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.98 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.functionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.99 + </Property>
123.100 + </Properties>
123.101 + </Component>
123.102 + <Component class="javax.swing.JLabel" name="moduleLabel">
123.103 + <Properties>
123.104 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.105 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.moduleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.106 + </Property>
123.107 + </Properties>
123.108 + </Component>
123.109 + <Component class="javax.swing.JLabel" name="parameterLabel">
123.110 + <Properties>
123.111 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.112 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.parameterLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.113 + </Property>
123.114 + </Properties>
123.115 + </Component>
123.116 + <Component class="javax.swing.JCheckBox" name="selfCb">
123.117 + <Properties>
123.118 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.119 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.selfCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.120 + </Property>
123.121 + </Properties>
123.122 + <Events>
123.123 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
123.124 + </Events>
123.125 + </Component>
123.126 + <Component class="javax.swing.JComboBox" name="moduleCombo">
123.127 + <Properties>
123.128 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
123.129 + <Connection code="getNameStyleModel()" type="code"/>
123.130 + </Property>
123.131 + </Properties>
123.132 + <Events>
123.133 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
123.134 + </Events>
123.135 + </Component>
123.136 + <Component class="javax.swing.JComboBox" name="classCombo">
123.137 + <Properties>
123.138 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
123.139 + <Connection code="getNameStyleModel()" type="code"/>
123.140 + </Property>
123.141 + </Properties>
123.142 + <Events>
123.143 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
123.144 + </Events>
123.145 + </Component>
123.146 + <Component class="javax.swing.JComboBox" name="functionCombo">
123.147 + <Properties>
123.148 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
123.149 + <Connection code="getNameStyleModel()" type="code"/>
123.150 + </Property>
123.151 + </Properties>
123.152 + <Events>
123.153 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
123.154 + </Events>
123.155 + </Component>
123.156 + <Component class="javax.swing.JLabel" name="variableLabel">
123.157 + <Properties>
123.158 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.159 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.variableLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.160 + </Property>
123.161 + <Property name="enabled" type="boolean" value="false"/>
123.162 + </Properties>
123.163 + </Component>
123.164 + <Component class="javax.swing.JComboBox" name="variableCombo">
123.165 + <Properties>
123.166 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
123.167 + <Connection code="getNameStyleModel()" type="code"/>
123.168 + </Property>
123.169 + <Property name="enabled" type="boolean" value="false"/>
123.170 + </Properties>
123.171 + <Events>
123.172 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
123.173 + </Events>
123.174 + </Component>
123.175 + <Component class="javax.swing.JLabel" name="ignoreLabel">
123.176 + <Properties>
123.177 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
123.178 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="NameRulePrefs.ignoreLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
123.179 + </Property>
123.180 + </Properties>
123.181 + </Component>
123.182 + <Component class="javax.swing.JTextField" name="ignoredText">
123.183 + </Component>
123.184 + </SubComponents>
123.185 +</Form>
124.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
124.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/NameRulePrefs.java Wed Sep 02 20:31:18 2015 +0200
124.3 @@ -0,0 +1,292 @@
124.4 +/*
124.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
124.6 + *
124.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
124.8 + *
124.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
124.10 + * Other names may be trademarks of their respective owners.
124.11 + *
124.12 + * The contents of this file are subject to the terms of either the GNU
124.13 + * General Public License Version 2 only ("GPL") or the Common
124.14 + * Development and Distribution License("CDDL") (collectively, the
124.15 + * "License"). You may not use this file except in compliance with the
124.16 + * License. You can obtain a copy of the License at
124.17 + * http://www.netbeans.org/cddl-gplv2.html
124.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
124.19 + * specific language governing permissions and limitations under the
124.20 + * License. When distributing the software, include this License Header
124.21 + * Notice in each file and include the License file at
124.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
124.23 + * particular file as subject to the "Classpath" exception as provided
124.24 + * by Oracle in the GPL Version 2 section of the License file that
124.25 + * accompanied this code. If applicable, add the following below the
124.26 + * License Header, with the fields enclosed by brackets [] replaced by
124.27 + * your own identifying information:
124.28 + * "Portions Copyrighted [year] [name of copyright owner]"
124.29 + *
124.30 + * If you wish your version of this file to be governed by only the CDDL
124.31 + * or only the GPL Version 2, indicate your decision by adding
124.32 + * "[Contributor] elects to include this software in this distribution
124.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
124.34 + * single choice of license, a recipient has the option to distribute
124.35 + * your version of this file under either the CDDL, the GPL Version 2 or
124.36 + * to extend the choice of license to its licensees as provided above.
124.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
124.38 + * Version 2 license, then the option applies only if the new code is
124.39 + * made subject to such option by the copyright holder.
124.40 + *
124.41 + * Contributor(s):
124.42 + *
124.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
124.44 + */
124.45 +package org.netbeans.modules.python.hints;
124.46 +
124.47 +import org.netbeans.modules.python.source.NameStyle;
124.48 +import java.awt.Component;
124.49 +import java.util.prefs.Preferences;
124.50 +import javax.swing.ComboBoxModel;
124.51 +import javax.swing.DefaultComboBoxModel;
124.52 +import javax.swing.JLabel;
124.53 +import javax.swing.JList;
124.54 +import javax.swing.ListCellRenderer;
124.55 +
124.56 +/**
124.57 + *
124.58 + * @author Tor Norbye
124.59 + */
124.60 +public class NameRulePrefs extends javax.swing.JPanel {
124.61 + private NameRule rule;
124.62 + private Preferences prefs;
124.63 +
124.64 + /** Creates new form NameRulePrefs */
124.65 + public NameRulePrefs(NameRule rule, Preferences prefs) {
124.66 + this.rule = rule;
124.67 + this.prefs = prefs;
124.68 +
124.69 + initComponents();
124.70 +
124.71 + ListCellRenderer renderer = new NameStyleRenderer();
124.72 + moduleCombo.setRenderer(renderer);
124.73 + functionCombo.setRenderer(renderer);
124.74 + classCombo.setRenderer(renderer);
124.75 + variableCombo.setRenderer(renderer);
124.76 +
124.77 + moduleCombo.setSelectedItem(NameRule.getModuleNameStyle(prefs));
124.78 + functionCombo.setSelectedItem(NameRule.getFunctionNameStyle(prefs));
124.79 + classCombo.setSelectedItem(NameRule.getClassNameStyle(prefs));
124.80 + variableCombo.setSelectedItem(NameRule.getVariableNameStyle(prefs));
124.81 +
124.82 + selfCb.setSelected(NameRule.isSelfRequired(prefs));
124.83 + ignoredText.setText(NameRule.getIgnoredNames(prefs));
124.84 + }
124.85 +
124.86 + private ComboBoxModel getNameStyleModel() {
124.87 + return new DefaultComboBoxModel(NameStyle.values());
124.88 + }
124.89 +
124.90 + private static class NameStyleRenderer extends JLabel implements ListCellRenderer/*, UIResource*/ {
124.91 + public NameStyleRenderer() {
124.92 + setOpaque(true);
124.93 + }
124.94 +
124.95 + @Override
124.96 + public Component getListCellRendererComponent(JList list, Object value,
124.97 + int index, boolean isSelected, boolean cellHasFocus) {
124.98 + // #93658: GTK needs name to render cell renderer "natively"
124.99 + setName("ComboBox.listRenderer"); // NOI18N
124.100 +
124.101 + if (isSelected) {
124.102 + setBackground(list.getSelectionBackground());
124.103 + setForeground(list.getSelectionForeground());
124.104 + } else {
124.105 + setBackground(list.getBackground());
124.106 + setForeground(list.getForeground());
124.107 + }
124.108 +
124.109 + if (value instanceof NameStyle) {
124.110 + setText(((NameStyle)value).getDisplayName());
124.111 + }
124.112 +
124.113 + return this;
124.114 + }
124.115 +
124.116 + // #93658: GTK needs name to render cell renderer "natively"
124.117 + public
124.118 + @Override
124.119 + String getName() {
124.120 + String name = super.getName();
124.121 + return name == null ? "ComboBox.renderer" : name; // NOI18N
124.122 + }
124.123 + }
124.124 +
124.125 + /** This method is called from within the constructor to
124.126 + * initialize the form.
124.127 + * WARNING: Do NOT modify this code. The content of this method is
124.128 + * always regenerated by the Form Editor.
124.129 + */
124.130 + @SuppressWarnings("unchecked")
124.131 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
124.132 + private void initComponents() {
124.133 +
124.134 + classLabel = new javax.swing.JLabel();
124.135 + functionLabel = new javax.swing.JLabel();
124.136 + moduleLabel = new javax.swing.JLabel();
124.137 + parameterLabel = new javax.swing.JLabel();
124.138 + selfCb = new javax.swing.JCheckBox();
124.139 + moduleCombo = new javax.swing.JComboBox();
124.140 + classCombo = new javax.swing.JComboBox();
124.141 + functionCombo = new javax.swing.JComboBox();
124.142 + variableLabel = new javax.swing.JLabel();
124.143 + variableCombo = new javax.swing.JComboBox();
124.144 + ignoreLabel = new javax.swing.JLabel();
124.145 + ignoredText = new javax.swing.JTextField();
124.146 +
124.147 + classLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.classLabel.text")); // NOI18N
124.148 +
124.149 + functionLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.functionLabel.text")); // NOI18N
124.150 +
124.151 + moduleLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.moduleLabel.text")); // NOI18N
124.152 +
124.153 + parameterLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.parameterLabel.text")); // NOI18N
124.154 +
124.155 + selfCb.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.selfCb.text")); // NOI18N
124.156 + selfCb.addActionListener(new java.awt.event.ActionListener() {
124.157 + public void actionPerformed(java.awt.event.ActionEvent evt) {
124.158 + changed(evt);
124.159 + }
124.160 + });
124.161 +
124.162 + moduleCombo.setModel(getNameStyleModel());
124.163 + moduleCombo.addActionListener(new java.awt.event.ActionListener() {
124.164 + public void actionPerformed(java.awt.event.ActionEvent evt) {
124.165 + changed(evt);
124.166 + }
124.167 + });
124.168 +
124.169 + classCombo.setModel(getNameStyleModel());
124.170 + classCombo.addActionListener(new java.awt.event.ActionListener() {
124.171 + public void actionPerformed(java.awt.event.ActionEvent evt) {
124.172 + changed(evt);
124.173 + }
124.174 + });
124.175 +
124.176 + functionCombo.setModel(getNameStyleModel());
124.177 + functionCombo.addActionListener(new java.awt.event.ActionListener() {
124.178 + public void actionPerformed(java.awt.event.ActionEvent evt) {
124.179 + changed(evt);
124.180 + }
124.181 + });
124.182 +
124.183 + variableLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.variableLabel.text")); // NOI18N
124.184 + variableLabel.setEnabled(false);
124.185 +
124.186 + variableCombo.setModel(getNameStyleModel());
124.187 + variableCombo.setEnabled(false);
124.188 + variableCombo.addActionListener(new java.awt.event.ActionListener() {
124.189 + public void actionPerformed(java.awt.event.ActionEvent evt) {
124.190 + changed(evt);
124.191 + }
124.192 + });
124.193 +
124.194 + ignoreLabel.setText(org.openide.util.NbBundle.getMessage(NameRulePrefs.class, "NameRulePrefs.ignoreLabel.text")); // NOI18N
124.195 +
124.196 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
124.197 + this.setLayout(layout);
124.198 + layout.setHorizontalGroup(
124.199 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
124.200 + .addGroup(layout.createSequentialGroup()
124.201 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
124.202 + .addGroup(layout.createSequentialGroup()
124.203 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
124.204 + .addComponent(moduleLabel)
124.205 + .addComponent(classLabel)
124.206 + .addComponent(functionLabel)
124.207 + .addComponent(variableLabel))
124.208 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
124.209 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
124.210 + .addComponent(variableCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
124.211 + .addComponent(classCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
124.212 + .addComponent(moduleCombo, javax.swing.GroupLayout.Alignment.LEADING, 0, 234, Short.MAX_VALUE)
124.213 + .addComponent(functionCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
124.214 + .addComponent(parameterLabel)
124.215 + .addComponent(selfCb)
124.216 + .addGroup(layout.createSequentialGroup()
124.217 + .addComponent(ignoreLabel)
124.218 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
124.219 + .addComponent(ignoredText)))
124.220 + .addContainerGap())
124.221 + );
124.222 + layout.setVerticalGroup(
124.223 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
124.224 + .addGroup(layout.createSequentialGroup()
124.225 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
124.226 + .addComponent(moduleLabel)
124.227 + .addComponent(moduleCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
124.228 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
124.229 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
124.230 + .addComponent(classLabel)
124.231 + .addComponent(classCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
124.232 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
124.233 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
124.234 + .addComponent(functionLabel)
124.235 + .addComponent(functionCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
124.236 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
124.237 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
124.238 + .addComponent(variableLabel)
124.239 + .addComponent(variableCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
124.240 + .addGap(18, 18, 18)
124.241 + .addComponent(parameterLabel)
124.242 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
124.243 + .addComponent(selfCb)
124.244 + .addGap(18, 18, 18)
124.245 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
124.246 + .addComponent(ignoreLabel)
124.247 + .addComponent(ignoredText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
124.248 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
124.249 + );
124.250 + }// </editor-fold>//GEN-END:initComponents
124.251 +
124.252 + private void changed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changed
124.253 + Object source = evt.getSource();
124.254 +
124.255 + if (source == moduleCombo) {
124.256 + NameStyle style = (NameStyle)moduleCombo.getSelectedItem();
124.257 + if (style != null) {
124.258 + rule.setModuleNameStyle(prefs, style);
124.259 + }
124.260 + } else if (source == functionCombo) {
124.261 + NameStyle style = (NameStyle)functionCombo.getSelectedItem();
124.262 + if (style != null) {
124.263 + rule.setFunctionNameStyle(prefs, style);
124.264 + }
124.265 + } else if (source == classCombo) {
124.266 + NameStyle style = (NameStyle)classCombo.getSelectedItem();
124.267 + if (style != null) {
124.268 + rule.setClassNameStyle(prefs, style);
124.269 + }
124.270 + } else if (source == variableCombo) {
124.271 + NameStyle style = (NameStyle)variableCombo.getSelectedItem();
124.272 + if (style != null) {
124.273 + rule.setVariableNameStyle(prefs, style);
124.274 + }
124.275 + } else if (source == ignoredText) {
124.276 + rule.setIgnoredNames(prefs, ignoredText.getText().trim());
124.277 + } else if (source == selfCb) {
124.278 + rule.setSelfRequired(prefs, selfCb.isSelected());
124.279 + }
124.280 + }//GEN-LAST:event_changed
124.281 + // Variables declaration - do not modify//GEN-BEGIN:variables
124.282 + private javax.swing.JComboBox classCombo;
124.283 + private javax.swing.JLabel classLabel;
124.284 + private javax.swing.JComboBox functionCombo;
124.285 + private javax.swing.JLabel functionLabel;
124.286 + private javax.swing.JLabel ignoreLabel;
124.287 + private javax.swing.JTextField ignoredText;
124.288 + private javax.swing.JComboBox moduleCombo;
124.289 + private javax.swing.JLabel moduleLabel;
124.290 + private javax.swing.JLabel parameterLabel;
124.291 + private javax.swing.JCheckBox selfCb;
124.292 + private javax.swing.JComboBox variableCombo;
124.293 + private javax.swing.JLabel variableLabel;
124.294 + // End of variables declaration//GEN-END:variables
124.295 +}
125.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonAstRule.java Wed Sep 02 20:31:18 2015 +0200
125.3 @@ -0,0 +1,51 @@
125.4 +/*
125.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
125.6 + *
125.7 + * Copyright 1997-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 + * Contributor(s):
125.31 + *
125.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
125.33 + */
125.34 +package org.netbeans.modules.python.hints;
125.35 +
125.36 +import java.util.List;
125.37 +import java.util.Set;
125.38 +import org.netbeans.modules.csl.api.Hint;
125.39 +import org.netbeans.modules.csl.api.Rule.AstRule;
125.40 +
125.41 +public abstract class PythonAstRule implements AstRule {
125.42 + /**
125.43 + * Get the ElementKinds this rule should run on.
125.44 + * The integers should correspond to values in {@link org.mozilla.javascript.Token}
125.45 + */
125.46 + @Override
125.47 + public abstract Set<Class> getKinds();
125.48 +
125.49 + /**
125.50 + * Run the test on given CompilationUnit and return list of Errors or
125.51 + * warrnings to be shown in the editor.
125.52 + */
125.53 + public abstract void run(PythonRuleContext context, List<Hint> result);
125.54 +}
126.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
126.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonHintOptions.java Wed Sep 02 20:31:18 2015 +0200
126.3 @@ -0,0 +1,71 @@
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 org.netbeans.modules.csl.api.HintsProvider;
126.37 +import org.netbeans.modules.csl.api.HintsProvider.HintsManager;
126.38 +import org.netbeans.modules.python.api.PythonMIMEResolver;
126.39 +import org.netbeans.spi.options.AdvancedOption;
126.40 +import org.netbeans.spi.options.OptionsPanelController;
126.41 +import org.openide.util.NbBundle;
126.42 +
126.43 +/**
126.44 + * Hint settings for Python
126.45 + */
126.46 +public class PythonHintOptions extends AdvancedOption {
126.47 + OptionsPanelController panelController;
126.48 +
126.49 + @Override
126.50 + public String getDisplayName() {
126.51 + return NbBundle.getMessage(PythonHintOptions.class, "CTL_Hints_DisplayName"); // NOI18N
126.52 + }
126.53 +
126.54 + @Override
126.55 + public String getTooltip() {
126.56 + return NbBundle.getMessage(PythonHintOptions.class, "CTL_Hints_ToolTip"); // NOI18N
126.57 + }
126.58 +
126.59 + @Override
126.60 + public synchronized OptionsPanelController create() {
126.61 + if (panelController == null) {
126.62 + HintsManager manager = HintsProvider.HintsManager.getManagerForMimeType(PythonMIMEResolver.PYTHON_MIME_TYPE);
126.63 + assert manager != null;
126.64 + panelController = manager.getOptionsController();
126.65 + }
126.66 +
126.67 + return panelController;
126.68 + }
126.69 +
126.70 + //TODO: temporary solution, this should be solved on GSF level
126.71 + public static OptionsPanelController createStatic() {
126.72 + return new PythonHintOptions().create();
126.73 + }
126.74 +}
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonHintsProvider.java Wed Sep 02 20:31:18 2015 +0200
127.3 @@ -0,0 +1,433 @@
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 java.util.Collections;
127.37 +import java.util.HashMap;
127.38 +import java.util.Iterator;
127.39 +import java.util.LinkedList;
127.40 +import java.util.List;
127.41 +import java.util.Map;
127.42 +import java.util.Map.Entry;
127.43 +import java.util.Set;
127.44 +import org.netbeans.modules.csl.api.Error;
127.45 +import org.netbeans.modules.csl.api.Hint;
127.46 +import org.netbeans.modules.csl.api.HintFix;
127.47 +import org.netbeans.modules.csl.api.HintSeverity;
127.48 +import org.netbeans.modules.csl.api.HintsProvider;
127.49 +import org.netbeans.modules.csl.api.HintsProvider.HintsManager;
127.50 +import org.netbeans.modules.csl.api.OffsetRange;
127.51 +import org.netbeans.modules.csl.api.Rule;
127.52 +import org.netbeans.modules.csl.api.RuleContext;
127.53 +import org.netbeans.modules.csl.spi.GsfUtilities;
127.54 +import org.netbeans.modules.csl.spi.ParserResult;
127.55 +import org.netbeans.modules.python.source.AstPath;
127.56 +import org.netbeans.modules.python.source.PythonAstUtils;
127.57 +import org.netbeans.modules.python.source.PythonParserResult;
127.58 +import org.openide.util.Exceptions;
127.59 +import org.python.antlr.PythonTree;
127.60 +import org.python.antlr.Visitor;
127.61 +
127.62 +/**
127.63 + *
127.64 + * @todo Write rules based on the PythonChecker ideas:
127.65 + * http://pychecker.sourceforge.net/
127.66 + * @todo Write rules based on the PyLint ideas:
127.67 + * http://www.logilab.org/projects/pylint
127.68 + * http://www.logilab.org/card/pylintfeatures
127.69 + *
127.70 + * @author Tor Norbye
127.71 + */
127.72 +public class PythonHintsProvider implements HintsProvider {
127.73 + private boolean cancelled;
127.74 +
127.75 + public PythonHintsProvider() {
127.76 + }
127.77 +
127.78 + private static class ScopeRule implements Rule {
127.79 + @Override
127.80 + public boolean appliesTo(RuleContext context) {
127.81 + return true;
127.82 + }
127.83 +
127.84 + @Override
127.85 + public String getDisplayName() {
127.86 + return "";
127.87 + }
127.88 +
127.89 + @Override
127.90 + public boolean showInTasklist() {
127.91 + return true;
127.92 + }
127.93 +
127.94 + @Override
127.95 + public HintSeverity getDefaultSeverity() {
127.96 + return HintSeverity.ERROR;
127.97 + }
127.98 + }
127.99 +
127.100 + @Override
127.101 + public void computeErrors(HintsManager manager, RuleContext context, List<Hint> result, List<Error> unhandled) {
127.102 + ParserResult parserResult = context.parserResult;
127.103 + if (parserResult == null) {
127.104 + return;
127.105 + }
127.106 +
127.107 + PythonParserResult pr = (PythonParserResult)parserResult;
127.108 + List<Error> scopeErrors = pr.getSymbolTable().getErrors();
127.109 + if (scopeErrors.size() > 0) {
127.110 + List<HintFix> fixList = Collections.emptyList();
127.111 + Rule rule = new ScopeRule(); // HACK! Just need a rule that will return a severity!
127.112 + for (Error error : scopeErrors) {
127.113 + Hint desc = new Hint(rule, error.getDisplayName(), error.getFile(),
127.114 + new OffsetRange(error.getStartPosition(), error.getEndPosition()), fixList, 10);
127.115 + result.add(desc);
127.116 + }
127.117 + }
127.118 +
127.119 + List<? extends Error> errors = parserResult.getDiagnostics();
127.120 + if (errors == null || errors.size() == 0) {
127.121 + return;
127.122 + }
127.123 +//
127.124 +// cancelled = false;
127.125 +//
127.126 +// @SuppressWarnings("unchecked")
127.127 +// Map<String,List<JsErrorRule>> hints = (Map)manager.getErrors();
127.128 +//
127.129 +// if (hints.isEmpty() || isCancelled()) {
127.130 + unhandled.addAll(errors);
127.131 +// return;
127.132 +// }
127.133 +//
127.134 +// for (Error error : errors) {
127.135 +// if (!applyErrorRules(manager, context, error, hints, result)) {
127.136 +// unhandled.add(error);
127.137 +// }
127.138 +// }
127.139 + }
127.140 +
127.141 + @Override
127.142 + public void computeSelectionHints(HintsManager manager, RuleContext context, List<Hint> result, int start, int end) {
127.143 + cancelled = false;
127.144 +
127.145 + if (GsfUtilities.isCodeTemplateEditing(context.doc)) {
127.146 + return;
127.147 + }
127.148 +
127.149 + ParserResult parserResult = context.parserResult;
127.150 + if (parserResult == null) {
127.151 + return;
127.152 + }
127.153 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
127.154 +
127.155 + if (root == null) {
127.156 + return;
127.157 + }
127.158 + @SuppressWarnings("unchecked")
127.159 + List<? extends Rule.SelectionRule> hints = manager.getSelectionHints();
127.160 +
127.161 + if (hints.isEmpty()) {
127.162 + return;
127.163 + }
127.164 +
127.165 + if (isCancelled()) {
127.166 + return;
127.167 + }
127.168 +
127.169 + try {
127.170 + context.doc.readLock();
127.171 + applySelectionRules(manager, context, hints, result);
127.172 + } finally {
127.173 + context.doc.readUnlock();
127.174 + }
127.175 +}
127.176 +
127.177 + private void applySelectionRules(HintsManager manager, RuleContext context, List<? extends Rule.SelectionRule> rules, List<Hint> result) {
127.178 +
127.179 + PythonRuleContext pythonContext = (PythonRuleContext)context;
127.180 +
127.181 + for (Rule.SelectionRule rule : rules) {
127.182 + if (!rule.appliesTo(context)) {
127.183 + continue;
127.184 + }
127.185 +
127.186 + if(!(rule instanceof PythonSelectionRule)) {
127.187 + continue;
127.188 + }
127.189 +
127.190 + if (!manager.isEnabled((PythonSelectionRule)rule)) {
127.191 + continue;
127.192 + }
127.193 +
127.194 + try {
127.195 + context.doc.readLock();
127.196 + ((PythonSelectionRule)rule).run(pythonContext, result);
127.197 + } finally {
127.198 + context.doc.readUnlock();
127.199 + }
127.200 + }
127.201 + }
127.202 +
127.203 + @Override
127.204 + public void computeHints(HintsManager manager, RuleContext context, List<Hint> result) {
127.205 + cancelled = false;
127.206 +
127.207 + if (context.parserResult == null) {
127.208 + return;
127.209 + }
127.210 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
127.211 +
127.212 + if (root == null) {
127.213 + return;
127.214 + }
127.215 + @SuppressWarnings("unchecked")
127.216 + Map<Class, List<PythonAstRule>> hints = (Map)manager.getHints(false, context);
127.217 +
127.218 + if (hints.isEmpty()) {
127.219 + return;
127.220 + }
127.221 +
127.222 + if (isCancelled()) {
127.223 + return;
127.224 + }
127.225 +
127.226 +// AstPath path = new AstPath();
127.227 +// path.descend(root);
127.228 +//
127.229 +// //applyRules(manager, NodeTypes.ROOTNODE, root, path, info, hints, descriptions);
127.230 +// applyHints(manager, context, -1, root, path, hints, result);
127.231 +//
127.232 +// scan(manager, context, root, path, hints, result);
127.233 +// path.ascend();
127.234 +
127.235 +
127.236 + RuleApplicator finder = new RuleApplicator(manager, context, hints, result);
127.237 + try {
127.238 + context.doc.readLock();
127.239 + finder.visit(root);
127.240 + } catch (Exception ex) {
127.241 + Exceptions.printStackTrace(ex);
127.242 + } finally {
127.243 + context.doc.readUnlock();
127.244 + }
127.245 + }
127.246 +
127.247 + @SuppressWarnings("unchecked")
127.248 + @Override
127.249 + public void computeSuggestions(HintsManager manager, RuleContext context, List<Hint> result, int caretOffset) {
127.250 + cancelled = false;
127.251 + if (context.parserResult == null) {
127.252 + return;
127.253 + }
127.254 +
127.255 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
127.256 +
127.257 + if (root == null) {
127.258 + return;
127.259 + }
127.260 +
127.261 + Map<Class, List<PythonAstRule>> suggestions = new HashMap<>();
127.262 + suggestions.putAll((Map)manager.getHints(true, context));
127.263 +
127.264 + Set<Entry<Class, List<PythonAstRule>>> entrySet = (Set)manager.getSuggestions().entrySet();
127.265 + for (Entry<Class, List<PythonAstRule>> e : entrySet) {
127.266 + List<PythonAstRule> rules = suggestions.get(e.getKey());
127.267 +
127.268 + if (rules != null) {
127.269 + List<PythonAstRule> res = new LinkedList<>();
127.270 +
127.271 + res.addAll(rules);
127.272 + res.addAll(e.getValue());
127.273 +
127.274 + suggestions.put(e.getKey(), res);
127.275 + } else {
127.276 + suggestions.put(e.getKey(), e.getValue());
127.277 + }
127.278 + }
127.279 +
127.280 + if (suggestions.isEmpty()) {
127.281 + return;
127.282 + }
127.283 +
127.284 +
127.285 + if (isCancelled()) {
127.286 + return;
127.287 + }
127.288 +
127.289 + try {
127.290 + context.doc.readLock();
127.291 +
127.292 + PythonParserResult info = (PythonParserResult)context.parserResult;
127.293 + int astOffset = PythonAstUtils.getAstOffset(info, caretOffset);
127.294 + AstPath path = AstPath.get(root, astOffset);
127.295 + Iterator<PythonTree> it = path.leafToRoot();
127.296 + while (it.hasNext()) {
127.297 + if (isCancelled()) {
127.298 + return;
127.299 + }
127.300 +
127.301 + PythonTree node = it.next();
127.302 +
127.303 + applySuggestions(manager, context, node.getClass(), node, path, suggestions, result);
127.304 + }
127.305 + } finally {
127.306 + context.doc.readUnlock();
127.307 + }
127.308 +
127.309 + //applyRules(NodeTypes.ROOTNODE, path, info, suggestions, caretOffset, result);
127.310 + }
127.311 +
127.312 + private void applySuggestions(HintsManager manager, RuleContext context, Class nodeType, PythonTree node, AstPath path, Map<Class, List<PythonAstRule>> hints,
127.313 + List<Hint> result) {
127.314 + List<PythonAstRule> rules = hints.get(nodeType);
127.315 +
127.316 + if (rules != null) {
127.317 + PythonRuleContext pyCtx = (PythonRuleContext)context;
127.318 + pyCtx.node = node;
127.319 + pyCtx.path = path;
127.320 +
127.321 + try {
127.322 + context.doc.readLock();
127.323 + for (PythonAstRule rule : rules) {
127.324 + if (manager.isEnabled(rule)) {
127.325 + rule.run(pyCtx, result);
127.326 + }
127.327 + }
127.328 + } finally {
127.329 + context.doc.readUnlock();
127.330 + }
127.331 + }
127.332 + }
127.333 +
127.334 +// /** Apply error rules and return true iff somebody added an error description for it */
127.335 +// private boolean applyErrorRules(HintsManager manager, RuleContext context, Error error, Map<String,List<JsErrorRule>> hints,
127.336 +// List<Hint> result) {
127.337 +// String code = error.getKey();
127.338 +// if (code != null) {
127.339 +// List<JsErrorRule> rules = hints.get(code);
127.340 +//
127.341 +// if (rules != null) {
127.342 +// int countBefore = result.size();
127.343 +// PythonRuleContext jsContext = (PythonRuleContext)context;
127.344 +//
127.345 +// boolean disabled = false;
127.346 +// for (JsErrorRule rule : rules) {
127.347 +// if (!manager.isEnabled(rule)) {
127.348 +// disabled = true;
127.349 +// } else if (rule.appliesTo(context)) {
127.350 +// rule.run(jsContext, error, result);
127.351 +// }
127.352 +// }
127.353 +//
127.354 +// return disabled || countBefore < result.size() || jsContext.remove;
127.355 +// }
127.356 +// }
127.357 +//
127.358 +// return false;
127.359 +// }
127.360 +//
127.361 +// private void applySelectionRules(HintsManager manager, RuleContext context, List<JsSelectionRule> rules,
127.362 +// List<Hint> result) {
127.363 +//
127.364 +// for (JsSelectionRule rule : rules) {
127.365 +// if (!rule.appliesTo(context)) {
127.366 +// continue;
127.367 +// }
127.368 +//
127.369 +// //if (!manager.isEnabled(rule)) {
127.370 +// // continue;
127.371 +// //}
127.372 +//
127.373 +// rule.run(context, result);
127.374 +// }
127.375 +// }
127.376 +//
127.377 + @Override
127.378 + public void cancel() {
127.379 + cancelled = true;
127.380 + }
127.381 +
127.382 + private boolean isCancelled() {
127.383 + return cancelled;
127.384 + }
127.385 +
127.386 + @Override
127.387 + public RuleContext createRuleContext() {
127.388 + return new PythonRuleContext();
127.389 + }
127.390 +
127.391 + @Override
127.392 + public List<Rule> getBuiltinRules() {
127.393 + return Collections.emptyList();
127.394 + }
127.395 +
127.396 + private static class RuleApplicator extends Visitor {
127.397 + private HintsManager manager;
127.398 + private RuleContext context;
127.399 + private AstPath path;
127.400 + private Map<Class, List<PythonAstRule>> hints;
127.401 + private List<Hint> result;
127.402 +
127.403 + public RuleApplicator(HintsManager manager, RuleContext context, Map<Class, List<PythonAstRule>> hints, List<Hint> result) {
127.404 + this.manager = manager;
127.405 + this.context = context;
127.406 + this.hints = hints;
127.407 + this.result = result;
127.408 +
127.409 + path = new AstPath();
127.410 + }
127.411 +
127.412 + @Override
127.413 + public void traverse(PythonTree node) throws Exception {
127.414 + path.descend(node);
127.415 + applyHints(node);
127.416 + super.traverse(node);
127.417 + path.ascend();
127.418 + }
127.419 +
127.420 + private void applyHints(PythonTree node) {
127.421 + List<PythonAstRule> rules = hints.get(node.getClass());
127.422 +
127.423 + if (rules != null) {
127.424 + PythonRuleContext jsContext = (PythonRuleContext)context;
127.425 + jsContext.node = node;
127.426 + jsContext.path = path;
127.427 +
127.428 + for (PythonAstRule rule : rules) {
127.429 + if (manager.isEnabled(rule)) {
127.430 + rule.run(jsContext, result);
127.431 + }
127.432 + }
127.433 + }
127.434 + }
127.435 + }
127.436 +}
128.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonRuleContext.java Wed Sep 02 20:31:18 2015 +0200
128.3 @@ -0,0 +1,45 @@
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 org.netbeans.modules.python.source.AstPath;
128.37 +import org.python.antlr.PythonTree;
128.38 +
128.39 +/**
128.40 + * Information about the current context a rule is being asked to evaluate.
128.41 + *
128.42 + * @author Tor Norbye
128.43 + */
128.44 +public class PythonRuleContext extends org.netbeans.modules.csl.api.RuleContext {
128.45 + public AstPath path;
128.46 + public PythonTree node;
128.47 + public boolean remove;
128.48 +}
129.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
129.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/PythonSelectionRule.java Wed Sep 02 20:31:18 2015 +0200
129.3 @@ -0,0 +1,128 @@
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 javax.swing.text.BadLocationException;
129.37 +import java.util.List;
129.38 +import org.netbeans.modules.python.source.PythonAstUtils;
129.39 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
129.40 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
129.41 +import org.netbeans.api.lexer.Token;
129.42 +import org.netbeans.api.lexer.TokenId;
129.43 +import org.netbeans.editor.BaseDocument;
129.44 +import org.netbeans.editor.Utilities;
129.45 +import org.netbeans.modules.csl.api.Hint;
129.46 +import org.netbeans.modules.csl.api.OffsetRange;
129.47 +import org.netbeans.modules.csl.api.Rule.SelectionRule;
129.48 +import org.netbeans.modules.csl.api.Rule.UserConfigurableRule;
129.49 +import org.openide.util.Exceptions;
129.50 +import org.python.antlr.PythonTree;
129.51 +
129.52 +/**
129.53 + * Represents a rule to be run on text selection
129.54 + *
129.55 + * @author Tor Norbye
129.56 + */
129.57 +public abstract class PythonSelectionRule implements SelectionRule, UserConfigurableRule {
129.58 + protected abstract int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange);
129.59 +
129.60 + //public abstract void run(PythonRuleContext context, List<Hint> result);
129.61 + public void run(PythonRuleContext context, List<Hint> result) {
129.62 + // TODO - decide if this code represents a complete statement...
129.63 + // For now - that's true iff there's no code to the left on the
129.64 + // start line and code to the right on the end line
129.65 + BaseDocument doc = context.doc;
129.66 + int originalStart = context.selectionStart;
129.67 + int originalEnd = context.selectionEnd;
129.68 + int docLength = doc.getLength();
129.69 +
129.70 + if (originalEnd > docLength) {
129.71 + return;
129.72 + }
129.73 + OffsetRange narrowed = PythonLexerUtils.narrow(doc, new OffsetRange(originalStart, originalEnd), false);
129.74 + if (narrowed == OffsetRange.NONE) {
129.75 + return;
129.76 + }
129.77 +
129.78 + int start = narrowed.getStart();
129.79 + int end = narrowed.getEnd();
129.80 + try {
129.81 + if (start > Utilities.getRowFirstNonWhite(doc, Math.min(docLength, start))) {
129.82 + return;
129.83 + }
129.84 + if (end < Utilities.getRowLastNonWhite(doc, Math.min(docLength, end)) + 1) {
129.85 + return;
129.86 + }
129.87 + } catch (BadLocationException ex) {
129.88 + Exceptions.printStackTrace(ex);
129.89 + }
129.90 +
129.91 + PythonTree root = PythonAstUtils.getRoot(context.parserResult);
129.92 + if (root == null) {
129.93 + return;
129.94 + }
129.95 +
129.96 + OffsetRange astRange = PythonAstUtils.getAstOffsets(context.parserResult, new OffsetRange(start, end));
129.97 + if (astRange == OffsetRange.NONE) {
129.98 + return;
129.99 + }
129.100 +
129.101 + int applicability = getApplicability(context, root, astRange);
129.102 + if (applicability == 0) {
129.103 + return;
129.104 + }
129.105 + // Don't allow extract with if you're inside strings or comments
129.106 + Token<? extends PythonTokenId> startToken = PythonLexerUtils.getToken(doc, start);
129.107 + Token<? extends PythonTokenId> endToken = PythonLexerUtils.getToken(doc, end);
129.108 + if (startToken == null || endToken == null) {
129.109 + return;
129.110 + }
129.111 + TokenId startId = startToken.id();
129.112 + if (startId == PythonTokenId.STRING_LITERAL ||
129.113 + (startId == PythonTokenId.COMMENT && start > 0 && startToken == PythonLexerUtils.getToken(doc, start - 1))) {
129.114 + return;
129.115 + }
129.116 + TokenId endId = endToken.id();
129.117 + if (endId == PythonTokenId.STRING_LITERAL) {
129.118 + return;
129.119 + }
129.120 +
129.121 + // TODO - don't enable inside comments or strings!!
129.122 + // TODO - if you are including functions or classes it should probably
129.123 + // be disabled!
129.124 +
129.125 + OffsetRange range = new OffsetRange(originalStart, originalEnd);
129.126 +
129.127 + run(context, result, range, applicability);
129.128 + }
129.129 +
129.130 + public abstract void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability);
129.131 +}
130.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
130.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/RelativeImports.java Wed Sep 02 20:31:18 2015 +0200
130.3 @@ -0,0 +1,246 @@
130.4 +/*
130.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
130.6 + *
130.7 + * Copyright 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 + * If you wish your version of this file to be governed by only the CDDL
130.31 + * or only the GPL Version 2, indicate your decision by adding
130.32 + * "[Contributor] elects to include this software in this distribution
130.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
130.34 + * single choice of license, a recipient has the option to distribute
130.35 + * your version of this file under either the CDDL, the GPL Version 2 or
130.36 + * to extend the choice of license to its licensees as provided above.
130.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
130.38 + * Version 2 license, then the option applies only if the new code is
130.39 + * made subject to such option by the copyright holder.
130.40 + *
130.41 + * Contributor(s):
130.42 + *
130.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
130.44 + */
130.45 +package org.netbeans.modules.python.hints;
130.46 +
130.47 +import java.util.ArrayList;
130.48 +import java.util.Collections;
130.49 +import java.util.List;
130.50 +import java.util.Set;
130.51 +import java.util.prefs.Preferences;
130.52 +import javax.swing.JComponent;
130.53 +import javax.swing.text.BadLocationException;
130.54 +import org.netbeans.modules.python.source.PythonAstUtils;
130.55 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
130.56 +import org.netbeans.editor.BaseDocument;
130.57 +import org.netbeans.editor.Utilities;
130.58 +import org.netbeans.modules.csl.api.EditList;
130.59 +import org.netbeans.modules.csl.api.Hint;
130.60 +import org.netbeans.modules.csl.api.HintFix;
130.61 +import org.netbeans.modules.csl.api.HintSeverity;
130.62 +import org.netbeans.modules.csl.api.OffsetRange;
130.63 +import org.netbeans.modules.csl.api.PreviewableFix;
130.64 +import org.netbeans.modules.csl.api.RuleContext;
130.65 +import org.netbeans.modules.csl.spi.ParserResult;
130.66 +import org.netbeans.modules.python.source.PythonParserResult;
130.67 +import org.openide.filesystems.FileObject;
130.68 +import org.openide.util.Exceptions;
130.69 +import org.openide.util.NbBundle;
130.70 +import org.python.antlr.PythonTree;
130.71 +import org.python.antlr.ast.ImportFrom;
130.72 +
130.73 +/**
130.74 + * Import statements should be one per line. This quickfix
130.75 + * offers to make it so.
130.76 + *
130.77 + * @todo Ensure that
130.78 + * {@code from __future__ import absolute_import}
130.79 + * is present, at least until Python 2.7
130.80 + *
130.81 + * @author Tor Norbye
130.82 + */
130.83 +public class RelativeImports extends PythonAstRule {
130.84 + @Override
130.85 + public Set<Class> getKinds() {
130.86 + return Collections.singleton((Class)ImportFrom.class);
130.87 + }
130.88 +
130.89 + @Override
130.90 + public void run(PythonRuleContext context, List<Hint> result) {
130.91 + ImportFrom imp = (ImportFrom)context.node;
130.92 + if (imp.getInternalModule() != null && imp.getInternalModule().startsWith(".")) {
130.93 + PythonTree node = context.node;
130.94 + PythonParserResult info = (PythonParserResult) context.parserResult;
130.95 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
130.96 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
130.97 + BaseDocument doc = context.doc;
130.98 + try {
130.99 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
130.100 + (context.caretOffset == -1 ||
130.101 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
130.102 + List<HintFix> fixList = new ArrayList<>();
130.103 + fixList.add(new RelativeImportsFix(context, imp));
130.104 + String displayName = getDisplayName();
130.105 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
130.106 + result.add(desc);
130.107 + }
130.108 + } catch (BadLocationException ex) {
130.109 + Exceptions.printStackTrace(ex);
130.110 + }
130.111 + }
130.112 + }
130.113 +
130.114 + @Override
130.115 + public String getId() {
130.116 + return "RelativeImports"; // NOI18N
130.117 + }
130.118 +
130.119 + @Override
130.120 + public String getDisplayName() {
130.121 + return NbBundle.getMessage(RelativeImports.class, "RelativeImports");
130.122 + }
130.123 +
130.124 + @Override
130.125 + public String getDescription() {
130.126 + return NbBundle.getMessage(RelativeImports.class, "RelativeImportsDesc");
130.127 + }
130.128 +
130.129 + @Override
130.130 + public boolean getDefaultEnabled() {
130.131 + return true;
130.132 + }
130.133 +
130.134 + @Override
130.135 + public JComponent getCustomizer(Preferences node) {
130.136 + return null;
130.137 + }
130.138 +
130.139 + @Override
130.140 + public boolean appliesTo(RuleContext context) {
130.141 + return true;
130.142 + }
130.143 +
130.144 + @Override
130.145 + public boolean showInTasklist() {
130.146 + return true;
130.147 + }
130.148 +
130.149 + @Override
130.150 + public HintSeverity getDefaultSeverity() {
130.151 + return HintSeverity.WARNING;
130.152 + }
130.153 +
130.154 + private static class RelativeImportsFix implements PreviewableFix {
130.155 + private final PythonRuleContext context;
130.156 + private final ImportFrom imp;
130.157 +
130.158 + private RelativeImportsFix(PythonRuleContext context, ImportFrom imp) {
130.159 + this.context = context;
130.160 + this.imp = imp;
130.161 + }
130.162 +
130.163 + @Override
130.164 + public String getDescription() {
130.165 + return NbBundle.getMessage(RelativeImports.class, "RelativeImportsFix");
130.166 + }
130.167 +
130.168 + @Override
130.169 + public boolean canPreview() {
130.170 + return true;
130.171 + }
130.172 +
130.173 + @Override
130.174 + public EditList getEditList() throws Exception {
130.175 + BaseDocument doc = context.doc;
130.176 + EditList edits = new EditList(doc);
130.177 +
130.178 + // Algorithm:
130.179 + // (1) Figure out which package we are in
130.180 + // (2) Subtrack package elements per dot
130.181 + // (3) Replace relative reference
130.182 +
130.183 + OffsetRange astRange = PythonAstUtils.getRange(imp);
130.184 + if (astRange != OffsetRange.NONE) {
130.185 + PythonParserResult info = (PythonParserResult)context.parserResult;
130.186 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
130.187 + if (lexRange != OffsetRange.NONE) {
130.188 + FileObject fo = info.getSnapshot().getSource().getFileObject();
130.189 + if (fo != null) {
130.190 + String path = imp.getInternalModule();
130.191 + int i = 0;
130.192 + for (; i < path.length(); i++) {
130.193 + if (path.charAt(i) != '.') {
130.194 + break;
130.195 + }
130.196 + }
130.197 + int levels = i;
130.198 + path = path.substring(levels);
130.199 +
130.200 + for (int j = 0; j < levels; j++) {
130.201 + if (fo != null) {
130.202 + fo = fo.getParent();
130.203 + }
130.204 + }
130.205 +
130.206 + // Finally, find out the absolute path we are in
130.207 + // Hopefully, I will have access to the python load path
130.208 + // here. But in the mean time, I can just see which
130.209 + // packages I am in...
130.210 + while (fo != null) {
130.211 + if (fo.getFileObject("__init__.py") != null) { // NOI18N
130.212 + // Yep, we're still in a package
130.213 + if (path.length() > 0) {
130.214 + path = fo.getName() + "." + path; // NOI18N
130.215 + } else {
130.216 + path = fo.getName();
130.217 + }
130.218 + }
130.219 + fo = fo.getParent();
130.220 + }
130.221 + String text = doc.getText(lexRange.getStart(), lexRange.getLength());
130.222 + int relativePos = text.indexOf(imp.getInternalModule());
130.223 + if (relativePos != -1) {
130.224 + edits.replace(lexRange.getStart() + relativePos, imp.getInternalModule().length(), path, false, 0);
130.225 + }
130.226 + }
130.227 + }
130.228 + }
130.229 +
130.230 + return edits;
130.231 + }
130.232 +
130.233 + @Override
130.234 + public void implement() throws Exception {
130.235 + EditList edits = getEditList();
130.236 + edits.apply();
130.237 + }
130.238 +
130.239 + @Override
130.240 + public boolean isSafe() {
130.241 + return true;
130.242 + }
130.243 +
130.244 + @Override
130.245 + public boolean isInteractive() {
130.246 + return false;
130.247 + }
130.248 + }
130.249 +}
131.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
131.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/SplitImports.java Wed Sep 02 20:31:18 2015 +0200
131.3 @@ -0,0 +1,222 @@
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.GsfUtilities;
131.66 +import org.netbeans.modules.editor.indent.api.IndentUtils;
131.67 +import org.netbeans.modules.python.source.PythonParserResult;
131.68 +import org.netbeans.modules.python.source.CodeStyle;
131.69 +import org.openide.util.Exceptions;
131.70 +import org.openide.util.NbBundle;
131.71 +import org.python.antlr.PythonTree;
131.72 +import org.python.antlr.ast.Import;
131.73 +import org.python.antlr.ast.alias;
131.74 +
131.75 +/**
131.76 + * Import statements should be one per line. This quickfix
131.77 + * offers to make it so.
131.78 + *
131.79 + * @author Tor Norbye
131.80 + */
131.81 +public class SplitImports extends PythonAstRule {
131.82 + @Override
131.83 + public Set<Class> getKinds() {
131.84 + return Collections.singleton((Class)Import.class);
131.85 + }
131.86 +
131.87 + @Override
131.88 + public void run(PythonRuleContext context, List<Hint> result) {
131.89 + Import imp = (Import)context.node;
131.90 + List<alias> names = imp.getInternalNames();
131.91 + if (names != null && names.size() > 1) {
131.92 + PythonTree node = context.node;
131.93 + PythonParserResult info = (PythonParserResult)context.parserResult;
131.94 + OffsetRange astOffsets = PythonAstUtils.getNameRange(info, node);
131.95 + OffsetRange lexOffsets = PythonLexerUtils.getLexerOffsets(info, astOffsets);
131.96 + BaseDocument doc = context.doc;
131.97 + try {
131.98 + if (lexOffsets != OffsetRange.NONE && lexOffsets.getStart() < doc.getLength() &&
131.99 + (context.caretOffset == -1 ||
131.100 + Utilities.getRowStart(doc, context.caretOffset) == Utilities.getRowStart(doc, lexOffsets.getStart()))) {
131.101 + List<HintFix> fixList = new ArrayList<>();
131.102 + fixList.add(new SplitImportsFix(context, imp));
131.103 + String displayName = getDisplayName();
131.104 + Hint desc = new Hint(this, displayName, info.getSnapshot().getSource().getFileObject(), lexOffsets, fixList, 1500);
131.105 + result.add(desc);
131.106 + }
131.107 + } catch (BadLocationException ex) {
131.108 + Exceptions.printStackTrace(ex);
131.109 + }
131.110 + }
131.111 + }
131.112 +
131.113 + @Override
131.114 + public String getId() {
131.115 + return "SplitImports"; // NOI18N
131.116 + }
131.117 +
131.118 + @Override
131.119 + public String getDisplayName() {
131.120 + return NbBundle.getMessage(SplitImports.class, "SplitImports");
131.121 + }
131.122 +
131.123 + @Override
131.124 + public String getDescription() {
131.125 + return NbBundle.getMessage(SplitImports.class, "SplitImportsDesc");
131.126 + }
131.127 +
131.128 + @Override
131.129 + public boolean getDefaultEnabled() {
131.130 + return true;
131.131 + }
131.132 +
131.133 + @Override
131.134 + public JComponent getCustomizer(Preferences node) {
131.135 + return null;
131.136 + }
131.137 +
131.138 + @Override
131.139 + public boolean appliesTo(RuleContext context) {
131.140 + CodeStyle codeStyle = CodeStyle.getDefault(context.doc);
131.141 + return codeStyle == null || codeStyle.oneImportPerLine();
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 SplitImportsFix implements PreviewableFix {
131.155 + private final PythonRuleContext context;
131.156 + private final Import imp;
131.157 +
131.158 + private SplitImportsFix(PythonRuleContext context, Import 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(SplitImports.class, "SplitImportsFix");
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 + OffsetRange astRange = PythonAstUtils.getRange(imp);
131.179 + if (astRange != OffsetRange.NONE) {
131.180 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets((PythonParserResult) context.parserResult, astRange);
131.181 + if (lexRange != OffsetRange.NONE) {
131.182 + int indent = GsfUtilities.getLineIndent(doc, lexRange.getStart());
131.183 + StringBuilder sb = new StringBuilder();
131.184 + List<alias> names = imp.getInternalNames();
131.185 + if (names != null) {
131.186 + for (alias at : names) {
131.187 + if (indent > 0 && sb.length() > 0) {
131.188 + sb.append(IndentUtils.createIndentString(doc, indent));
131.189 + }
131.190 + sb.append("import "); // NOI18N
131.191 + sb.append(at.getInternalName());
131.192 + if (at.getInternalAsname() != null && at.getInternalAsname().length() > 0) {
131.193 + sb.append(" as "); // NOI18N
131.194 + sb.append(at.getInternalAsname());
131.195 + }
131.196 + sb.append("\n");
131.197 + }
131.198 + }
131.199 + // Remove the final newline since Import doesn't include it
131.200 + sb.setLength(sb.length() - 1);
131.201 +
131.202 + edits.replace(lexRange.getStart(), lexRange.getLength(), sb.toString(), false, 0);
131.203 + }
131.204 + }
131.205 +
131.206 + return edits;
131.207 + }
131.208 +
131.209 + @Override
131.210 + public void implement() throws Exception {
131.211 + EditList edits = getEditList();
131.212 + edits.apply();
131.213 + }
131.214 +
131.215 + @Override
131.216 + public boolean isSafe() {
131.217 + return true;
131.218 + }
131.219 +
131.220 + @Override
131.221 + public boolean isInteractive() {
131.222 + return false;
131.223 + }
131.224 + }
131.225 +}
132.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
132.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/SurroundWith.java Wed Sep 02 20:31:18 2015 +0200
132.3 @@ -0,0 +1,377 @@
132.4 +/*
132.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
132.6 + *
132.7 + * Copyright 1997-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 + * Contributor(s):
132.31 + *
132.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
132.33 + */
132.34 +package org.netbeans.modules.python.hints;
132.35 +
132.36 +import java.util.ArrayList;
132.37 +import java.util.List;
132.38 +import java.util.prefs.Preferences;
132.39 +import javax.swing.JComponent;
132.40 +import javax.swing.text.JTextComponent;
132.41 +import javax.swing.text.Position;
132.42 +import org.netbeans.editor.BaseDocument;
132.43 +import org.netbeans.editor.Utilities;
132.44 +import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager;
132.45 +import org.netbeans.modules.csl.api.EditList;
132.46 +import org.netbeans.modules.csl.api.Hint;
132.47 +import org.netbeans.modules.csl.api.HintFix;
132.48 +import org.netbeans.modules.csl.api.HintSeverity;
132.49 +import org.netbeans.modules.csl.api.OffsetRange;
132.50 +import org.netbeans.modules.csl.api.PreviewableFix;
132.51 +import org.netbeans.modules.csl.api.RuleContext;
132.52 +import org.netbeans.modules.csl.spi.GsfUtilities;
132.53 +import org.netbeans.modules.editor.indent.api.IndentUtils;
132.54 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
132.55 +import org.openide.util.Exceptions;
132.56 +import org.openide.util.NbBundle;
132.57 +import org.python.antlr.PythonTree;
132.58 +import org.python.antlr.Visitor;
132.59 +import org.python.antlr.ast.ClassDef;
132.60 +import org.python.antlr.ast.FunctionDef;
132.61 +import org.python.antlr.ast.Import;
132.62 +import org.python.antlr.ast.ImportFrom;
132.63 +
132.64 +/**
132.65 + * Offer to surround code with for example try/except/finally
132.66 + *
132.67 + * @author Tor Norbye
132.68 + */
132.69 +public class SurroundWith extends PythonSelectionRule {
132.70 + @Override
132.71 + protected int getApplicability(PythonRuleContext context, PythonTree root, OffsetRange astRange) {
132.72 + if (!ApplicabilityVisitor.applies(root, astRange)) {
132.73 + return 0;
132.74 + }
132.75 +
132.76 + return 1;
132.77 + }
132.78 +
132.79 + @Override
132.80 + public void run(PythonRuleContext context, List<Hint> result, OffsetRange range, int applicability) {
132.81 + int start = range.getStart();
132.82 + int end = range.getEnd();
132.83 +
132.84 + // Adjust the fix range to be right around the dot so that the light bulb ends up
132.85 + // on the same line as the caret and alt-enter works
132.86 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
132.87 + if (target != null) {
132.88 + int dot = target.getCaret().getDot();
132.89 + range = new OffsetRange(dot, dot);
132.90 + }
132.91 +
132.92 + List<HintFix> fixList = new ArrayList<>(3);
132.93 + fixList.add(new SurroundWithFix(context, start, end, false, true));
132.94 + fixList.add(new SurroundWithFix(context, start, end, true, true));
132.95 + fixList.add(new SurroundWithFix(context, start, end, true, false));
132.96 + String displayName = getDisplayName();
132.97 + Hint desc = new Hint(this, displayName, context.parserResult.getSnapshot().getSource().getFileObject(),
132.98 + range, fixList, 1500);
132.99 + result.add(desc);
132.100 + }
132.101 +
132.102 + @Override
132.103 + public boolean appliesTo(RuleContext context) {
132.104 + return true;
132.105 + }
132.106 +
132.107 + @Override
132.108 + public String getDisplayName() {
132.109 + return NbBundle.getMessage(SurroundWith.class, "SurroundWith");
132.110 + }
132.111 +
132.112 + @Override
132.113 + public boolean showInTasklist() {
132.114 + return false;
132.115 + }
132.116 +
132.117 + @Override
132.118 + public HintSeverity getDefaultSeverity() {
132.119 + return HintSeverity.CURRENT_LINE_WARNING;
132.120 + }
132.121 +
132.122 + @Override
132.123 + public String getId() {
132.124 + return "SurroundWith"; // NOI18N
132.125 + }
132.126 +
132.127 + @Override
132.128 + public String getDescription() {
132.129 + return "";
132.130 + }
132.131 +
132.132 + @Override
132.133 + public boolean getDefaultEnabled() {
132.134 + return true;
132.135 + }
132.136 +
132.137 + @Override
132.138 + public JComponent getCustomizer(Preferences node) {
132.139 + return null;
132.140 + }
132.141 +
132.142 + private static class SurroundWithFix implements PreviewableFix {
132.143 + private final PythonRuleContext context;
132.144 + private final boolean includeFinally;
132.145 + private final boolean includeExcept;
132.146 + private Position startPos;
132.147 + private Position endPos;
132.148 + private Position codeTemplatePos;
132.149 + private String codeTemplateText;
132.150 + private final int start;
132.151 + private final int end;
132.152 +
132.153 + private SurroundWithFix(PythonRuleContext context,
132.154 + int start, int end,
132.155 + boolean includeFinally, boolean includeExcept) {
132.156 + assert includeExcept || includeFinally;
132.157 +
132.158 + this.context = context;
132.159 +
132.160 + OffsetRange range = PythonLexerUtils.narrow(context.doc, new OffsetRange(start, end), false);
132.161 + this.start = range.getStart();
132.162 + this.end = range.getEnd();
132.163 + this.includeFinally = includeFinally;
132.164 + this.includeExcept = includeExcept;
132.165 + }
132.166 +
132.167 + @Override
132.168 + public String getDescription() {
132.169 + if (includeExcept && includeFinally) {
132.170 + return NbBundle.getMessage(CreateDocString.class, "SurroundWithTEF");
132.171 + } else if (includeExcept) {
132.172 + return NbBundle.getMessage(CreateDocString.class, "SurroundWithTE");
132.173 + } else {
132.174 + assert includeFinally;
132.175 + return NbBundle.getMessage(CreateDocString.class, "SurroundWithTF");
132.176 + }
132.177 + }
132.178 +
132.179 + @Override
132.180 + public boolean canPreview() {
132.181 + return true;
132.182 + }
132.183 +
132.184 + @Override
132.185 + public EditList getEditList() throws Exception {
132.186 + return getEditList(true);
132.187 + }
132.188 +
132.189 + private EditList getEditList(boolean previewOnly) throws Exception {
132.190 + BaseDocument doc = context.doc;
132.191 + EditList edits = new EditList(doc);
132.192 +
132.193 + int indentSize = IndentUtils.indentLevelSize(doc);
132.194 + String oneIndent = IndentUtils.createIndentString(doc, indentSize);
132.195 + //int initialIndent = GsfUtilities.getLineIndent(doc, start);
132.196 + int lineStart = Utilities.getRowStart(doc, start);
132.197 + String initialIndentStr = IndentUtils.createIndentString(doc, IndentUtils.lineIndent(doc, lineStart));
132.198 + int nextLine = Utilities.getRowEnd(doc, end) + 1;
132.199 + if (nextLine > doc.getLength()) {
132.200 + nextLine = doc.getLength();
132.201 + edits.replace(nextLine, 0, "\n", false, 1);
132.202 + }
132.203 +
132.204 + // Indent the selected lines
132.205 + edits.replace(lineStart, 0, initialIndentStr + "try:\n", false, 1);
132.206 + for (int offset = start; offset < end; offset = Utilities.getRowEnd(doc, offset) + 1) {
132.207 + edits.replace(offset, 0, oneIndent, false, 1);
132.208 + }
132.209 +
132.210 + StringBuilder sb = new StringBuilder();
132.211 + if (includeExcept) {
132.212 + sb.append(initialIndentStr);
132.213 + sb.append("except ");
132.214 + if (!previewOnly) {
132.215 + sb.append("${except default=\"");
132.216 + }
132.217 + sb.append("Exception, e");
132.218 + if (!previewOnly) {
132.219 + sb.append("\"}");
132.220 + }
132.221 + sb.append(":\n");
132.222 + sb.append(initialIndentStr);
132.223 + sb.append(oneIndent);
132.224 + int caretDelta = sb.length();
132.225 + startPos = edits.createPosition(nextLine + caretDelta);
132.226 + if (!previewOnly) {
132.227 + sb.append("${action default=\"");
132.228 + }
132.229 + sb.append("print \"Exception: \", e");
132.230 + if (!previewOnly) {
132.231 + sb.append("\"}");
132.232 + }
132.233 + caretDelta = sb.length();
132.234 + endPos = edits.createPosition(nextLine + caretDelta);
132.235 + sb.append("\n");
132.236 + if (!previewOnly && !includeExcept) {
132.237 + sb.append("${cursor}");
132.238 + }
132.239 + }
132.240 + if (includeFinally) {
132.241 + sb.append(initialIndentStr);
132.242 + sb.append("finally:\n");
132.243 + sb.append(initialIndentStr);
132.244 + sb.append(oneIndent);
132.245 + if (!previewOnly) {
132.246 + sb.append("${finally default=\"\"}\n${cursor}");
132.247 + }
132.248 + int caretDelta = sb.length();
132.249 + if (!includeExcept) {
132.250 + endPos = startPos = edits.createPosition(nextLine + caretDelta);
132.251 + }
132.252 + sb.append("\n");
132.253 + }
132.254 + if (previewOnly) {
132.255 + edits.replace(nextLine, 0, sb.toString(), false, 1);
132.256 + } else {
132.257 + codeTemplatePos = edits.createPosition(nextLine, Position.Bias.Backward);
132.258 + codeTemplateText = sb.toString();
132.259 + }
132.260 +
132.261 + return edits;
132.262 + }
132.263 +
132.264 + @Override
132.265 + public void implement() throws Exception {
132.266 + EditList edits = getEditList(true);
132.267 +
132.268 + JTextComponent target = GsfUtilities.getPaneFor(context.parserResult.getSnapshot().getSource().getFileObject());
132.269 + edits.apply();
132.270 + if (target != null) {
132.271 + if (codeTemplateText != null && codeTemplatePos != null) {
132.272 + final CodeTemplateManager ctm = CodeTemplateManager.get(context.doc);
132.273 + if (ctm != null) {
132.274 + target.getCaret().setDot(codeTemplatePos.getOffset());
132.275 + ctm.createTemporary(codeTemplateText).insert(target);
132.276 + }
132.277 + } else if (startPos != null && endPos != null) {
132.278 + target.setSelectionStart(startPos.getOffset());
132.279 + target.setSelectionEnd(endPos.getOffset());
132.280 + }
132.281 + }
132.282 + }
132.283 +
132.284 + @Override
132.285 + public boolean isSafe() {
132.286 + return true;
132.287 + }
132.288 +
132.289 + @Override
132.290 + public boolean isInteractive() {
132.291 + return false;
132.292 + }
132.293 + }
132.294 +
132.295 + /** @todo Prune search in traverse, ala AstPath.
132.296 + * @todo Build up start and end AstPaths.
132.297 + */
132.298 + private static class ApplicabilityVisitor extends Visitor {
132.299 + private boolean applies = true;
132.300 + private final int start;
132.301 + private final int end;
132.302 +
132.303 + static boolean applies(PythonTree root, OffsetRange astRange) {
132.304 + ApplicabilityVisitor visitor = new ApplicabilityVisitor(astRange);
132.305 + try {
132.306 + visitor.visit(root);
132.307 + } catch (Exception ex) {
132.308 + Exceptions.printStackTrace(ex);
132.309 + return false;
132.310 + }
132.311 + return visitor.isApplicable();
132.312 + }
132.313 +
132.314 + ApplicabilityVisitor(OffsetRange astRange) {
132.315 + this.start = astRange.getStart();
132.316 + this.end = astRange.getEnd();
132.317 + }
132.318 +
132.319 + public boolean isApplicable() {
132.320 + return applies;
132.321 + }
132.322 +
132.323 + private void maybeBail(PythonTree node) {
132.324 + int nodeStart = node.getCharStartIndex();
132.325 + int nodeEnd = node.getCharStopIndex();
132.326 + if (nodeStart >= start && nodeStart < end) {
132.327 + applies = false;
132.328 + }
132.329 + if (nodeEnd > start && nodeEnd < end) {
132.330 + applies = false;
132.331 + }
132.332 + }
132.333 +
132.334 + @Override
132.335 + public void traverse(PythonTree node) throws Exception {
132.336 + if (!applies) {
132.337 + return;
132.338 + }
132.339 +
132.340 + int nodeStart = node.getCharStartIndex();
132.341 + int nodeStop = node.getCharStopIndex();
132.342 + //if (!(nodeStop < start || nodeStart > end)) {
132.343 + if (nodeStop >= start && nodeStart <= end) {
132.344 + super.traverse(node);
132.345 + }
132.346 + }
132.347 +
132.348 + @Override
132.349 + public Object visitClassDef(ClassDef node) throws Exception {
132.350 + maybeBail(node);
132.351 + return super.visitClassDef(node);
132.352 + }
132.353 +
132.354 + @Override
132.355 + public Object visitFunctionDef(FunctionDef node) throws Exception {
132.356 + maybeBail(node);
132.357 + return super.visitFunctionDef(node);
132.358 + }
132.359 +
132.360 + @Override
132.361 + public Object visitImport(Import node) throws Exception {
132.362 + maybeBail(node);
132.363 + return super.visitImport(node);
132.364 + }
132.365 +
132.366 + @Override
132.367 + public Object visitImportFrom(ImportFrom node) throws Exception {
132.368 + maybeBail(node);
132.369 + return super.visitImportFrom(node);
132.370 + }
132.371 +
132.372 + // Module is okay - you get this when you select all text in a simple "script" file
132.373 + // with only statements
132.374 + //@Override
132.375 + //public Object visitModule(Module node) throws Exception {
132.376 + // maybeBail(node);
132.377 + // return super.visitModule(node);
132.378 + //}
132.379 + }
132.380 +}
133.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
133.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnresolvedClassComponents.java Wed Sep 02 20:31:18 2015 +0200
133.3 @@ -0,0 +1,207 @@
133.4 +/*
133.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
133.6 + *
133.7 + * Copyright 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 + * If you wish your version of this file to be governed by only the CDDL
133.31 + * or only the GPL Version 2, indicate your decision by adding
133.32 + * "[Contributor] elects to include this software in this distribution
133.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
133.34 + * single choice of license, a recipient has the option to distribute
133.35 + * your version of this file under either the CDDL, the GPL Version 2 or
133.36 + * to extend the choice of license to its licensees as provided above.
133.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
133.38 + * Version 2 license, then the option applies only if the new code is
133.39 + * made subject to such option by the copyright holder.
133.40 + *
133.41 + * Contributor(s):
133.42 + *
133.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
133.44 + */
133.45 +package org.netbeans.modules.python.hints;
133.46 +
133.47 +import java.util.Collections;
133.48 +import java.util.List;
133.49 +import java.util.Set;
133.50 +import java.util.prefs.Preferences;
133.51 +import javax.swing.JComponent;
133.52 +import org.netbeans.modules.csl.api.Hint;
133.53 +import org.netbeans.modules.csl.api.HintFix;
133.54 +import org.netbeans.modules.csl.api.HintSeverity;
133.55 +import org.netbeans.modules.csl.api.OffsetRange;
133.56 +import org.netbeans.modules.csl.api.RuleContext;
133.57 +import org.netbeans.modules.python.source.PythonAstUtils;
133.58 +import org.netbeans.modules.python.source.PythonParserResult;
133.59 +import org.netbeans.modules.python.source.ImportManager;
133.60 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
133.61 +import org.netbeans.modules.python.source.scopes.SymbolTable;
133.62 +import org.openide.util.NbBundle;
133.63 +import org.python.antlr.PythonTree;
133.64 +import org.python.antlr.ast.Module;
133.65 +
133.66 +/**
133.67 + * Detect Unresolved class attributes
133.68 + *
133.69 + * @author Jean-Yves Mengant
133.70 + */
133.71 +public class UnresolvedClassComponents extends PythonAstRule {
133.72 +
133.73 + private final static String CLASS_UNRESOLVED_ATTRIBUTES = "UnresolvedAttributes";
133.74 + private final static String CLASS_UNRESOLVED_INHERITANCE_VAR = "UnresolvedInheritanceVariable";
133.75 + private final static String CLASS_UNRESOLVED_ATTRIBUTES_VAR = "UnresolvedAttributesVariable";
133.76 + private final static String CLASS_UNRESOLVED_ATTRIBUTES_DESC = "UnresolvedAttributesDesc";
133.77 +
133.78 +
133.79 +
133.80 + public UnresolvedClassComponents() {
133.81 + }
133.82 +
133.83 + @Override
133.84 + public boolean appliesTo(RuleContext context) {
133.85 + return true;
133.86 + }
133.87 +
133.88 + @Override
133.89 + public Set<Class> getKinds() {
133.90 + return Collections.<Class>singleton(Module.class);
133.91 + }
133.92 +
133.93 + private void populateMessages( PythonParserResult info, List<PythonTree> unresolved , List<Hint> result ,boolean isClass ) {
133.94 + if (unresolved.size() > 0) {
133.95 +
133.96 + for (PythonTree node : unresolved) {
133.97 + // Compute suggestions
133.98 + String name = PythonAstUtils.getName(node);
133.99 + if (name == null) {
133.100 + name = "";
133.101 + }
133.102 + List<HintFix> fixList = Collections.emptyList();
133.103 + String message ;
133.104 + if ( isClass)
133.105 + message = NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_INHERITANCE_VAR, name);
133.106 + else
133.107 + message = NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES_VAR, name);
133.108 + OffsetRange range = PythonAstUtils.getRange( node);
133.109 + range = PythonLexerUtils.getLexerOffsets(info, range);
133.110 + if (range != OffsetRange.NONE) {
133.111 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
133.112 + result.add(desc);
133.113 + }
133.114 + }
133.115 + }
133.116 + }
133.117 +
133.118 +
133.119 + @Override
133.120 + public void run(PythonRuleContext context, List<Hint> result) {
133.121 + PythonParserResult info = (PythonParserResult) context.parserResult;
133.122 + SymbolTable symbolTable = info.getSymbolTable();
133.123 +
133.124 + List<PythonTree> unresolvedAttributes = symbolTable.getUnresolvedAttributes(info);
133.125 + populateMessages(info,unresolvedAttributes,result,false) ;
133.126 + List<PythonTree> unresolvedParents = symbolTable.getUnresolvedParents(info);
133.127 + populateMessages(info,unresolvedParents,result,true) ;
133.128 + }
133.129 +
133.130 + @Override
133.131 + public String getId() {
133.132 + return CLASS_UNRESOLVED_ATTRIBUTES; // NOI18N
133.133 + }
133.134 +
133.135 + @Override
133.136 + public String getDisplayName() {
133.137 + return NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES);
133.138 + }
133.139 +
133.140 + @Override
133.141 + public String getDescription() {
133.142 + return NbBundle.getMessage(NameRule.class, CLASS_UNRESOLVED_ATTRIBUTES_DESC);
133.143 + }
133.144 +
133.145 + @Override
133.146 + public boolean getDefaultEnabled() {
133.147 + return false;
133.148 + }
133.149 +
133.150 + @Override
133.151 + public boolean showInTasklist() {
133.152 + return true;
133.153 + }
133.154 +
133.155 + @Override
133.156 + public HintSeverity getDefaultSeverity() {
133.157 + return HintSeverity.ERROR;
133.158 + }
133.159 +
133.160 + @Override
133.161 + public JComponent getCustomizer(Preferences node) {
133.162 + return null;
133.163 + }
133.164 +
133.165 + private static class ImportFix implements HintFix {
133.166 + private final PythonRuleContext context;
133.167 + private final PythonTree node;
133.168 + private final String module;
133.169 +
133.170 + private ImportFix(PythonRuleContext context, PythonTree node, String module) {
133.171 + this.context = context;
133.172 + this.node = node;
133.173 + this.module = module;
133.174 + }
133.175 +
133.176 + @Override
133.177 + public String getDescription() {
133.178 + return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
133.179 + }
133.180 +
133.181 + @Override
133.182 + public void implement() throws Exception {
133.183 + String mod = this.module;
133.184 + String symbol = null;
133.185 + int colon = mod.indexOf(':');
133.186 + if (colon != -1) {
133.187 + int end = mod.indexOf('(', colon + 1);
133.188 + if (end == -1) {
133.189 + end = mod.indexOf(';', colon + 1);
133.190 + if (end == -1) {
133.191 + end = mod.length();
133.192 + }
133.193 + }
133.194 + symbol = mod.substring(colon + 1, end).trim();
133.195 + mod = mod.substring(0, colon).trim();
133.196 + }
133.197 + new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
133.198 + }
133.199 +
133.200 + @Override
133.201 + public boolean isSafe() {
133.202 + return true;
133.203 + }
133.204 +
133.205 + @Override
133.206 + public boolean isInteractive() {
133.207 + return false;
133.208 + }
133.209 + }
133.210 +}
134.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
134.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnresolvedDetector.java Wed Sep 02 20:31:18 2015 +0200
134.3 @@ -0,0 +1,227 @@
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.ArrayList;
134.48 +import java.util.Collections;
134.49 +import java.util.List;
134.50 +import java.util.Set;
134.51 +import java.util.prefs.Preferences;
134.52 +import javax.swing.JComponent;
134.53 +import org.netbeans.modules.csl.api.Hint;
134.54 +import org.netbeans.modules.csl.api.HintFix;
134.55 +import org.netbeans.modules.csl.api.HintSeverity;
134.56 +import org.netbeans.modules.csl.api.OffsetRange;
134.57 +import org.netbeans.modules.csl.api.RuleContext;
134.58 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
134.59 +import org.netbeans.modules.python.source.PythonAstUtils;
134.60 +import org.netbeans.modules.python.source.PythonIndex;
134.61 +import org.netbeans.modules.python.source.PythonParserResult;
134.62 +import org.netbeans.modules.python.source.elements.IndexedElement;
134.63 +import org.netbeans.modules.python.source.ImportManager;
134.64 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
134.65 +import org.netbeans.modules.python.source.scopes.SymbolTable;
134.66 +import org.openide.util.NbBundle;
134.67 +import org.python.antlr.PythonTree;
134.68 +import org.python.antlr.ast.Attribute;
134.69 +import org.python.antlr.ast.Call;
134.70 +import org.python.antlr.ast.Module;
134.71 +
134.72 +/**
134.73 + * Detect Unresolved variables
134.74 + *
134.75 + * @author Tor Norbye
134.76 + */
134.77 +public class UnresolvedDetector extends PythonAstRule {
134.78 + public UnresolvedDetector() {
134.79 + }
134.80 +
134.81 + @Override
134.82 + public boolean appliesTo(RuleContext context) {
134.83 + return true;
134.84 + }
134.85 +
134.86 + @Override
134.87 + public Set<Class> getKinds() {
134.88 + return Collections.<Class>singleton(Module.class);
134.89 + }
134.90 +
134.91 + @Override
134.92 + public void run(PythonRuleContext context, List<Hint> result) {
134.93 + PythonParserResult info = (PythonParserResult) context.parserResult;
134.94 + SymbolTable symbolTable = info.getSymbolTable();
134.95 +
134.96 + List<PythonTree> unresolvedNames = symbolTable.getUnresolved(info);
134.97 + if (unresolvedNames.size() > 0) {
134.98 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
134.99 +
134.100 + for (PythonTree node : unresolvedNames) {
134.101 + // Compute suggestions
134.102 + String name = PythonAstUtils.getName(node);
134.103 + if (name == null) {
134.104 + name = "";
134.105 + }
134.106 + List<HintFix> fixList = new ArrayList<>(3);
134.107 + // Is is a reference to a module?
134.108 + boolean tryModule = false;
134.109 + if (node.getParent() instanceof Call) {
134.110 + Call call = (Call)node.getParent();
134.111 + PythonTree t = call.getInternalFunc();
134.112 + if (t instanceof Attribute) {
134.113 + tryModule = true;
134.114 + }
134.115 + }
134.116 + String message = NbBundle.getMessage(NameRule.class, "UnresolvedVariable", name);
134.117 + if (name.equals("true")) { // NOI18N
134.118 + // Help for new language converts...
134.119 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "True"); // NOI18N
134.120 + } else if (name.equals("false")) {
134.121 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "False"); // NOI18N
134.122 + } else if (name.equals("nil") || name.equals("null")) {
134.123 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "None"); // NOI18N
134.124 + } else if (name.equals("this")) {
134.125 + message = NbBundle.getMessage(NameRule.class, "UnresolvedVariableMaybe", name, "self"); // NOI18N
134.126 + } else if (tryModule) {
134.127 + Set<IndexedElement> moduleElements = index.getModules(name, QuerySupport.Kind.EXACT);
134.128 + if (moduleElements.size() > 0) {
134.129 + fixList.add(new ImportFix(context, node, name));
134.130 + }
134.131 + } else {
134.132 + Set<String> modules = index.getImportsFor(name, true);
134.133 + if (modules.size() > 0) {
134.134 + for (String module : modules) {
134.135 + fixList.add(new ImportFix(context, node, module));
134.136 + }
134.137 + }
134.138 + }
134.139 +
134.140 + OffsetRange range = PythonAstUtils.getNameRange(info, node);
134.141 + range = PythonLexerUtils.getLexerOffsets(info, range);
134.142 + if (range != OffsetRange.NONE) {
134.143 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
134.144 + result.add(desc);
134.145 + }
134.146 + }
134.147 + }
134.148 + }
134.149 +
134.150 + @Override
134.151 + public String getId() {
134.152 + return "Unresolved"; // NOI18N
134.153 + }
134.154 +
134.155 + @Override
134.156 + public String getDisplayName() {
134.157 + return NbBundle.getMessage(NameRule.class, "Unresolved");
134.158 + }
134.159 +
134.160 + @Override
134.161 + public String getDescription() {
134.162 + return NbBundle.getMessage(NameRule.class, "UnresolvedDesc");
134.163 + }
134.164 +
134.165 + @Override
134.166 + public boolean getDefaultEnabled() {
134.167 + return false;
134.168 + }
134.169 +
134.170 + @Override
134.171 + public boolean showInTasklist() {
134.172 + return true;
134.173 + }
134.174 +
134.175 + @Override
134.176 + public HintSeverity getDefaultSeverity() {
134.177 + return HintSeverity.ERROR;
134.178 + }
134.179 +
134.180 + @Override
134.181 + public JComponent getCustomizer(Preferences node) {
134.182 + return null;
134.183 + }
134.184 +
134.185 + private static class ImportFix implements HintFix {
134.186 + private final PythonRuleContext context;
134.187 + private final PythonTree node;
134.188 + private final String module;
134.189 +
134.190 + private ImportFix(PythonRuleContext context, PythonTree node, String module) {
134.191 + this.context = context;
134.192 + this.node = node;
134.193 + this.module = module;
134.194 + }
134.195 +
134.196 + @Override
134.197 + public String getDescription() {
134.198 + return NbBundle.getMessage(CreateDocString.class, "FixImport", module);
134.199 + }
134.200 +
134.201 + @Override
134.202 + public void implement() throws Exception {
134.203 + String mod = this.module;
134.204 + String symbol = null;
134.205 + int colon = mod.indexOf(':');
134.206 + if (colon != -1) {
134.207 + int end = mod.indexOf('(', colon + 1);
134.208 + if (end == -1) {
134.209 + end = mod.indexOf(';', colon + 1);
134.210 + if (end == -1) {
134.211 + end = mod.length();
134.212 + }
134.213 + }
134.214 + symbol = mod.substring(colon + 1, end).trim();
134.215 + mod = mod.substring(0, colon).trim();
134.216 + }
134.217 + new ImportManager((PythonParserResult) context.parserResult).ensureImported(mod, symbol, false, false, true);
134.218 + }
134.219 +
134.220 + @Override
134.221 + public boolean isSafe() {
134.222 + return true;
134.223 + }
134.224 +
134.225 + @Override
134.226 + public boolean isInteractive() {
134.227 + return false;
134.228 + }
134.229 + }
134.230 +}
135.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
135.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedDetector.java Wed Sep 02 20:31:18 2015 +0200
135.3 @@ -0,0 +1,244 @@
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.HashSet;
135.50 +import java.util.List;
135.51 +import java.util.Set;
135.52 +import java.util.prefs.Preferences;
135.53 +import javax.swing.JComponent;
135.54 +import org.netbeans.modules.csl.api.Hint;
135.55 +import org.netbeans.modules.csl.api.HintFix;
135.56 +import org.netbeans.modules.csl.api.HintSeverity;
135.57 +import org.netbeans.modules.csl.api.OffsetRange;
135.58 +import org.netbeans.modules.csl.api.RuleContext;
135.59 +import org.netbeans.modules.python.source.PythonAstUtils;
135.60 +import org.netbeans.modules.python.source.PythonParserResult;
135.61 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
135.62 +import org.netbeans.modules.python.source.scopes.SymbolTable;
135.63 +import org.openide.util.NbBundle;
135.64 +import org.python.antlr.PythonTree;
135.65 +import org.python.antlr.ast.Assign;
135.66 +import org.python.antlr.ast.For;
135.67 +import org.python.antlr.ast.Module;
135.68 +import org.python.antlr.ast.Tuple;
135.69 +import org.python.antlr.base.expr;
135.70 +
135.71 +/**
135.72 + * Detect unused variables
135.73 + *
135.74 + * @todo Find a more reliable way of detecting return tuples without relying on the
135.75 + * parent reference
135.76 + *
135.77 + * @author Tor Norbye
135.78 + */
135.79 +public class UnusedDetector extends PythonAstRule {
135.80 + /** Default names ignored */
135.81 + private static final String DEFAULT_IGNORED_NAMES = "_, dummy";
135.82 + private static final String PARAMS_KEY = "params"; // NOI18N
135.83 + private static final String SKIP_TUPLE_ASSIGN_KEY = "skipTuples"; // NOI18N
135.84 + private static final String IGNORED_KEY = "ignorednames"; // NOI18N
135.85 +
135.86 + public UnusedDetector() {
135.87 + }
135.88 +
135.89 + @Override
135.90 + public boolean appliesTo(RuleContext context) {
135.91 + return true;
135.92 + }
135.93 +
135.94 + @Override
135.95 + public Set<Class> getKinds() {
135.96 + return Collections.<Class>singleton(Module.class);
135.97 + }
135.98 +
135.99 + @Override
135.100 + public void run(PythonRuleContext context, List<Hint> result) {
135.101 + PythonParserResult info = (PythonParserResult) context.parserResult;
135.102 + SymbolTable symbolTable = info.getSymbolTable();
135.103 +
135.104 + boolean skipParams = true;
135.105 + Preferences pref = context.manager.getPreferences(this);
135.106 + if (pref != null) {
135.107 + skipParams = getSkipParameters(pref);
135.108 + }
135.109 +
135.110 + List<PythonTree> unusedNames = symbolTable.getUnused(true, skipParams);
135.111 + if (unusedNames.size() == 0) {
135.112 + return;
135.113 + }
135.114 +
135.115 + boolean skipTupleAssigns = true;
135.116 + Set<String> ignoreNames = Collections.emptySet();
135.117 + if (pref != null) {
135.118 + skipParams = getSkipParameters(pref);
135.119 + skipTupleAssigns = getSkipTupleAssignments(pref);
135.120 + String ignoreNamesStr = getIgnoreNames(pref);
135.121 + if (ignoreNamesStr.length() > 0) {
135.122 + ignoreNames = new HashSet<>();
135.123 + for (String s : ignoreNamesStr.split(",")) { // NOI18N
135.124 + ignoreNames.add(s.trim());
135.125 + }
135.126 + }
135.127 + }
135.128 +
135.129 + for (PythonTree node : unusedNames) {
135.130 + if (skipTupleAssigns && isTupleAssignment(node)) {
135.131 + continue;
135.132 + }
135.133 + String name = PythonAstUtils.getName(node);
135.134 + if (name == null) {
135.135 + name = "";
135.136 + }
135.137 + if (ignoreNames.contains(name)) {
135.138 + continue;
135.139 + }
135.140 + OffsetRange range = PythonAstUtils.getNameRange(info, node);
135.141 + range = PythonLexerUtils.getLexerOffsets(info, range);
135.142 + if (range != OffsetRange.NONE) {
135.143 + List<HintFix> fixList = new ArrayList<>(3);
135.144 + String message = NbBundle.getMessage(NameRule.class, "UnusedVariable", name);
135.145 + Hint desc = new Hint(this, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2305);
135.146 + result.add(desc);
135.147 + }
135.148 + }
135.149 + }
135.150 +
135.151 + private boolean isTupleAssignment(PythonTree node) {
135.152 + // This may not work right since the parent pointers often aren't set right;
135.153 + // find a more efficient way to do it correctly than a path search for each node
135.154 + if (node.getParent() instanceof Tuple) {
135.155 + // Allow tuples in tuples
135.156 + PythonTree parentParent = node.getParent().getParent();
135.157 + while (parentParent instanceof Tuple) {
135.158 + parentParent = parentParent.getParent();
135.159 + node = node.getParent();
135.160 + }
135.161 + if (parentParent instanceof Assign) {
135.162 + Assign assign = (Assign)parentParent;
135.163 + List<expr> targets = assign.getInternalTargets();
135.164 + if (targets != null && targets.size() > 0 && targets.get(0) == node.getParent()) {
135.165 + return true;
135.166 + }
135.167 + }
135.168 + if (parentParent instanceof For &&
135.169 + ((For)parentParent).getInternalTarget() == node.getParent()) {
135.170 + return true;
135.171 + }
135.172 + }
135.173 +
135.174 + return false;
135.175 + }
135.176 +
135.177 + @Override
135.178 + public String getId() {
135.179 + return "Unused"; // NOI18N
135.180 + }
135.181 +
135.182 + @Override
135.183 + public String getDisplayName() {
135.184 + return NbBundle.getMessage(NameRule.class, "Unused");
135.185 + }
135.186 +
135.187 + @Override
135.188 + public String getDescription() {
135.189 + return NbBundle.getMessage(NameRule.class, "UnusedDesc");
135.190 + }
135.191 +
135.192 + @Override
135.193 + public boolean getDefaultEnabled() {
135.194 + return true;
135.195 + }
135.196 +
135.197 + @Override
135.198 + public boolean showInTasklist() {
135.199 + return true;
135.200 + }
135.201 +
135.202 + @Override
135.203 + public HintSeverity getDefaultSeverity() {
135.204 + return HintSeverity.WARNING;
135.205 + }
135.206 +
135.207 + @Override
135.208 + public JComponent getCustomizer(Preferences node) {
135.209 + return new UnusedDetectorPrefs(node);
135.210 + }
135.211 +
135.212 + static boolean getSkipParameters(Preferences prefs) {
135.213 + return prefs.getBoolean(PARAMS_KEY, true);
135.214 + }
135.215 +
135.216 + static void setSkipParameters(Preferences prefs, boolean skipParams) {
135.217 + if (skipParams) {
135.218 + prefs.remove(PARAMS_KEY);
135.219 + } else {
135.220 + prefs.putBoolean(PARAMS_KEY, false);
135.221 + }
135.222 + }
135.223 +
135.224 + static boolean getSkipTupleAssignments(Preferences prefs) {
135.225 + return prefs.getBoolean(SKIP_TUPLE_ASSIGN_KEY, true);
135.226 + }
135.227 +
135.228 + static void setSkipTupleAssignments(Preferences prefs, boolean skipTupleAssigns) {
135.229 + if (skipTupleAssigns) {
135.230 + prefs.remove(SKIP_TUPLE_ASSIGN_KEY);
135.231 + } else {
135.232 + prefs.putBoolean(SKIP_TUPLE_ASSIGN_KEY, false);
135.233 + }
135.234 + }
135.235 +
135.236 + static String getIgnoreNames(Preferences prefs) {
135.237 + return prefs.get(IGNORED_KEY, DEFAULT_IGNORED_NAMES);
135.238 + }
135.239 +
135.240 + static void setIgnoreNames(Preferences prefs, String ignoredNames) {
135.241 + if (ignoredNames.length() == 0) {
135.242 + prefs.remove(IGNORED_KEY);
135.243 + } else {
135.244 + prefs.put(IGNORED_KEY, ignoredNames);
135.245 + }
135.246 + }
135.247 +}
136.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
136.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedDetectorPrefs.form Wed Sep 02 20:31:18 2015 +0200
136.3 @@ -0,0 +1,84 @@
136.4 +<?xml version="1.0" encoding="UTF-8" ?>
136.5 +
136.6 +<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
136.7 + <AuxValues>
136.8 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
136.9 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
136.10 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
136.11 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
136.12 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
136.13 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
136.14 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="2"/>
136.15 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
136.16 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
136.17 + </AuxValues>
136.18 +
136.19 + <Layout>
136.20 + <DimensionLayout dim="0">
136.21 + <Group type="103" groupAlignment="0" attributes="0">
136.22 + <Component id="skipParams" min="-2" max="-2" attributes="0"/>
136.23 + <Component id="skipTupleAssignments" alignment="0" min="-2" max="-2" attributes="0"/>
136.24 + <Group type="102" alignment="0" attributes="0">
136.25 + <Component id="ignoredLabel" min="-2" max="-2" attributes="0"/>
136.26 + <EmptySpace max="-2" attributes="0"/>
136.27 + <Component id="ignoredNames" min="-2" max="-2" attributes="0"/>
136.28 + </Group>
136.29 + </Group>
136.30 + </DimensionLayout>
136.31 + <DimensionLayout dim="1">
136.32 + <Group type="103" groupAlignment="0" attributes="0">
136.33 + <Group type="102" attributes="0">
136.34 + <Component id="skipParams" min="-2" max="-2" attributes="0"/>
136.35 + <EmptySpace max="-2" attributes="0"/>
136.36 + <Component id="skipTupleAssignments" min="-2" max="-2" attributes="0"/>
136.37 + <EmptySpace max="-2" attributes="0"/>
136.38 + <Group type="103" groupAlignment="3" attributes="0">
136.39 + <Component id="ignoredLabel" alignment="3" min="-2" max="-2" attributes="0"/>
136.40 + <Component id="ignoredNames" alignment="3" min="-2" max="-2" attributes="0"/>
136.41 + </Group>
136.42 + <EmptySpace max="32767" attributes="0"/>
136.43 + </Group>
136.44 + </Group>
136.45 + </DimensionLayout>
136.46 + </Layout>
136.47 + <SubComponents>
136.48 + <Component class="javax.swing.JCheckBox" name="skipParams">
136.49 + <Properties>
136.50 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
136.51 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.skipParams.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
136.52 + </Property>
136.53 + </Properties>
136.54 + <Events>
136.55 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
136.56 + </Events>
136.57 + </Component>
136.58 + <Component class="javax.swing.JCheckBox" name="skipTupleAssignments">
136.59 + <Properties>
136.60 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
136.61 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.skipTupleAssignments.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
136.62 + </Property>
136.63 + </Properties>
136.64 + <Events>
136.65 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
136.66 + </Events>
136.67 + </Component>
136.68 + <Component class="javax.swing.JTextField" name="ignoredNames">
136.69 + <Properties>
136.70 + <Property name="columns" type="int" value="25"/>
136.71 + </Properties>
136.72 + <Events>
136.73 + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="changed"/>
136.74 + </Events>
136.75 + </Component>
136.76 + <Component class="javax.swing.JLabel" name="ignoredLabel">
136.77 + <Properties>
136.78 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
136.79 + <ComponentRef name="ignoredNames"/>
136.80 + </Property>
136.81 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
136.82 + <ResourceString bundle="org/netbeans/modules/python/editor/hints/Bundle.properties" key="UnusedDetectorPrefs.ignoredLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
136.83 + </Property>
136.84 + </Properties>
136.85 + </Component>
136.86 + </SubComponents>
136.87 +</Form>
137.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
137.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedDetectorPrefs.java Wed Sep 02 20:31:18 2015 +0200
137.3 @@ -0,0 +1,152 @@
137.4 +/*
137.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
137.6 + *
137.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
137.8 + *
137.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
137.10 + * Other names may be trademarks of their respective owners.
137.11 + *
137.12 + * The contents of this file are subject to the terms of either the GNU
137.13 + * General Public License Version 2 only ("GPL") or the Common
137.14 + * Development and Distribution License("CDDL") (collectively, the
137.15 + * "License"). You may not use this file except in compliance with the
137.16 + * License. You can obtain a copy of the License at
137.17 + * http://www.netbeans.org/cddl-gplv2.html
137.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
137.19 + * specific language governing permissions and limitations under the
137.20 + * License. When distributing the software, include this License Header
137.21 + * Notice in each file and include the License file at
137.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
137.23 + * particular file as subject to the "Classpath" exception as provided
137.24 + * by Oracle in the GPL Version 2 section of the License file that
137.25 + * accompanied this code. If applicable, add the following below the
137.26 + * License Header, with the fields enclosed by brackets [] replaced by
137.27 + * your own identifying information:
137.28 + * "Portions Copyrighted [year] [name of copyright owner]"
137.29 + *
137.30 + * If you wish your version of this file to be governed by only the CDDL
137.31 + * or only the GPL Version 2, indicate your decision by adding
137.32 + * "[Contributor] elects to include this software in this distribution
137.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
137.34 + * single choice of license, a recipient has the option to distribute
137.35 + * your version of this file under either the CDDL, the GPL Version 2 or
137.36 + * to extend the choice of license to its licensees as provided above.
137.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
137.38 + * Version 2 license, then the option applies only if the new code is
137.39 + * made subject to such option by the copyright holder.
137.40 + *
137.41 + * Contributor(s):
137.42 + *
137.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
137.44 + */
137.45 +
137.46 +/*
137.47 + * UnusedDetectorPrefs.java
137.48 + *
137.49 + * Created on Nov 10, 2008, 9:48:35 AM
137.50 + */
137.51 +package org.netbeans.modules.python.hints;
137.52 +
137.53 +import java.awt.event.ActionListener;
137.54 +import java.util.prefs.Preferences;
137.55 +
137.56 +/**
137.57 + * Preferences where users can configure the unused detector rules
137.58 + *
137.59 + * @author Tor Norbye
137.60 + */
137.61 +public class UnusedDetectorPrefs extends javax.swing.JPanel implements ActionListener {
137.62 + private Preferences prefs;
137.63 +
137.64 + /** Creates new form UnusedDetectorPrefs */
137.65 + public UnusedDetectorPrefs(Preferences prefs) {
137.66 + initComponents();
137.67 + this.prefs = prefs;
137.68 + skipParams.setSelected(UnusedDetector.getSkipParameters(prefs));
137.69 + skipTupleAssignments.setSelected(UnusedDetector.getSkipTupleAssignments(prefs));
137.70 + String ignore = UnusedDetector.getIgnoreNames(prefs);
137.71 + if (ignore == null) {
137.72 + ignore = "";
137.73 + }
137.74 + ignoredNames.setText(ignore);
137.75 + }
137.76 +
137.77 + @SuppressWarnings("unchecked")
137.78 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
137.79 + private void initComponents() {
137.80 +
137.81 + skipParams = new javax.swing.JCheckBox();
137.82 + skipTupleAssignments = new javax.swing.JCheckBox();
137.83 + ignoredNames = new javax.swing.JTextField();
137.84 + ignoredLabel = new javax.swing.JLabel();
137.85 +
137.86 + skipParams.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.skipParams.text")); // NOI18N
137.87 + skipParams.addActionListener(this);
137.88 +
137.89 + skipTupleAssignments.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.skipTupleAssignments.text")); // NOI18N
137.90 + skipTupleAssignments.addActionListener(this);
137.91 +
137.92 + ignoredNames.setColumns(25);
137.93 + ignoredNames.addActionListener(this);
137.94 +
137.95 + ignoredLabel.setLabelFor(ignoredNames);
137.96 + ignoredLabel.setText(org.openide.util.NbBundle.getMessage(UnusedDetectorPrefs.class, "UnusedDetectorPrefs.ignoredLabel.text")); // NOI18N
137.97 +
137.98 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
137.99 + this.setLayout(layout);
137.100 + layout.setHorizontalGroup(
137.101 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
137.102 + .addComponent(skipParams)
137.103 + .addComponent(skipTupleAssignments)
137.104 + .addGroup(layout.createSequentialGroup()
137.105 + .addComponent(ignoredLabel)
137.106 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
137.107 + .addComponent(ignoredNames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
137.108 + );
137.109 + layout.setVerticalGroup(
137.110 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
137.111 + .addGroup(layout.createSequentialGroup()
137.112 + .addComponent(skipParams)
137.113 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
137.114 + .addComponent(skipTupleAssignments)
137.115 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
137.116 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
137.117 + .addComponent(ignoredLabel)
137.118 + .addComponent(ignoredNames, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
137.119 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
137.120 + );
137.121 + }
137.122 +
137.123 + // Code for dispatching events from components to event handlers.
137.124 +
137.125 + public void actionPerformed(java.awt.event.ActionEvent evt) {
137.126 + if (evt.getSource() == skipParams) {
137.127 + UnusedDetectorPrefs.this.changed(evt);
137.128 + }
137.129 + else if (evt.getSource() == skipTupleAssignments) {
137.130 + UnusedDetectorPrefs.this.changed(evt);
137.131 + }
137.132 + else if (evt.getSource() == ignoredNames) {
137.133 + UnusedDetectorPrefs.this.changed(evt);
137.134 + }
137.135 + }// </editor-fold>//GEN-END:initComponents
137.136 +
137.137 + private void changed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changed
137.138 + Object source = evt.getSource();
137.139 + if (source == ignoredNames) {
137.140 + UnusedDetector.setIgnoreNames(prefs, ignoredNames.getText().trim());
137.141 + } else if (source == skipParams) {
137.142 + UnusedDetector.setSkipParameters(prefs, skipParams.isSelected());
137.143 + } else if (source == skipTupleAssignments) {
137.144 + UnusedDetector.setSkipTupleAssignments(prefs, skipTupleAssignments.isSelected());
137.145 + } else {
137.146 + assert false : source;
137.147 + }
137.148 + }//GEN-LAST:event_changed
137.149 + // Variables declaration - do not modify//GEN-BEGIN:variables
137.150 + private javax.swing.JLabel ignoredLabel;
137.151 + private javax.swing.JTextField ignoredNames;
137.152 + private javax.swing.JCheckBox skipParams;
137.153 + private javax.swing.JCheckBox skipTupleAssignments;
137.154 + // End of variables declaration//GEN-END:variables
137.155 +}
138.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
138.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/UnusedImports.java Wed Sep 02 20:31:18 2015 +0200
138.3 @@ -0,0 +1,286 @@
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 +package org.netbeans.modules.python.hints;
138.46 +
138.47 +import java.util.ArrayList;
138.48 +import java.util.Collections;
138.49 +import java.util.HashMap;
138.50 +import java.util.List;
138.51 +import java.util.Map;
138.52 +import java.util.Set;
138.53 +import java.util.prefs.Preferences;
138.54 +import javax.swing.JComponent;
138.55 +import org.netbeans.editor.BaseDocument;
138.56 +import org.netbeans.modules.csl.api.EditList;
138.57 +import org.netbeans.modules.csl.api.Hint;
138.58 +import org.netbeans.modules.csl.api.HintFix;
138.59 +import org.netbeans.modules.csl.api.HintSeverity;
138.60 +import org.netbeans.modules.csl.api.OffsetRange;
138.61 +import org.netbeans.modules.csl.api.RuleContext;
138.62 +import org.netbeans.modules.python.source.PythonAstUtils;
138.63 +import org.netbeans.modules.python.source.PythonParserResult;
138.64 +import org.netbeans.modules.python.source.ImportEntry;
138.65 +import org.netbeans.modules.python.source.ImportManager;
138.66 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
138.67 +import org.netbeans.modules.python.source.scopes.SymbolTable;
138.68 +import org.openide.filesystems.FileObject;
138.69 +import org.openide.util.NbBundle;
138.70 +import org.python.antlr.PythonTree;
138.71 +import org.python.antlr.ast.Import;
138.72 +import org.python.antlr.ast.ImportFrom;
138.73 +import org.python.antlr.ast.Module;
138.74 +import org.python.antlr.ast.alias;
138.75 +
138.76 +/**
138.77 + * Detect unused imports
138.78 + *
138.79 + * @author Tor Norbye
138.80 + */
138.81 +public class UnusedImports extends PythonAstRule {
138.82 + public UnusedImports() {
138.83 + }
138.84 +
138.85 + @Override
138.86 + public boolean appliesTo(RuleContext context) {
138.87 + FileObject fo = context.parserResult.getSnapshot().getSource().getFileObject();
138.88 + return fo == null || !fo.getName().equals("__init__"); // NOI18N
138.89 + }
138.90 +
138.91 + @Override
138.92 + public Set<Class> getKinds() {
138.93 + return Collections.<Class>singleton(Module.class);
138.94 + }
138.95 +
138.96 + @Override
138.97 + public void run(PythonRuleContext context, List<Hint> result) {
138.98 + computeUnusedImports(this, context, result, null);
138.99 + }
138.100 +
138.101 + private static void computeUnusedImports(UnusedImports detector, PythonRuleContext context, List<Hint> result, Map<PythonTree, List<String>> unused) {
138.102 + assert result == null || unused == null; // compute either results or set of unused
138.103 +
138.104 + PythonParserResult info = (PythonParserResult) context.parserResult;
138.105 + SymbolTable symbolTable = info.getSymbolTable();
138.106 + List<ImportEntry> unusedImports = symbolTable.getUnusedImports();
138.107 + if (unusedImports.isEmpty()) {
138.108 + return;
138.109 + }
138.110 + Map<PythonTree, List<String>> maps = new HashMap<>();
138.111 + for (ImportEntry entry : unusedImports) {
138.112 + maps.put(entry.node, new ArrayList<String>());
138.113 + }
138.114 + for (ImportEntry entry : unusedImports) {
138.115 + if (entry.isFromImport) {
138.116 + String name = entry.asName != null ? entry.asName : entry.symbol;
138.117 + maps.get(entry.node).add(name);
138.118 + } else {
138.119 + String name = entry.asName != null ? entry.asName : entry.module;
138.120 + maps.get(entry.node).add(name);
138.121 + }
138.122 + }
138.123 + for (Map.Entry<PythonTree, List<String>> entry : maps.entrySet()) {
138.124 + PythonTree node = entry.getKey();
138.125 + List<String> list = entry.getValue();
138.126 + if (node instanceof Import) {
138.127 + Import imp = (Import)node;
138.128 + List<alias> names = imp.getInternalNames();
138.129 + if (names != null && names.size() == list.size()) {
138.130 + list.clear();
138.131 + }
138.132 + } else {
138.133 + assert node instanceof ImportFrom;
138.134 + ImportFrom imp = (ImportFrom)node;
138.135 + List<alias> names = imp.getInternalNames();
138.136 + if (names != null && names.size() == list.size()) {
138.137 + list.clear();
138.138 + }
138.139 + }
138.140 + }
138.141 +
138.142 + for (Map.Entry<PythonTree, List<String>> entry : maps.entrySet()) {
138.143 + PythonTree node = entry.getKey();
138.144 + List<String> list = entry.getValue();
138.145 + if (list.size() == 0) {
138.146 + list = null;
138.147 + }
138.148 + if (unused != null) {
138.149 + unused.put(node, list);
138.150 + } else {
138.151 + addError(detector, context, node, list, result);
138.152 + }
138.153 + }
138.154 + }
138.155 +
138.156 + private static void addError(UnusedImports detector, PythonRuleContext context, PythonTree node, List<String> symbols, List<Hint> result) {
138.157 + PythonParserResult info = (PythonParserResult) context.parserResult;
138.158 + OffsetRange range = PythonAstUtils.getNameRange(info, node);
138.159 + range = PythonLexerUtils.getLexerOffsets(info, range);
138.160 + if (range != OffsetRange.NONE) {
138.161 + List<HintFix> fixList = new ArrayList<>(3);
138.162 + fixList.add(new UnusedFix(detector, context, node, symbols, false));
138.163 + fixList.add(new UnusedFix(detector, context, null, null, false)); // Remove All
138.164 + fixList.add(new UnusedFix(detector, context, null, null, true)); // Organize
138.165 + String message;
138.166 + if (symbols != null) {
138.167 + message = NbBundle.getMessage(NameRule.class, "UnusedImportSymbols", symbols);
138.168 + } else {
138.169 + message = NbBundle.getMessage(NameRule.class, "UnusedImport");
138.170 + }
138.171 + Hint desc = new Hint(detector, message, info.getSnapshot().getSource().getFileObject(), range, fixList, 2500);
138.172 + result.add(desc);
138.173 + }
138.174 + }
138.175 +
138.176 + @Override
138.177 + public String getId() {
138.178 + return "UnusedImports"; // NOI18N
138.179 + }
138.180 +
138.181 + @Override
138.182 + public String getDisplayName() {
138.183 + return NbBundle.getMessage(NameRule.class, "UnusedImports");
138.184 + }
138.185 +
138.186 + @Override
138.187 + public String getDescription() {
138.188 + return NbBundle.getMessage(NameRule.class, "UnusedImportsDesc");
138.189 + }
138.190 +
138.191 + @Override
138.192 + public boolean getDefaultEnabled() {
138.193 + return true;
138.194 + }
138.195 +
138.196 + @Override
138.197 + public boolean showInTasklist() {
138.198 + return false; // ? or maybe yes?
138.199 + }
138.200 +
138.201 + @Override
138.202 + public HintSeverity getDefaultSeverity() {
138.203 + return HintSeverity.WARNING;
138.204 + }
138.205 +
138.206 + @Override
138.207 + public JComponent getCustomizer(Preferences node) {
138.208 + return null;
138.209 + }
138.210 +
138.211 + /**
138.212 + * Fix to insert self argument or rename first argument to self
138.213 + */
138.214 + private static class UnusedFix implements /*PreviewableFix*/ HintFix { // Preview not particularly helpful and clutters menu
138.215 + private final UnusedImports detector;
138.216 + private final PythonRuleContext context;
138.217 + private final PythonTree node;
138.218 + private final List<String> symbols;
138.219 + private final boolean organizeOnly;
138.220 +
138.221 + private UnusedFix(UnusedImports detector, PythonRuleContext context, PythonTree node, List<String> symbols, boolean organizeOnly) {
138.222 + this.detector = detector;
138.223 + this.context = context;
138.224 + this.node = node;
138.225 + this.symbols = symbols;
138.226 + this.organizeOnly = organizeOnly;
138.227 + }
138.228 +
138.229 + @Override
138.230 + public String getDescription() {
138.231 + if (node == null) {
138.232 + if (organizeOnly) {
138.233 + return NbBundle.getMessage(CreateDocString.class, "OrganizeImports");
138.234 + } else {
138.235 + return NbBundle.getMessage(CreateDocString.class, "DeleteAllUnused");
138.236 + }
138.237 + } else if (symbols != null) {
138.238 + return NbBundle.getMessage(CreateDocString.class, "UnusedFixSymbols", symbols);
138.239 + } else {
138.240 + return NbBundle.getMessage(CreateDocString.class, "UnusedFix");
138.241 + }
138.242 + }
138.243 +
138.244 + public boolean canPreview() {
138.245 + return true;
138.246 + }
138.247 +
138.248 + public EditList getEditList() throws Exception {
138.249 + BaseDocument doc = context.doc;
138.250 + EditList edits = new EditList(doc);
138.251 +
138.252 + ImportManager importManager = new ImportManager((PythonParserResult) context.parserResult);
138.253 +
138.254 + if (node == null) {
138.255 + if (organizeOnly) {
138.256 + importManager.cleanup(edits, 0, doc.getLength(), true);
138.257 + } else {
138.258 + Map<PythonTree, List<String>> onlyNames = new HashMap<>();
138.259 + computeUnusedImports(detector, context, null, onlyNames);
138.260 + Set<PythonTree> candidates = onlyNames.keySet();
138.261 + importManager.removeImports(edits, candidates, false, onlyNames);
138.262 + }
138.263 + } else {
138.264 + Set<PythonTree> candidates = Collections.singleton(node);
138.265 + Map<PythonTree, List<String>> onlyNames = new HashMap<>();
138.266 + onlyNames.put(node, symbols);
138.267 + importManager.removeImports(edits, candidates, false, onlyNames);
138.268 + }
138.269 +
138.270 + return edits;
138.271 + }
138.272 +
138.273 + @Override
138.274 + public void implement() throws Exception {
138.275 + EditList edits = getEditList();
138.276 + edits.apply();
138.277 + }
138.278 +
138.279 + @Override
138.280 + public boolean isSafe() {
138.281 + return true;
138.282 + }
138.283 +
138.284 + @Override
138.285 + public boolean isInteractive() {
138.286 + return false;
138.287 + }
138.288 + }
138.289 +}
139.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
139.2 +++ b/python.hints/src/org/netbeans/modules/python/hints/layer.xml Wed Sep 02 20:31:18 2015 +0200
139.3 @@ -0,0 +1,61 @@
139.4 +<?xml version="1.0" encoding="UTF-8"?>
139.5 +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
139.6 +<filesystem>
139.7 +
139.8 + <folder name="csl-hints">
139.9 + <folder name="text">
139.10 + <folder name="x-python">
139.11 + <folder name="hints">
139.12 + <folder name="general">
139.13 + <attr name="position" intvalue="100"/>
139.14 + <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.python.editor.hints.Bundle"/>
139.15 + <file name="org-netbeans-modules-python-hints-NameRule.instance"/>
139.16 + <file name="org-netbeans-modules-python-hints-CreateDocString.instance"/>
139.17 + <file name="org-netbeans-modules-python-hints-AssignToVariable.instance"/>
139.18 + <file name="org-netbeans-modules-python-hints-SplitImports.instance"/>
139.19 + <file name="org-netbeans-modules-python-hints-RelativeImports.instance"/>
139.20 + <file name="org-netbeans-modules-python-hints-Deprecations.instance"/>
139.21 + <file name="org-netbeans-modules-python-hints-UnusedImports.instance"/>
139.22 + <file name="org-netbeans-modules-python-hints-UnusedDetector.instance"/>
139.23 + <file name="org-netbeans-modules-python-hints-UnresolvedDetector.instance"/>
139.24 + <file name="org-netbeans-modules-python-hints-UnresolvedClassComponents.instance"/>
139.25 + <file name="org-netbeans-modules-python-hints-AllAssignExists.instance"/>
139.26 + <file name="org-netbeans-modules-python-hints-AccessToProtected.instance"/>
139.27 + <file name="org-netbeans-modules-python-hints-AttributeDefinedOutsideInit.instance"/>
139.28 + <file name="org-netbeans-modules-python-hints-ClassCircularRedundancy.instance"/>
139.29 + </folder>
139.30 + </folder>
139.31 + <folder name="selection">
139.32 + <file name="org-netbeans-modules-python-editor-hints-SurroundWith.instance"/>
139.33 + <file name="org-netbeans-modules-python-editor-hints-ExtractCode.instance"/>
139.34 + </folder>
139.35 + </folder>
139.36 + </folder>
139.37 + </folder>
139.38 +
139.39 + <folder name="CslPlugins">
139.40 + <folder name="text">
139.41 + <folder name="x-python">
139.42 + <file name="hints.instance">
139.43 + <attr name="instanceClass" stringvalue="org.netbeans.modules.python.hints.PythonHintsProvider"/>
139.44 + </file>
139.45 + </folder>
139.46 + </folder>
139.47 + </folder>
139.48 +
139.49 + <folder name="OptionsDialog">
139.50 + <folder name="Editor">
139.51 + <folder name="Hints">
139.52 + <attr name="position" intvalue="0"/>
139.53 + <folder name="text">
139.54 + <folder name="x-python">
139.55 + <file name="PythonHints.instance">
139.56 + <attr name="instanceOf" stringvalue="org.netbeans.spi.options.OptionsPanelController"/>
139.57 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.hints.PythonHintOptions.createStatic"/>
139.58 + </file>
139.59 + </folder>
139.60 + </folder>
139.61 + </folder>
139.62 + </folder>
139.63 + </folder>
139.64 +</filesystem>
140.1 --- a/python.project/src/org/netbeans/modules/python/project/GotoTest.java Mon Aug 31 12:40:19 2015 +0200
140.2 +++ b/python.project/src/org/netbeans/modules/python/project/GotoTest.java Wed Sep 02 20:31:18 2015 +0200
140.3 @@ -48,7 +48,7 @@
140.4 import java.util.regex.Pattern;
140.5
140.6
140.7 -import org.netbeans.modules.python.editor.PythonUtils;
140.8 +import org.netbeans.modules.python.source.PythonUtils;
140.9 import org.netbeans.spi.gototest.TestLocator;
140.10 import org.netbeans.spi.gototest.TestLocator.LocationResult;
140.11 import org.openide.filesystems.FileObject;
141.1 --- a/python.source/manifest.mf Mon Aug 31 12:40:19 2015 +0200
141.2 +++ b/python.source/manifest.mf Wed Sep 02 20:31:18 2015 +0200
141.3 @@ -1,5 +1,6 @@
141.4 Manifest-Version: 1.0
141.5 OpenIDE-Module: org.netbeans.modules.python.source
141.6 +OpenIDE-Module-Layer: org/netbeans/modules/python/source/layer.xml
141.7 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/python/source/Bundle.properties
141.8 -OpenIDE-Module-Specification-Version: 1.0
141.9 +OpenIDE-Module-Specification-Version: 1.1
141.10 AutoUpdate-Show-In-Client: false
142.1 --- a/python.source/nbproject/project.xml Mon Aug 31 12:40:19 2015 +0200
142.2 +++ b/python.source/nbproject/project.xml Wed Sep 02 20:31:18 2015 +0200
142.3 @@ -7,6 +7,15 @@
142.4 <!--<suite-component/>-->
142.5 <module-dependencies>
142.6 <dependency>
142.7 + <code-name-base>org.jython</code-name-base>
142.8 + <build-prerequisite/>
142.9 + <compile-dependency/>
142.10 + <run-dependency>
142.11 + <release-version>2</release-version>
142.12 + <specification-version>2.12</specification-version>
142.13 + </run-dependency>
142.14 + </dependency>
142.15 + <dependency>
142.16 <code-name-base>org.netbeans.api.annotations.common</code-name-base>
142.17 <build-prerequisite/>
142.18 <compile-dependency/>
142.19 @@ -16,6 +25,103 @@
142.20 </run-dependency>
142.21 </dependency>
142.22 <dependency>
142.23 + <code-name-base>org.netbeans.modules.csl.api</code-name-base>
142.24 + <build-prerequisite/>
142.25 + <compile-dependency/>
142.26 + <run-dependency>
142.27 + <release-version>2</release-version>
142.28 + <specification-version>2.51</specification-version>
142.29 + </run-dependency>
142.30 + </dependency>
142.31 + <dependency>
142.32 + <code-name-base>org.netbeans.modules.editor.document</code-name-base>
142.33 + <build-prerequisite/>
142.34 + <compile-dependency/>
142.35 + <run-dependency>
142.36 + <specification-version>1.5</specification-version>
142.37 + </run-dependency>
142.38 + </dependency>
142.39 + <dependency>
142.40 + <code-name-base>org.netbeans.modules.editor.indent</code-name-base>
142.41 + <build-prerequisite/>
142.42 + <compile-dependency/>
142.43 + <run-dependency>
142.44 + <release-version>2</release-version>
142.45 + <specification-version>1.42</specification-version>
142.46 + </run-dependency>
142.47 + </dependency>
142.48 + <dependency>
142.49 + <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
142.50 + <build-prerequisite/>
142.51 + <compile-dependency/>
142.52 + <run-dependency>
142.53 + <release-version>3</release-version>
142.54 + <specification-version>4.3</specification-version>
142.55 + </run-dependency>
142.56 + </dependency>
142.57 + <dependency>
142.58 + <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
142.59 + <build-prerequisite/>
142.60 + <compile-dependency/>
142.61 + <run-dependency>
142.62 + <release-version>1</release-version>
142.63 + <specification-version>2.3</specification-version>
142.64 + </run-dependency>
142.65 + </dependency>
142.66 + <dependency>
142.67 + <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
142.68 + <build-prerequisite/>
142.69 + <compile-dependency/>
142.70 + <run-dependency>
142.71 + <release-version>1</release-version>
142.72 + <specification-version>1.39</specification-version>
142.73 + </run-dependency>
142.74 + </dependency>
142.75 + <dependency>
142.76 + <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
142.77 + <build-prerequisite/>
142.78 + <compile-dependency/>
142.79 + <run-dependency>
142.80 + <release-version>1</release-version>
142.81 + <specification-version>1.55</specification-version>
142.82 + </run-dependency>
142.83 + </dependency>
142.84 + <dependency>
142.85 + <code-name-base>org.netbeans.modules.lexer</code-name-base>
142.86 + <build-prerequisite/>
142.87 + <compile-dependency/>
142.88 + <run-dependency>
142.89 + <release-version>2</release-version>
142.90 + <specification-version>1.62</specification-version>
142.91 + </run-dependency>
142.92 + </dependency>
142.93 + <dependency>
142.94 + <code-name-base>org.netbeans.modules.options.editor</code-name-base>
142.95 + <build-prerequisite/>
142.96 + <compile-dependency/>
142.97 + <run-dependency>
142.98 + <release-version>1</release-version>
142.99 + <specification-version>1.54</specification-version>
142.100 + </run-dependency>
142.101 + </dependency>
142.102 + <dependency>
142.103 + <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
142.104 + <build-prerequisite/>
142.105 + <compile-dependency/>
142.106 + <run-dependency>
142.107 + <release-version>1</release-version>
142.108 + <specification-version>9.5</specification-version>
142.109 + </run-dependency>
142.110 + </dependency>
142.111 + <dependency>
142.112 + <code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
142.113 + <build-prerequisite/>
142.114 + <compile-dependency/>
142.115 + <run-dependency>
142.116 + <specification-version>9.7</specification-version>
142.117 + </run-dependency>
142.118 + </dependency>
142.119 + <dependency>
142.120 <code-name-base>org.netbeans.modules.projectapi</code-name-base>
142.121 <build-prerequisite/>
142.122 <compile-dependency/>
142.123 @@ -25,6 +131,31 @@
142.124 </run-dependency>
142.125 </dependency>
142.126 <dependency>
142.127 + <code-name-base>org.netbeans.modules.python.core</code-name-base>
142.128 + <build-prerequisite/>
142.129 + <compile-dependency/>
142.130 + <run-dependency>
142.131 + <specification-version>1.4</specification-version>
142.132 + </run-dependency>
142.133 + </dependency>
142.134 + <dependency>
142.135 + <code-name-base>org.netbeans.modules.queries</code-name-base>
142.136 + <build-prerequisite/>
142.137 + <compile-dependency/>
142.138 + <run-dependency>
142.139 + <release-version>1</release-version>
142.140 + <specification-version>1.42</specification-version>
142.141 + </run-dependency>
142.142 + </dependency>
142.143 + <dependency>
142.144 + <code-name-base>org.openide.awt</code-name-base>
142.145 + <build-prerequisite/>
142.146 + <compile-dependency/>
142.147 + <run-dependency>
142.148 + <specification-version>7.65</specification-version>
142.149 + </run-dependency>
142.150 + </dependency>
142.151 + <dependency>
142.152 <code-name-base>org.openide.filesystems</code-name-base>
142.153 <build-prerequisite/>
142.154 <compile-dependency/>
142.155 @@ -49,6 +180,38 @@
142.156 </run-dependency>
142.157 </dependency>
142.158 <dependency>
142.159 + <code-name-base>org.openide.loaders</code-name-base>
142.160 + <build-prerequisite/>
142.161 + <compile-dependency/>
142.162 + <run-dependency>
142.163 + <specification-version>7.63</specification-version>
142.164 + </run-dependency>
142.165 + </dependency>
142.166 + <dependency>
142.167 + <code-name-base>org.openide.modules</code-name-base>
142.168 + <build-prerequisite/>
142.169 + <compile-dependency/>
142.170 + <run-dependency>
142.171 + <specification-version>7.47</specification-version>
142.172 + </run-dependency>
142.173 + </dependency>
142.174 + <dependency>
142.175 + <code-name-base>org.openide.nodes</code-name-base>
142.176 + <build-prerequisite/>
142.177 + <compile-dependency/>
142.178 + <run-dependency>
142.179 + <specification-version>7.42</specification-version>
142.180 + </run-dependency>
142.181 + </dependency>
142.182 + <dependency>
142.183 + <code-name-base>org.openide.text</code-name-base>
142.184 + <build-prerequisite/>
142.185 + <compile-dependency/>
142.186 + <run-dependency>
142.187 + <specification-version>6.66</specification-version>
142.188 + </run-dependency>
142.189 + </dependency>
142.190 + <dependency>
142.191 <code-name-base>org.openide.util</code-name-base>
142.192 <build-prerequisite/>
142.193 <compile-dependency/>
142.194 @@ -72,9 +235,21 @@
142.195 <specification-version>9.3</specification-version>
142.196 </run-dependency>
142.197 </dependency>
142.198 + <dependency>
142.199 + <code-name-base>org.openide.windows</code-name-base>
142.200 + <build-prerequisite/>
142.201 + <compile-dependency/>
142.202 + <run-dependency>
142.203 + <specification-version>6.74</specification-version>
142.204 + </run-dependency>
142.205 + </dependency>
142.206 </module-dependencies>
142.207 <public-packages>
142.208 + <package>org.netbeans.modules.python.source</package>
142.209 + <package>org.netbeans.modules.python.source.elements</package>
142.210 + <package>org.netbeans.modules.python.source.lexer</package>
142.211 <package>org.netbeans.modules.python.source.queries</package>
142.212 + <package>org.netbeans.modules.python.source.scopes</package>
142.213 </public-packages>
142.214 </data>
142.215 </configuration>
143.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
143.2 +++ b/python.source/src/org/netbeans/modules/python/source/AstPath.java Wed Sep 02 20:31:18 2015 +0200
143.3 @@ -0,0 +1,436 @@
143.4 +/*
143.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
143.6 + *
143.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
143.8 + *
143.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
143.10 + * Other names may be trademarks of their respective owners.
143.11 + *
143.12 + * The contents of this file are subject to the terms of either the GNU
143.13 + * General Public License Version 2 only ("GPL") or the Common
143.14 + * Development and Distribution License("CDDL") (collectively, the
143.15 + * "License"). You may not use this file except in compliance with the
143.16 + * License. You can obtain a copy of the License at
143.17 + * http://www.netbeans.org/cddl-gplv2.html
143.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
143.19 + * specific language governing permissions and limitations under the
143.20 + * License. When distributing the software, include this License Header
143.21 + * Notice in each file and include the License file at
143.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
143.23 + * particular file as subject to the "Classpath" exception as provided
143.24 + * by Oracle in the GPL Version 2 section of the License file that
143.25 + * accompanied this code. If applicable, add the following below the
143.26 + * License Header, with the fields enclosed by brackets [] replaced by
143.27 + * your own identifying information:
143.28 + * "Portions Copyrighted [year] [name of copyright owner]"
143.29 + *
143.30 + * Contributor(s):
143.31 + *
143.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
143.33 + */
143.34 +package org.netbeans.modules.python.source;
143.35 +
143.36 +import java.util.ArrayList;
143.37 +import java.util.Iterator;
143.38 +import java.util.ListIterator;
143.39 +import org.openide.util.Exceptions;
143.40 +import org.python.antlr.PythonTree;
143.41 +import org.python.antlr.Visitor;
143.42 +
143.43 +/**
143.44 + * AstPath represents a path from a root node to a particular node in the AST.
143.45 + * This is necessary because the parent node pointers in the nodes aren't always
143.46 + * non null, so we can't just pass a node as a reference to a traversable path
143.47 + * from the root to a node.
143.48 + *
143.49 + * @author Tor Norbye
143.50 + */
143.51 +public class AstPath implements Iterable<PythonTree> {
143.52 + private ArrayList<PythonTree> path = new ArrayList<>(30);
143.53 +
143.54 + public AstPath() {
143.55 + }
143.56 +
143.57 + public AstPath(AstPath other) {
143.58 + path.addAll(other.path);
143.59 + }
143.60 +
143.61 + public AstPath(ArrayList<PythonTree> path) {
143.62 + this.path = path;
143.63 + }
143.64 +
143.65 +// /**
143.66 +// * Initialize a node path to the given caretOffset
143.67 +// */
143.68 +// public AstPath(PythonTree root, int caretOffset) {
143.69 +// findPathTo(root, caretOffset);
143.70 +// }
143.71 +//
143.72 +// /**
143.73 +// * Find the path to the given node in the AST
143.74 +// */
143.75 +// @SuppressWarnings("unchecked")
143.76 +// public AstPath(PythonTree node, PythonTree target) {
143.77 +// if (!find(node, target)) {
143.78 +// path.clear();
143.79 +// } else {
143.80 +// // Reverse the list such that node is on top
143.81 +// // When I get time rewrite the find method to build the list that way in the first place
143.82 +// Collections.reverse(path);
143.83 +// }
143.84 +// }
143.85 + public void descend(PythonTree node) {
143.86 + path.add(node);
143.87 + }
143.88 +
143.89 + public void ascend() {
143.90 + path.remove(path.size() - 1);
143.91 + }
143.92 +
143.93 + /**
143.94 + * Return the closest ancestor of the leaf that is of the given type
143.95 + */
143.96 + public PythonTree getTypedAncestor(Class clz) {
143.97 + return getTypedAncestor(clz, null);
143.98 + }
143.99 +
143.100 + /**
143.101 + * Return the closest ancestor of the given node that is of the given type
143.102 + */
143.103 + public PythonTree getTypedAncestor(Class clz, PythonTree from) {
143.104 + int i = path.size() - 1;
143.105 +
143.106 + // First find the given starting point
143.107 + if (from != null) {
143.108 + for (; i >= 0; i--) {
143.109 + PythonTree node = path.get(i);
143.110 +
143.111 + if (node == from) {
143.112 + break;
143.113 + }
143.114 + }
143.115 + }
143.116 +
143.117 + for (; i >= 0; i--) {
143.118 + PythonTree node = path.get(i);
143.119 +
143.120 + if (clz.isInstance(node)) {
143.121 + return node;
143.122 + }
143.123 + }
143.124 +
143.125 + return null; // not found
143.126 + }
143.127 +
143.128 + /**
143.129 + * Return true iff this path contains a node of the given node type
143.130 + *
143.131 + * @param nodeType The nodeType to check
143.132 + * @return true if the given nodeType is found in the path
143.133 + */
143.134 + public boolean contains(Class clz) {
143.135 + return getTypedAncestor(clz) != null;
143.136 + }
143.137 +
143.138 +// /**
143.139 +// * Find the position closest to the given offset in the AST. Place the path from the leaf up to the path in the
143.140 +// * passed in path list.
143.141 +// */
143.142 +// @SuppressWarnings("unchecked")
143.143 +// public PythonTree findPathTo(PythonTree node, int offset) {
143.144 +// PythonTree result = find(node, offset);
143.145 +// path.add(node);
143.146 +//
143.147 +// // Reverse the list such that node is on top
143.148 +// // When I get time rewrite the find method to build the list that way in the first place
143.149 +// Collections.reverse(path);
143.150 +//
143.151 +// return result;
143.152 +// }
143.153 +//
143.154 +// @SuppressWarnings("unchecked")
143.155 +// private PythonTree find(PythonTree node, int offset) {
143.156 +// int begin = node.getSourceStart();
143.157 +// int end = node.getSourceEnd();
143.158 +//
143.159 +// if ((offset >= begin) && (offset <= end)) {
143.160 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
143.161 +// PythonTree found = find(child, offset);
143.162 +//
143.163 +// if (found != null) {
143.164 +// path.add(child);
143.165 +//
143.166 +// return found;
143.167 +// }
143.168 +// }
143.169 +//
143.170 +// return node;
143.171 +// } else {
143.172 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
143.173 +// PythonTree found = find(child, offset);
143.174 +//
143.175 +// if (found != null) {
143.176 +// path.add(child);
143.177 +//
143.178 +// return found;
143.179 +// }
143.180 +// }
143.181 +//
143.182 +// return null;
143.183 +// }
143.184 +// }
143.185 +//
143.186 +// /**
143.187 +// * Find the path to the given node in the AST
143.188 +// */
143.189 +// @SuppressWarnings("unchecked")
143.190 +// public boolean find(PythonTree node, PythonTree target) {
143.191 +// if (node == target) {
143.192 +// return true;
143.193 +// }
143.194 +//
143.195 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
143.196 +// boolean found = find(child, target);
143.197 +//
143.198 +// if (found) {
143.199 +// path.add(child);
143.200 +//
143.201 +// return found;
143.202 +// }
143.203 +// }
143.204 +//
143.205 +// return false;
143.206 +// }
143.207 + @Override
143.208 + public String toString() {
143.209 + StringBuilder sb = new StringBuilder();
143.210 + sb.append("Path(");
143.211 + sb.append(path.size());
143.212 + sb.append(")=[");
143.213 +
143.214 + for (PythonTree n : path) {
143.215 + String name = n.toString();
143.216 + name = name.substring(name.lastIndexOf('.') + 1);
143.217 + sb.append(name);
143.218 + sb.append(":");
143.219 + }
143.220 +
143.221 + sb.append("]");
143.222 +
143.223 + return sb.toString();
143.224 + }
143.225 +
143.226 + public PythonTree leaf() {
143.227 + if (path.size() == 0) {
143.228 + return null;
143.229 + } else {
143.230 + return path.get(path.size() - 1);
143.231 + }
143.232 + }
143.233 +
143.234 + public PythonTree leafParent() {
143.235 + if (path.size() < 2) {
143.236 + return null;
143.237 + } else {
143.238 + return path.get(path.size() - 2);
143.239 + }
143.240 + }
143.241 +
143.242 + public PythonTree leafGrandParent() {
143.243 + if (path.size() < 3) {
143.244 + return null;
143.245 + } else {
143.246 + return path.get(path.size() - 3);
143.247 + }
143.248 + }
143.249 +
143.250 + /**
143.251 + * Return the top/module level node -- this is not the module node
143.252 + * itself but the first node below it.
143.253 + */
143.254 + public PythonTree topModuleLevel() {
143.255 + if (path.size() >= 2) {
143.256 + return path.get(1);
143.257 + } else {
143.258 + return null;
143.259 + }
143.260 + }
143.261 +
143.262 + public PythonTree root() {
143.263 + if (path.size() == 0) {
143.264 + return null;
143.265 + } else {
143.266 + return path.get(0);
143.267 + }
143.268 + }
143.269 +
143.270 + /** Return an iterator that returns the elements from the leaf back up to the root */
143.271 + @Override
143.272 + public Iterator<PythonTree> iterator() {
143.273 + return new LeafToRootIterator(path);
143.274 + }
143.275 +
143.276 + /** REturn an iterator that starts at the root and walks down to the leaf */
143.277 + public ListIterator<PythonTree> rootToLeaf() {
143.278 + return path.listIterator();
143.279 + }
143.280 +
143.281 + /** Return an iterator that walks from the leaf back up to the root */
143.282 + public ListIterator<PythonTree> leafToRoot() {
143.283 + return new LeafToRootIterator(path);
143.284 + }
143.285 +
143.286 + private static class LeafToRootIterator implements ListIterator<PythonTree> {
143.287 + private final ListIterator<PythonTree> it;
143.288 +
143.289 + private LeafToRootIterator(ArrayList<PythonTree> path) {
143.290 + it = path.listIterator(path.size());
143.291 + }
143.292 +
143.293 + @Override
143.294 + public boolean hasNext() {
143.295 + return it.hasPrevious();
143.296 + }
143.297 +
143.298 + @Override
143.299 + public PythonTree next() {
143.300 + return it.previous();
143.301 + }
143.302 +
143.303 + @Override
143.304 + public boolean hasPrevious() {
143.305 + return it.hasNext();
143.306 + }
143.307 +
143.308 + @Override
143.309 + public PythonTree previous() {
143.310 + return it.next();
143.311 + }
143.312 +
143.313 + @Override
143.314 + public int nextIndex() {
143.315 + return it.previousIndex();
143.316 + }
143.317 +
143.318 + @Override
143.319 + public int previousIndex() {
143.320 + return it.nextIndex();
143.321 + }
143.322 +
143.323 + @Override
143.324 + public void remove() {
143.325 + throw new UnsupportedOperationException("Not supported yet.");
143.326 + }
143.327 +
143.328 + @Override
143.329 + public void set(PythonTree arg0) {
143.330 + throw new UnsupportedOperationException("Not supported yet.");
143.331 + }
143.332 +
143.333 + @Override
143.334 + public void add(PythonTree arg0) {
143.335 + throw new UnsupportedOperationException("Not supported yet.");
143.336 + }
143.337 + }
143.338 +
143.339 + private static class FindByOffsetVisitor extends Visitor {
143.340 + private int targetOffset;
143.341 + private ArrayList<PythonTree> path = new ArrayList<>();
143.342 +
143.343 + private FindByOffsetVisitor(int targetOffset) {
143.344 + this.targetOffset = targetOffset;
143.345 + }
143.346 +
143.347 + @Override
143.348 + public void traverse(PythonTree node) throws Exception {
143.349 + if (targetOffset >= node.getCharStartIndex() && targetOffset <= node.getCharStopIndex()) {
143.350 +// if (targetOffset == node.getCharStopIndex() && node.getClass() == FunctionDef.class) {
143.351 +// // For functions, don't include the last offset, since we can end up with
143.352 +// // functions that overlap - caret at the start position will add BOTH functions
143.353 +// // which we don't want
143.354 +// } else {
143.355 + path.add(node);
143.356 +// }
143.357 + super.traverse(node);
143.358 + }
143.359 + }
143.360 +
143.361 + AstPath getPath() {
143.362 + return new AstPath(path);
143.363 + }
143.364 + }
143.365 +
143.366 + public static AstPath get(PythonTree root, int offset) {
143.367 + FindByOffsetVisitor finder = new FindByOffsetVisitor(offset);
143.368 + try {
143.369 + finder.visit(root);
143.370 + AstPath path = finder.getPath();
143.371 + if (path.path.size() == 0) {
143.372 + path.path.add(root);
143.373 + }
143.374 +
143.375 + return path;
143.376 + } catch (Exception ex) {
143.377 + Exceptions.printStackTrace(ex);
143.378 + }
143.379 +
143.380 + return null;
143.381 + }
143.382 +
143.383 + private static class FindByNodeVisitor extends Visitor {
143.384 + private PythonTree target;
143.385 + private int startOffset;
143.386 + private int endOffset;
143.387 + private ArrayList<PythonTree> path = new ArrayList<>();
143.388 + private boolean found;
143.389 +
143.390 + private FindByNodeVisitor(PythonTree target) {
143.391 + this.target = target;
143.392 + this.startOffset = target.getCharStartIndex();
143.393 + this.endOffset = target.getCharStopIndex();
143.394 + }
143.395 +
143.396 + @Override
143.397 + public void traverse(PythonTree node) throws Exception {
143.398 + if (found) {
143.399 + return;
143.400 + }
143.401 + if (node == target) {
143.402 + path.add(node);
143.403 + found = true;
143.404 + return;
143.405 + }
143.406 + if (startOffset >= node.getCharStartIndex() && endOffset <= node.getCharStopIndex()) {
143.407 + path.add(node);
143.408 + node.traverse(this);
143.409 + if (found) {
143.410 + return;
143.411 + }
143.412 + path.remove(path.size() - 1);
143.413 + }
143.414 + }
143.415 +
143.416 + AstPath getPath() {
143.417 + return new AstPath(path);
143.418 + }
143.419 + }
143.420 +
143.421 + /**
143.422 + * Find the path to the given node in the AST
143.423 + */
143.424 + public static AstPath get(PythonTree root, PythonTree target) {
143.425 + FindByNodeVisitor finder = new FindByNodeVisitor(target);
143.426 + try {
143.427 + finder.visit(root);
143.428 + AstPath path = finder.getPath();
143.429 + if (path.path.size() == 0) {
143.430 + path.path.add(root);
143.431 + }
143.432 +
143.433 + return path;
143.434 + } catch (Exception ex) {
143.435 + Exceptions.printStackTrace(ex);
143.436 + return null;
143.437 + }
143.438 + }
143.439 +}
144.1 --- a/python.source/src/org/netbeans/modules/python/source/Bundle.properties Mon Aug 31 12:40:19 2015 +0200
144.2 +++ b/python.source/src/org/netbeans/modules/python/source/Bundle.properties Wed Sep 02 20:31:18 2015 +0200
144.3 @@ -1,1 +1,3 @@
144.4 OpenIDE-Module-Name=Python Source
144.5 +
144.6 +NoPreference=No Preference
145.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
145.2 +++ b/python.source/src/org/netbeans/modules/python/source/CodeStyle.java Wed Sep 02 20:31:18 2015 +0200
145.3 @@ -0,0 +1,738 @@
145.4 +/*
145.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
145.6 + *
145.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
145.8 + *
145.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
145.10 + * Other names may be trademarks of their respective owners.
145.11 + *
145.12 + * The contents of this file are subject to the terms of either the GNU
145.13 + * General Public License Version 2 only ("GPL") or the Common
145.14 + * Development and Distribution License("CDDL") (collectively, the
145.15 + * "License"). You may not use this file except in compliance with the
145.16 + * License. You can obtain a copy of the License at
145.17 + * http://www.netbeans.org/cddl-gplv2.html
145.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
145.19 + * specific language governing permissions and limitations under the
145.20 + * License. When distributing the software, include this License Header
145.21 + * Notice in each file and include the License file at
145.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
145.23 + * particular file as subject to the "Classpath" exception as provided
145.24 + * by Oracle in the GPL Version 2 section of the License file that
145.25 + * accompanied this code. If applicable, add the following below the
145.26 + * License Header, with the fields enclosed by brackets [] replaced by
145.27 + * your own identifying information:
145.28 + * "Portions Copyrighted [year] [name of copyright owner]"
145.29 + *
145.30 + * Contributor(s):
145.31 + *
145.32 + * The Original Software is NetBeans. The Initial Developer of the Original
145.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
145.34 + * Microsystems, Inc. All Rights Reserved.
145.35 + *
145.36 + * If you wish your version of this file to be governed by only the CDDL
145.37 + * or only the GPL Version 2, indicate your decision by adding
145.38 + * "[Contributor] elects to include this software in this distribution
145.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
145.40 + * single choice of license, a recipient has the option to distribute
145.41 + * your version of this file under either the CDDL, the GPL Version 2 or
145.42 + * to extend the choice of license to its licensees as provided above.
145.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
145.44 + * Version 2 license, then the option applies only if the new code is
145.45 + * made subject to such option by the copyright holder.
145.46 + */
145.47 +package org.netbeans.modules.python.source;
145.48 +
145.49 +import java.util.prefs.Preferences;
145.50 +import javax.swing.text.Document;
145.51 +import org.netbeans.modules.editor.indent.spi.CodeStylePreferences;
145.52 +import org.netbeans.modules.python.source.ui.FmtOptions;
145.53 +
145.54 +import org.openide.filesystems.FileObject;
145.55 +import static org.netbeans.modules.python.source.ui.FmtOptions.*;
145.56 +
145.57 +/**
145.58 + * XXX make sure the getters get the defaults from somewhere
145.59 + * XXX add support for profiles
145.60 + * XXX get the preferences node from somewhere else in odrer to be able not to
145.61 + * use the getters and to be able to write to it.
145.62 + *
145.63 + * @author Dusan Balek
145.64 + */
145.65 +public final class CodeStyle {
145.66 + static {
145.67 + FmtOptions.codeStyleProducer = new Producer();
145.68 + }
145.69 + private Preferences preferences;
145.70 +
145.71 + private CodeStyle(Preferences preferences) {
145.72 + this.preferences = preferences;
145.73 + }
145.74 +
145.75 +// /**
145.76 +// * Gets <code>CodeStyle</code> for files in the given project.
145.77 +// *
145.78 +// * <p>Please see the other two <code>getDefault</code> methods as they are
145.79 +// * the preferred way of getting <code>CodeStyle</code>.
145.80 +// *
145.81 +// * @param project The project to get the <code>CodeStyle</code> for.
145.82 +// * @return The current code style that would be used by documents opened
145.83 +// * from files belonging to the <code>project</code>.
145.84 +// *
145.85 +// * @deprecated Please use {@link #getDefault(javax.swing.text.Document)}
145.86 +// * or {@link #getDefault(org.openide.filesystems.FileObject)} respectively.
145.87 +// */
145.88 +// @Deprecated
145.89 +// public static CodeStyle getDefault(Project project) {
145.90 +// return getDefault(project.getProjectDirectory());
145.91 +// }
145.92 + /**
145.93 + * Gets <code>CodeStyle</code> for the given file. If you have a document
145.94 + * instance you should use the {@link #getDefault(javax.swing.text.Document)}
145.95 + * method.
145.96 + *
145.97 + * @param file The file to get the <code>CodeStyle</code> for.
145.98 + * @return The current code style that would be used by a document if the
145.99 + * <code>file</code> were opened in the editor.
145.100 + *
145.101 + * @since 0.39
145.102 + */
145.103 + public synchronized static CodeStyle getDefault(FileObject file) {
145.104 + Preferences prefs = CodeStylePreferences.get(file).getPreferences();
145.105 + return FmtOptions.codeStyleProducer.create(prefs);
145.106 + }
145.107 +
145.108 + /**
145.109 + * Gets <code>CodeStyle</code> for the given document. This is the preferred
145.110 + * method of getting <code>CodeStyle</code>. If you don't have a document
145.111 + * you can use {@link #getDefault(org.openide.filesystems.FileObject)} method instead.
145.112 + *
145.113 + * @param doc The document to get the <code>CodeStyle</code> for.
145.114 + * @return The current code style used by a document. This is the code style that
145.115 + * will be used when formatting the document or generating new code.
145.116 + *
145.117 + * @since 0.39
145.118 + */
145.119 + public synchronized static CodeStyle getDefault(Document doc) {
145.120 + Preferences prefs = CodeStylePreferences.get(doc).getPreferences();
145.121 + return FmtOptions.codeStyleProducer.create(prefs);
145.122 + }
145.123 +
145.124 + // General tabs and indents ------------------------------------------------
145.125 + public boolean expandTabToSpaces() {
145.126 +// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
145.127 + return preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
145.128 + }
145.129 +
145.130 + public int getTabSize() {
145.131 +// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
145.132 + return preferences.getInt(tabSize, getDefaultAsInt(tabSize));
145.133 + }
145.134 +
145.135 + public int getIndentSize() {
145.136 +// System.out.println("~~~ indent-shift-width=" + preferences.get(SimpleValueNames.INDENT_SHIFT_WIDTH, null));
145.137 + int indentLevel = preferences.getInt(indentSize, getDefaultAsInt(indentSize));
145.138 +
145.139 + if (indentLevel <= 0) {
145.140 +// System.out.println("~~~ expand-tabs=" + preferences.get(SimpleValueNames.EXPAND_TABS, null));
145.141 + boolean expandTabs = preferences.getBoolean(expandTabToSpaces, getDefaultAsBoolean(expandTabToSpaces));
145.142 + if (expandTabs) {
145.143 +// System.out.println("~~~ spaces-per-tab=" + preferences.get(SimpleValueNames.SPACES_PER_TAB, null));
145.144 + indentLevel = preferences.getInt(spacesPerTab, getDefaultAsInt(spacesPerTab));
145.145 + } else {
145.146 +// System.out.println("~~~ tab-size=" + preferences.get(SimpleValueNames.TAB_SIZE, null));
145.147 + indentLevel = preferences.getInt(tabSize, getDefaultAsInt(tabSize));
145.148 + }
145.149 + }
145.150 +
145.151 + return indentLevel;
145.152 + }
145.153 +
145.154 + public int getContinuationIndentSize() {
145.155 + return preferences.getInt(continuationIndentSize, getDefaultAsInt(continuationIndentSize));
145.156 + }
145.157 +
145.158 + public int getLabelIndent() {
145.159 + return preferences.getInt(labelIndent, getDefaultAsInt(labelIndent));
145.160 + }
145.161 +
145.162 + public boolean absoluteLabelIndent() {
145.163 + return preferences.getBoolean(absoluteLabelIndent, getDefaultAsBoolean(absoluteLabelIndent));
145.164 + }
145.165 +
145.166 + public boolean indentTopLevelClassMembers() {
145.167 + return preferences.getBoolean(indentTopLevelClassMembers, getDefaultAsBoolean(indentTopLevelClassMembers));
145.168 + }
145.169 +
145.170 + public boolean indentCasesFromSwitch() {
145.171 + return preferences.getBoolean(indentCasesFromSwitch, getDefaultAsBoolean(indentCasesFromSwitch));
145.172 + }
145.173 +
145.174 + public int getRightMargin() {
145.175 + return preferences.getInt(rightMargin, getDefaultAsInt(rightMargin));
145.176 + }
145.177 +
145.178 + /*
145.179 + public boolean addLeadingStarInComment() {
145.180 + return preferences.getBoolean(addLeadingStarInComment, getDefaultAsBoolean(addLeadingStarInComment));
145.181 + }
145.182 +
145.183 + // Code generation ---------------------------------------------------------
145.184 +
145.185 + public boolean preferLongerNames() {
145.186 + return preferences.getBoolean(preferLongerNames, getDefaultAsBoolean(preferLongerNames));
145.187 + }
145.188 +
145.189 + public String getFieldNamePrefix() {
145.190 + return preferences.get(fieldNamePrefix, getDefaultAsString(fieldNamePrefix));
145.191 + }
145.192 +
145.193 + public String getFieldNameSuffix() {
145.194 + return preferences.get(fieldNameSuffix, getDefaultAsString(fieldNameSuffix));
145.195 + }
145.196 +
145.197 + public String getStaticFieldNamePrefix() {
145.198 + return preferences.get(staticFieldNamePrefix, getDefaultAsString(staticFieldNamePrefix));
145.199 + }
145.200 +
145.201 + public String getStaticFieldNameSuffix() {
145.202 + return preferences.get(staticFieldNameSuffix, getDefaultAsString(staticFieldNameSuffix));
145.203 + }
145.204 +
145.205 + public String getParameterNamePrefix() {
145.206 + return preferences.get(parameterNamePrefix, getDefaultAsString(parameterNamePrefix));
145.207 + }
145.208 +
145.209 + public String getParameterNameSuffix() {
145.210 + return preferences.get(parameterNameSuffix, getDefaultAsString(parameterNameSuffix));
145.211 + }
145.212 +
145.213 + public String getLocalVarNamePrefix() {
145.214 + return preferences.get(localVarNamePrefix, getDefaultAsString(localVarNamePrefix));
145.215 + }
145.216 +
145.217 + public String getLocalVarNameSuffix() {
145.218 + return preferences.get(localVarNameSuffix, getDefaultAsString(localVarNameSuffix));
145.219 + }
145.220 +
145.221 + public boolean qualifyFieldAccess() {
145.222 + return preferences.getBoolean(qualifyFieldAccess, getDefaultAsBoolean(qualifyFieldAccess));
145.223 + }
145.224 +
145.225 + public boolean useIsForBooleanGetters() {
145.226 + return preferences.getBoolean(useIsForBooleanGetters, getDefaultAsBoolean(useIsForBooleanGetters));
145.227 + }
145.228 +
145.229 + public boolean addOverrideAnnotation() {
145.230 + return preferences.getBoolean(addOverrideAnnotation, getDefaultAsBoolean(addOverrideAnnotation));
145.231 + }
145.232 +
145.233 + public boolean makeLocalVarsFinal() {
145.234 + return preferences.getBoolean(makeLocalVarsFinal, getDefaultAsBoolean(makeLocalVarsFinal));
145.235 + }
145.236 +
145.237 + // Alignment ----------------------------------------------------
145.238 +
145.239 + public boolean alignMultilineMethodParams() {
145.240 + return preferences.getBoolean(alignMultilineMethodParams, getDefaultAsBoolean(alignMultilineMethodParams));
145.241 + }
145.242 +
145.243 + public boolean alignMultilineCallArgs() {
145.244 + return preferences.getBoolean(alignMultilineCallArgs, getDefaultAsBoolean(alignMultilineCallArgs));
145.245 + }
145.246 +
145.247 + public boolean alignMultilineAnnotationArgs() {
145.248 + return preferences.getBoolean(alignMultilineAnnotationArgs, getDefaultAsBoolean(alignMultilineAnnotationArgs));
145.249 + }
145.250 +
145.251 + public boolean alignMultilineImplements() {
145.252 + return preferences.getBoolean(alignMultilineImplements, getDefaultAsBoolean(alignMultilineImplements));
145.253 + }
145.254 +
145.255 + public boolean alignMultilineThrows() {
145.256 + return preferences.getBoolean(alignMultilineThrows, getDefaultAsBoolean(alignMultilineThrows));
145.257 + }
145.258 +
145.259 + public boolean alignMultilineParenthesized() {
145.260 + return preferences.getBoolean(alignMultilineParenthesized, getDefaultAsBoolean(alignMultilineParenthesized));
145.261 + }
145.262 +
145.263 + public boolean alignMultilineBinaryOp() {
145.264 + return preferences.getBoolean(alignMultilineBinaryOp, getDefaultAsBoolean(alignMultilineBinaryOp));
145.265 + }
145.266 +
145.267 + public boolean alignMultilineTernaryOp() {
145.268 + return preferences.getBoolean(alignMultilineTernaryOp, getDefaultAsBoolean(alignMultilineTernaryOp));
145.269 + }
145.270 +
145.271 + public boolean alignMultilineAssignment() {
145.272 + return preferences.getBoolean(alignMultilineAssignment, getDefaultAsBoolean(alignMultilineAssignment));
145.273 + }
145.274 +
145.275 + public boolean alignMultilineFor() {
145.276 + return preferences.getBoolean(alignMultilineFor, getDefaultAsBoolean(alignMultilineFor));
145.277 + }
145.278 +
145.279 + public boolean alignMultilineArrayInit() {
145.280 + return preferences.getBoolean(alignMultilineArrayInit, getDefaultAsBoolean(alignMultilineArrayInit));
145.281 + }
145.282 +
145.283 + public boolean placeElseOnNewLine() {
145.284 + return preferences.getBoolean(placeElseOnNewLine, getDefaultAsBoolean(placeElseOnNewLine));
145.285 + }
145.286 +
145.287 + public boolean placeWhileOnNewLine() {
145.288 + return preferences.getBoolean(placeWhileOnNewLine, getDefaultAsBoolean(placeWhileOnNewLine));
145.289 + }
145.290 +
145.291 + public boolean placeCatchOnNewLine() {
145.292 + return preferences.getBoolean(placeCatchOnNewLine, getDefaultAsBoolean(placeCatchOnNewLine));
145.293 + }
145.294 +
145.295 + public boolean placeFinallyOnNewLine() {
145.296 + return preferences.getBoolean(placeFinallyOnNewLine, getDefaultAsBoolean(placeFinallyOnNewLine));
145.297 + }
145.298 +
145.299 + public boolean placeNewLineAfterModifiers() {
145.300 + return preferences.getBoolean(placeNewLineAfterModifiers, getDefaultAsBoolean(placeNewLineAfterModifiers));
145.301 + }
145.302 +
145.303 + // Wrapping ----------------------------------------------------------------
145.304 +
145.305 + public WrapStyle wrapExtendsImplementsKeyword() {
145.306 + String wrap = preferences.get(wrapExtendsImplementsKeyword, getDefaultAsString(wrapExtendsImplementsKeyword));
145.307 + return WrapStyle.valueOf(wrap);
145.308 + }
145.309 +
145.310 + public WrapStyle wrapExtendsImplementsList() {
145.311 + String wrap = preferences.get(wrapExtendsImplementsList, getDefaultAsString(wrapExtendsImplementsList));
145.312 + return WrapStyle.valueOf(wrap);
145.313 + }
145.314 +
145.315 + public WrapStyle wrapMethodParams() {
145.316 + String wrap = preferences.get(wrapMethodParams, getDefaultAsString(wrapMethodParams));
145.317 + return WrapStyle.valueOf(wrap);
145.318 + }
145.319 +
145.320 + public WrapStyle wrapThrowsKeyword() {
145.321 + String wrap = preferences.get(wrapThrowsKeyword, getDefaultAsString(wrapThrowsKeyword));
145.322 + return WrapStyle.valueOf(wrap);
145.323 + }
145.324 +
145.325 + public WrapStyle wrapThrowsList() {
145.326 + String wrap = preferences.get(wrapThrowsList, getDefaultAsString(wrapThrowsList));
145.327 + return WrapStyle.valueOf(wrap);
145.328 + }
145.329 +
145.330 + public WrapStyle wrapMethodCallArgs() {
145.331 + String wrap = preferences.get(wrapMethodCallArgs, getDefaultAsString(wrapMethodCallArgs));
145.332 + return WrapStyle.valueOf(wrap);
145.333 + }
145.334 +
145.335 + public WrapStyle wrapAnnotationArgs() {
145.336 + String wrap = preferences.get(wrapAnnotationArgs, getDefaultAsString(wrapAnnotationArgs));
145.337 + return WrapStyle.valueOf(wrap);
145.338 + }
145.339 +
145.340 + public WrapStyle wrapChainedMethodCalls() {
145.341 + String wrap = preferences.get(wrapChainedMethodCalls, getDefaultAsString(wrapChainedMethodCalls));
145.342 + return WrapStyle.valueOf(wrap);
145.343 + }
145.344 +
145.345 + public WrapStyle wrapArrayInit() {
145.346 + String wrap = preferences.get(wrapArrayInit, getDefaultAsString(wrapArrayInit));
145.347 + return WrapStyle.valueOf(wrap);
145.348 + }
145.349 +
145.350 + public WrapStyle wrapFor() {
145.351 + String wrap = preferences.get(wrapFor, getDefaultAsString(wrapFor));
145.352 + return WrapStyle.valueOf(wrap);
145.353 + }
145.354 +
145.355 + public WrapStyle wrapForStatement() {
145.356 + String wrap = preferences.get(wrapForStatement, getDefaultAsString(wrapForStatement));
145.357 + return WrapStyle.valueOf(wrap);
145.358 + }
145.359 +
145.360 + public WrapStyle wrapIfStatement() {
145.361 + String wrap = preferences.get(wrapIfStatement, getDefaultAsString(wrapIfStatement));
145.362 + return WrapStyle.valueOf(wrap);
145.363 + }
145.364 +
145.365 + public WrapStyle wrapWhileStatement() {
145.366 + String wrap = preferences.get(wrapWhileStatement, getDefaultAsString(wrapWhileStatement));
145.367 + return WrapStyle.valueOf(wrap);
145.368 + }
145.369 +
145.370 + public WrapStyle wrapDoWhileStatement() {
145.371 + String wrap = preferences.get(wrapDoWhileStatement, getDefaultAsString(wrapDoWhileStatement));
145.372 + return WrapStyle.valueOf(wrap);
145.373 + }
145.374 +
145.375 + public WrapStyle wrapAssert() {
145.376 + String wrap = preferences.get(wrapAssert, getDefaultAsString(wrapAssert));
145.377 + return WrapStyle.valueOf(wrap);
145.378 + }
145.379 +
145.380 + public WrapStyle wrapEnumConstants() {
145.381 + String wrap = preferences.get(wrapEnumConstants, getDefaultAsString(wrapEnumConstants));
145.382 + return WrapStyle.valueOf(wrap);
145.383 + }
145.384 +
145.385 + public WrapStyle wrapAnnotations() {
145.386 + String wrap = preferences.get(wrapAnnotations, getDefaultAsString(wrapAnnotations));
145.387 + return WrapStyle.valueOf(wrap);
145.388 + }
145.389 +
145.390 + public WrapStyle wrapBinaryOps() {
145.391 + String wrap = preferences.get(wrapBinaryOps, getDefaultAsString(wrapBinaryOps));
145.392 + return WrapStyle.valueOf(wrap);
145.393 + }
145.394 +
145.395 + public WrapStyle wrapTernaryOps() {
145.396 + String wrap = preferences.get(wrapTernaryOps, getDefaultAsString(wrapTernaryOps));
145.397 + return WrapStyle.valueOf(wrap);
145.398 + }
145.399 +
145.400 + public WrapStyle wrapAssignOps() {
145.401 + String wrap = preferences.get(wrapAssignOps, getDefaultAsString(wrapAssignOps));
145.402 + return WrapStyle.valueOf(wrap);
145.403 + }
145.404 +
145.405 + // Blank lines -------------------------------------------------------------
145.406 +
145.407 + public int getBlankLinesBeforePackage() {
145.408 + return preferences.getInt(blankLinesBeforePackage, getDefaultAsInt(blankLinesBeforePackage));
145.409 + }
145.410 +
145.411 + public int getBlankLinesAfterPackage() {
145.412 + return preferences.getInt(blankLinesAfterPackage, getDefaultAsInt(blankLinesAfterPackage));
145.413 + }
145.414 +
145.415 + public int getBlankLinesBeforeImports() {
145.416 + return preferences.getInt(blankLinesBeforeImports, getDefaultAsInt(blankLinesBeforeImports));
145.417 + }
145.418 +
145.419 + public int getBlankLinesAfterImports() {
145.420 + return preferences.getInt(blankLinesAfterImports, getDefaultAsInt(blankLinesAfterImports));
145.421 + }
145.422 +
145.423 + public int getBlankLinesBeforeClass() {
145.424 + return preferences.getInt(blankLinesBeforeClass, getDefaultAsInt(blankLinesBeforeClass));
145.425 + }
145.426 +
145.427 + public int getBlankLinesAfterClass() {
145.428 + return preferences.getInt(blankLinesAfterClass, getDefaultAsInt(blankLinesAfterClass));
145.429 + }
145.430 +
145.431 + public int getBlankLinesAfterClassHeader() {
145.432 + return preferences.getInt(blankLinesAfterClassHeader, getDefaultAsInt(blankLinesAfterClassHeader));
145.433 + }
145.434 +
145.435 + public int getBlankLinesBeforeFields() {
145.436 + return preferences.getInt(blankLinesBeforeFields, getDefaultAsInt(blankLinesBeforeFields));
145.437 + }
145.438 +
145.439 + public int getBlankLinesAfterFields() {
145.440 + return preferences.getInt(blankLinesAfterFields, getDefaultAsInt(blankLinesAfterFields));
145.441 + }
145.442 +
145.443 + public int getBlankLinesBeforeMethods() {
145.444 + return preferences.getInt(blankLinesBeforeMethods, getDefaultAsInt(blankLinesBeforeMethods));
145.445 + }
145.446 +
145.447 + public int getBlankLinesAfterMethods() {
145.448 + return preferences.getInt(blankLinesAfterMethods, getDefaultAsInt(blankLinesAfterMethods));
145.449 + }
145.450 +
145.451 + // Spaces ------------------------------------------------------------------
145.452 +
145.453 + public boolean spaceBeforeWhile() {
145.454 + return preferences.getBoolean(spaceBeforeWhile, getDefaultAsBoolean(spaceBeforeWhile));
145.455 + }
145.456 +
145.457 + public boolean spaceBeforeElse() {
145.458 + return preferences.getBoolean(spaceBeforeElse, getDefaultAsBoolean(spaceBeforeElse));
145.459 + }
145.460 +
145.461 + public boolean spaceBeforeCatch() {
145.462 + return preferences.getBoolean(spaceBeforeCatch, getDefaultAsBoolean(spaceBeforeCatch));
145.463 + }
145.464 +
145.465 + public boolean spaceBeforeFinally() {
145.466 + return preferences.getBoolean(spaceBeforeFinally, getDefaultAsBoolean(spaceBeforeFinally));
145.467 + }
145.468 +
145.469 + public boolean spaceBeforeMethodDeclParen() {
145.470 + return preferences.getBoolean(spaceBeforeMethodDeclParen, getDefaultAsBoolean(spaceBeforeMethodDeclParen));
145.471 + }
145.472 +
145.473 + public boolean spaceBeforeMethodCallParen() {
145.474 + return preferences.getBoolean(spaceBeforeMethodCallParen, getDefaultAsBoolean(spaceBeforeMethodCallParen));
145.475 + }
145.476 +
145.477 + public boolean spaceBeforeIfParen() {
145.478 + return preferences.getBoolean(spaceBeforeIfParen, getDefaultAsBoolean(spaceBeforeIfParen));
145.479 + }
145.480 +
145.481 + public boolean spaceBeforeForParen() {
145.482 + return preferences.getBoolean(spaceBeforeForParen, getDefaultAsBoolean(spaceBeforeForParen));
145.483 + }
145.484 +
145.485 + public boolean spaceBeforeWhileParen() {
145.486 + return preferences.getBoolean(spaceBeforeWhileParen, getDefaultAsBoolean(spaceBeforeWhileParen));
145.487 + }
145.488 +
145.489 + public boolean spaceBeforeCatchParen() {
145.490 + return preferences.getBoolean(spaceBeforeCatchParen, getDefaultAsBoolean(spaceBeforeCatchParen));
145.491 + }
145.492 +
145.493 + public boolean spaceBeforeSwitchParen() {
145.494 + return preferences.getBoolean(spaceBeforeSwitchParen, getDefaultAsBoolean(spaceBeforeSwitchParen));
145.495 + }
145.496 +
145.497 + public boolean spaceBeforeSynchronizedParen() {
145.498 + return preferences.getBoolean(spaceBeforeSynchronizedParen, getDefaultAsBoolean(spaceBeforeSynchronizedParen));
145.499 + }
145.500 +
145.501 + public boolean spaceBeforeAnnotationParen() {
145.502 + return preferences.getBoolean(spaceBeforeAnnotationParen, getDefaultAsBoolean(spaceBeforeAnnotationParen));
145.503 + }
145.504 +
145.505 + public boolean spaceAroundUnaryOps() {
145.506 + return preferences.getBoolean(spaceAroundUnaryOps, getDefaultAsBoolean(spaceAroundUnaryOps));
145.507 + }
145.508 +
145.509 + public boolean spaceAroundBinaryOps() {
145.510 + return preferences.getBoolean(spaceAroundBinaryOps, getDefaultAsBoolean(spaceAroundBinaryOps));
145.511 + }
145.512 +
145.513 + public boolean spaceAroundTernaryOps() {
145.514 + return preferences.getBoolean(spaceAroundTernaryOps, getDefaultAsBoolean(spaceAroundTernaryOps));
145.515 + }
145.516 +
145.517 + public boolean spaceAroundAssignOps() {
145.518 + return preferences.getBoolean(spaceAroundAssignOps, getDefaultAsBoolean(spaceAroundAssignOps));
145.519 + }
145.520 +
145.521 + public boolean spaceBeforeClassDeclLeftBrace() {
145.522 + return preferences.getBoolean(spaceBeforeClassDeclLeftBrace, getDefaultAsBoolean(spaceBeforeClassDeclLeftBrace));
145.523 + }
145.524 +
145.525 + public boolean spaceBeforeMethodDeclLeftBrace() {
145.526 + return preferences.getBoolean(spaceBeforeMethodDeclLeftBrace, getDefaultAsBoolean(spaceBeforeMethodDeclLeftBrace));
145.527 + }
145.528 +
145.529 + public boolean spaceBeforeIfLeftBrace() {
145.530 + return preferences.getBoolean(spaceBeforeIfLeftBrace, getDefaultAsBoolean(spaceBeforeIfLeftBrace));
145.531 + }
145.532 +
145.533 + public boolean spaceBeforeElseLeftBrace() {
145.534 + return preferences.getBoolean(spaceBeforeElseLeftBrace, getDefaultAsBoolean(spaceBeforeElseLeftBrace));
145.535 + }
145.536 +
145.537 + public boolean spaceBeforeWhileLeftBrace() {
145.538 + return preferences.getBoolean(spaceBeforeWhileLeftBrace, getDefaultAsBoolean(spaceBeforeWhileLeftBrace));
145.539 + }
145.540 +
145.541 + public boolean spaceBeforeForLeftBrace() {
145.542 + return preferences.getBoolean(spaceBeforeForLeftBrace, getDefaultAsBoolean(spaceBeforeForLeftBrace));
145.543 + }
145.544 +
145.545 + public boolean spaceBeforeDoLeftBrace() {
145.546 + return preferences.getBoolean(spaceBeforeDoLeftBrace, getDefaultAsBoolean(spaceBeforeDoLeftBrace));
145.547 + }
145.548 +
145.549 + public boolean spaceBeforeSwitchLeftBrace() {
145.550 + return preferences.getBoolean(spaceBeforeSwitchLeftBrace, getDefaultAsBoolean(spaceBeforeSwitchLeftBrace));
145.551 + }
145.552 +
145.553 + public boolean spaceBeforeTryLeftBrace() {
145.554 + return preferences.getBoolean(spaceBeforeTryLeftBrace, getDefaultAsBoolean(spaceBeforeTryLeftBrace));
145.555 + }
145.556 +
145.557 + public boolean spaceBeforeCatchLeftBrace() {
145.558 + return preferences.getBoolean(spaceBeforeCatchLeftBrace, getDefaultAsBoolean(spaceBeforeCatchLeftBrace));
145.559 + }
145.560 +
145.561 + public boolean spaceBeforeFinallyLeftBrace() {
145.562 + return preferences.getBoolean(spaceBeforeFinallyLeftBrace, getDefaultAsBoolean(spaceBeforeFinallyLeftBrace));
145.563 + }
145.564 +
145.565 + public boolean spaceBeforeSynchronizedLeftBrace() {
145.566 + return preferences.getBoolean(spaceBeforeSynchronizedLeftBrace, getDefaultAsBoolean(spaceBeforeSynchronizedLeftBrace));
145.567 + }
145.568 +
145.569 + public boolean spaceBeforeStaticInitLeftBrace() {
145.570 + return preferences.getBoolean(spaceBeforeStaticInitLeftBrace, getDefaultAsBoolean(spaceBeforeStaticInitLeftBrace));
145.571 + }
145.572 +
145.573 + public boolean spaceBeforeArrayInitLeftBrace() {
145.574 + return preferences.getBoolean(spaceBeforeArrayInitLeftBrace, getDefaultAsBoolean(spaceBeforeArrayInitLeftBrace));
145.575 + }
145.576 +
145.577 + public boolean spaceWithinParens() {
145.578 + return preferences.getBoolean(spaceWithinParens, getDefaultAsBoolean(spaceWithinParens));
145.579 + }
145.580 +
145.581 + public boolean spaceWithinMethodDeclParens() {
145.582 + return preferences.getBoolean(spaceWithinMethodDeclParens, getDefaultAsBoolean(spaceWithinMethodDeclParens));
145.583 + }
145.584 +
145.585 + public boolean spaceWithinMethodCallParens() {
145.586 + return preferences.getBoolean(spaceWithinMethodCallParens, getDefaultAsBoolean(spaceWithinMethodCallParens));
145.587 + }
145.588 +
145.589 + public boolean spaceWithinIfParens() {
145.590 + return preferences.getBoolean(spaceWithinIfParens, getDefaultAsBoolean(spaceWithinIfParens));
145.591 + }
145.592 +
145.593 + public boolean spaceWithinForParens() {
145.594 + return preferences.getBoolean(spaceWithinForParens, getDefaultAsBoolean(spaceWithinForParens));
145.595 + }
145.596 +
145.597 + public boolean spaceWithinWhileParens() {
145.598 + return preferences.getBoolean(spaceWithinWhileParens, getDefaultAsBoolean(spaceWithinWhileParens));
145.599 + }
145.600 +
145.601 + public boolean spaceWithinSwitchParens() {
145.602 + return preferences.getBoolean(spaceWithinSwitchParens, getDefaultAsBoolean(spaceWithinSwitchParens));
145.603 + }
145.604 +
145.605 + public boolean spaceWithinCatchParens() {
145.606 + return preferences.getBoolean(spaceWithinCatchParens, getDefaultAsBoolean(spaceWithinCatchParens));
145.607 + }
145.608 +
145.609 + public boolean spaceWithinSynchronizedParens() {
145.610 + return preferences.getBoolean(spaceWithinSynchronizedParens, getDefaultAsBoolean(spaceWithinSynchronizedParens));
145.611 + }
145.612 +
145.613 + public boolean spaceWithinTypeCastParens() {
145.614 + return preferences.getBoolean(spaceWithinTypeCastParens, getDefaultAsBoolean(spaceWithinTypeCastParens));
145.615 + }
145.616 +
145.617 + public boolean spaceWithinAnnotationParens() {
145.618 + return preferences.getBoolean(spaceWithinAnnotationParens, getDefaultAsBoolean(spaceWithinAnnotationParens));
145.619 + }
145.620 +
145.621 + public boolean spaceWithinBraces() {
145.622 + return preferences.getBoolean(spaceWithinBraces, getDefaultAsBoolean(spaceWithinBraces));
145.623 + }
145.624 +
145.625 + public boolean spaceWithinArrayInitBrackets() {
145.626 + return preferences.getBoolean(spaceWithinArrayInitBrackets, getDefaultAsBoolean(spaceWithinArrayInitBrackets));
145.627 + }
145.628 +
145.629 + public boolean spaceBeforeComma() {
145.630 + return preferences.getBoolean(spaceBeforeComma, getDefaultAsBoolean(spaceBeforeComma));
145.631 + }
145.632 +
145.633 + public boolean spaceAfterComma() {
145.634 + return preferences.getBoolean(spaceAfterComma, getDefaultAsBoolean(spaceAfterComma));
145.635 + }
145.636 +
145.637 + public boolean spaceBeforeSemi() {
145.638 + return preferences.getBoolean(spaceBeforeSemi, getDefaultAsBoolean(spaceBeforeSemi));
145.639 + }
145.640 +
145.641 + public boolean spaceAfterSemi() {
145.642 + return preferences.getBoolean(spaceAfterSemi, getDefaultAsBoolean(spaceAfterSemi));
145.643 + }
145.644 +
145.645 + public boolean spaceBeforeColon() {
145.646 + return preferences.getBoolean(spaceBeforeColon, getDefaultAsBoolean(spaceBeforeColon));
145.647 + }
145.648 +
145.649 + public boolean spaceAfterColon() {
145.650 + return preferences.getBoolean(spaceAfterColon, getDefaultAsBoolean(spaceAfterColon));
145.651 + }
145.652 +
145.653 + public boolean spaceAfterTypeCast() {
145.654 + return preferences.getBoolean(spaceAfterTypeCast, getDefaultAsBoolean(spaceAfterTypeCast));
145.655 + }
145.656 +
145.657 + */
145.658 + // Spaces -----------------------------------------------------------------
145.659 + public boolean addSpaceAroundOperators() {
145.660 + return preferences.getBoolean(addSpaceAroundOperators, getDefaultAsBoolean(addSpaceAroundOperators));
145.661 + }
145.662 +
145.663 + public boolean removeSpaceInsideParens() {
145.664 + return preferences.getBoolean(removeSpaceInParens, getDefaultAsBoolean(removeSpaceInParens));
145.665 + }
145.666 +
145.667 + public boolean addSpaceAfterComma() {
145.668 + return preferences.getBoolean(addSpaceAfterComma, getDefaultAsBoolean(addSpaceAfterComma));
145.669 + }
145.670 +
145.671 + public boolean removeSpaceBeforeSep() {
145.672 + return preferences.getBoolean(removeSpaceBeforeSep, getDefaultAsBoolean(removeSpaceBeforeSep));
145.673 + }
145.674 +
145.675 + public boolean removeSpaceInParamAssign() {
145.676 + return preferences.getBoolean(removeSpaceInParamAssign, getDefaultAsBoolean(removeSpaceInParamAssign));
145.677 + }
145.678 +
145.679 + public boolean collapseSpaces() {
145.680 + return preferences.getBoolean(collapseSpaces, getDefaultAsBoolean(collapseSpaces));
145.681 + }
145.682 +
145.683 + // Imports -----------------------------------------------------------------
145.684 + public boolean formatImports() {
145.685 + return preferences.getBoolean(formatImports, getDefaultAsBoolean(formatImports));
145.686 + }
145.687 +
145.688 + public boolean oneImportPerLine() {
145.689 + return preferences.getBoolean(oneImportPerLine, getDefaultAsBoolean(oneImportPerLine));
145.690 + }
145.691 +
145.692 + public boolean removeDuplicates() {
145.693 + return preferences.getBoolean(removeDuplicates, getDefaultAsBoolean(removeDuplicates));
145.694 + }
145.695 +
145.696 + public boolean systemLibsFirst() {
145.697 + return preferences.getBoolean(systemLibsFirst, getDefaultAsBoolean(systemLibsFirst));
145.698 + }
145.699 +
145.700 + public boolean preferSymbolImports() {
145.701 + return preferences.getBoolean(preferSymbolImports, getDefaultAsBoolean(preferSymbolImports));
145.702 + }
145.703 +
145.704 + public boolean sortImports() {
145.705 + return preferences.getBoolean(sortImports, getDefaultAsBoolean(sortImports));
145.706 + }
145.707 +
145.708 + public boolean separateFromImps() {
145.709 + return preferences.getBoolean(separateFromImps, getDefaultAsBoolean(separateFromImps));
145.710 + }
145.711 +
145.712 + public ImportCleanupStyle cleanupImports() {
145.713 + String cleanup = preferences.get(cleanupUnusedImports, getDefaultAsString(cleanupUnusedImports));
145.714 + return ImportCleanupStyle.valueOf(cleanup);
145.715 + }
145.716 +
145.717 + public String[] getPackagesForStarImport() {
145.718 + return null;
145.719 + }
145.720 +
145.721 + // Nested classes ----------------------------------------------------------
145.722 + public enum WrapStyle {
145.723 + WRAP_ALWAYS,
145.724 + WRAP_IF_LONG,
145.725 + WRAP_NEVER
145.726 + }
145.727 +
145.728 + public enum ImportCleanupStyle {
145.729 + LEAVE_ALONE,
145.730 + COMMENT_OUT,
145.731 + DELETE
145.732 + }
145.733 +
145.734 + // Communication with non public packages ----------------------------------
145.735 + private static class Producer implements FmtOptions.CodeStyleProducer {
145.736 + @Override
145.737 + public CodeStyle create(Preferences preferences) {
145.738 + return new CodeStyle(preferences);
145.739 + }
145.740 + }
145.741 +}
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
146.2 +++ b/python.source/src/org/netbeans/modules/python/source/ImportEntry.java Wed Sep 02 20:31:18 2015 +0200
146.3 @@ -0,0 +1,171 @@
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 + * The Original Software is NetBeans. The Initial Developer of the Original
146.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
146.34 + * Microsystems, Inc. All Rights Reserved.
146.35 + *
146.36 + * If you wish your version of this file to be governed by only the CDDL
146.37 + * or only the GPL Version 2, indicate your decision by adding
146.38 + * "[Contributor] elects to include this software in this distribution
146.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
146.40 + * single choice of license, a recipient has the option to distribute
146.41 + * your version of this file under either the CDDL, the GPL Version 2 or
146.42 + * to extend the choice of license to its licensees as provided above.
146.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
146.44 + * Version 2 license, then the option applies only if the new code is
146.45 + * made subject to such option by the copyright holder.
146.46 + */
146.47 +package org.netbeans.modules.python.source;
146.48 +
146.49 +import org.python.antlr.PythonTree;
146.50 +
146.51 +/**
146.52 + * State about a single atomic import. (A single import statement in Python
146.53 + * can correspond to many atomic imports: one for each symbol or module
146.54 + * imported)
146.55 + *
146.56 + * @author Tor Norbye
146.57 + */
146.58 +public class ImportEntry implements Comparable<ImportEntry> {
146.59 + public final String module;
146.60 + public final String asName;
146.61 + public final String symbol;
146.62 + public final boolean isSystem;
146.63 + public final boolean isFromImport;
146.64 + /**
146.65 + * Natural order of import statements (in the source). This will be non zero if
146.66 + * we want to preserve the original order rather than the alphabetical order.
146.67 + */
146.68 + public int ordinal;
146.69 + /**
146.70 + * Corresponding import statement node. This will be non null if we want to consider
146.71 + * duplicate import statements as different
146.72 + */
146.73 + public PythonTree node;
146.74 + /**
146.75 + * Whether we have a symbol import AND we're sorting by symbol imports.
146.76 + * Will be false even for symbol imports when we're not sorting by symbols.
146.77 + */
146.78 + public boolean sortedFrom;
146.79 +
146.80 + public ImportEntry(String module, String symbol, String asName, boolean isSystem, PythonTree node, int ordinal) {
146.81 + super();
146.82 + this.module = module;
146.83 + this.symbol = symbol;
146.84 + this.asName = asName;
146.85 + this.isSystem = isSystem;
146.86 + this.isFromImport = symbol != null;
146.87 + this.node = node;
146.88 + this.ordinal = ordinal;
146.89 +
146.90 + this.sortedFrom = symbol != null;
146.91 + }
146.92 +
146.93 + public ImportEntry(String module, String asName, boolean isSystem, PythonTree node, int ordinal) {
146.94 + this(module, null, asName, isSystem, node, ordinal);
146.95 + }
146.96 +
146.97 + @Override
146.98 + public boolean equals(Object obj) {
146.99 + if (obj == null) {
146.100 + return false;
146.101 + }
146.102 + if (getClass() != obj.getClass()) {
146.103 + return false;
146.104 + }
146.105 + final ImportEntry other = (ImportEntry)obj;
146.106 + if (this.node != other.node) {
146.107 + return false;
146.108 + }
146.109 + if ((this.module == null) ? (other.module != null) : !this.module.equals(other.module)) {
146.110 + return false;
146.111 + }
146.112 + if ((this.asName == null) ? (other.asName != null) : !this.asName.equals(other.asName)) {
146.113 + return false;
146.114 + }
146.115 + if ((this.symbol == null) ? (other.symbol != null) : !this.symbol.equals(other.symbol)) {
146.116 + return false;
146.117 + }
146.118 + return true;
146.119 + }
146.120 +
146.121 + @Override
146.122 + public int hashCode() {
146.123 + int hash = 7;
146.124 + hash = 29 * hash + (this.module != null ? this.module.hashCode() : 0);
146.125 + return hash;
146.126 + }
146.127 +
146.128 + @Override
146.129 + public int compareTo(ImportEntry other) {
146.130 + boolean thisIsFuture = "__future__".equals(module); // NOI18N
146.131 + boolean otherIsFuture = "__future__".equals(other.module); // NOI18N
146.132 + if (thisIsFuture != otherIsFuture) {
146.133 + return thisIsFuture ? -1 : 1;
146.134 + }
146.135 + if (isSystem != other.isSystem) {
146.136 + return isSystem ? -1 : 1;
146.137 + }
146.138 + if (sortedFrom != other.sortedFrom) {
146.139 + return sortedFrom ? 1 : -1;
146.140 + }
146.141 + if (ordinal != other.ordinal) {
146.142 + return ordinal - other.ordinal;
146.143 + }
146.144 + // Then we sort by module name
146.145 + int result = module.compareTo(other.module);
146.146 + if (result != 0) {
146.147 + return result;
146.148 + }
146.149 + // And then, for each module, first the imports, then the from imports
146.150 + if (isFromImport != other.isFromImport) {
146.151 + return isFromImport ? 1 : -1;
146.152 + }
146.153 + if (symbol != null) {
146.154 + assert other.symbol != null;
146.155 + // since isFromImport==
146.156 + result = symbol.compareTo(other.symbol);
146.157 + if (result != 0) {
146.158 + return result;
146.159 + }
146.160 + }
146.161 + if (asName == null) {
146.162 + return (other.asName == null) ? 0 : 1;
146.163 + }
146.164 + if (other.asName == null) {
146.165 + return -1;
146.166 + }
146.167 + return asName.compareTo(other.asName);
146.168 + }
146.169 +
146.170 + @Override
146.171 + public String toString() {
146.172 + return "ImportEntry(" + module + ", " + symbol + ", " + asName + ")"; // NOI18N
146.173 + }
146.174 +}
147.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147.2 +++ b/python.source/src/org/netbeans/modules/python/source/ImportManager.java Wed Sep 02 20:31:18 2015 +0200
147.3 @@ -0,0 +1,1048 @@
147.4 +/*
147.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
147.6 + *
147.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
147.8 + *
147.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
147.10 + * Other names may be trademarks of their respective owners.
147.11 + *
147.12 + * The contents of this file are subject to the terms of either the GNU
147.13 + * General Public License Version 2 only ("GPL") or the Common
147.14 + * Development and Distribution License("CDDL") (collectively, the
147.15 + * "License"). You may not use this file except in compliance with the
147.16 + * License. You can obtain a copy of the License at
147.17 + * http://www.netbeans.org/cddl-gplv2.html
147.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
147.19 + * specific language governing permissions and limitations under the
147.20 + * License. When distributing the software, include this License Header
147.21 + * Notice in each file and include the License file at
147.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
147.23 + * particular file as subject to the "Classpath" exception as provided
147.24 + * by Oracle in the GPL Version 2 section of the License file that
147.25 + * accompanied this code. If applicable, add the following below the
147.26 + * License Header, with the fields enclosed by brackets [] replaced by
147.27 + * your own identifying information:
147.28 + * "Portions Copyrighted [year] [name of copyright owner]"
147.29 + *
147.30 + * If you wish your version of this file to be governed by only the CDDL
147.31 + * or only the GPL Version 2, indicate your decision by adding
147.32 + * "[Contributor] elects to include this software in this distribution
147.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
147.34 + * single choice of license, a recipient has the option to distribute
147.35 + * your version of this file under either the CDDL, the GPL Version 2 or
147.36 + * to extend the choice of license to its licensees as provided above.
147.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
147.38 + * Version 2 license, then the option applies only if the new code is
147.39 + * made subject to such option by the copyright holder.
147.40 + *
147.41 + * Contributor(s):
147.42 + *
147.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
147.44 + */
147.45 +package org.netbeans.modules.python.source;
147.46 +
147.47 +import java.awt.Toolkit;
147.48 +import java.util.ArrayList;
147.49 +import java.util.Collection;
147.50 +import java.util.Collections;
147.51 +import java.util.HashMap;
147.52 +import java.util.HashSet;
147.53 +import java.util.List;
147.54 +import java.util.Map;
147.55 +import java.util.Set;
147.56 +import javax.swing.text.BadLocationException;
147.57 +import org.netbeans.api.editor.EditorRegistry;
147.58 +import org.netbeans.editor.BaseDocument;
147.59 +import org.netbeans.editor.Utilities;
147.60 +import org.netbeans.modules.csl.api.EditList;
147.61 +import org.netbeans.modules.csl.api.OffsetRange;
147.62 +import org.netbeans.modules.csl.spi.GsfUtilities;
147.63 +import org.netbeans.modules.editor.indent.api.IndentUtils;
147.64 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
147.65 +import org.netbeans.modules.python.source.ImportEntry;
147.66 +import org.netbeans.modules.python.source.PythonAstUtils;
147.67 +import org.netbeans.modules.python.source.PythonIndex;
147.68 +import org.netbeans.modules.python.source.PythonParserResult;
147.69 +import org.netbeans.modules.python.source.elements.IndexedElement;
147.70 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
147.71 +import org.netbeans.modules.python.source.CodeStyle;
147.72 +import org.netbeans.modules.python.source.CodeStyle.ImportCleanupStyle;
147.73 +import org.netbeans.modules.python.source.scopes.SymbolTable;
147.74 +import org.netbeans.modules.python.source.scopes.SymInfo;
147.75 +import org.openide.util.Exceptions;
147.76 +import org.openide.util.NbBundle;
147.77 +import org.python.antlr.PythonTree;
147.78 +import org.python.antlr.ast.Import;
147.79 +import org.python.antlr.ast.ImportFrom;
147.80 +import org.python.antlr.ast.Str;
147.81 +import org.python.antlr.ast.alias;
147.82 +
147.83 +/**
147.84 + * Computations regarding module imports.
147.85 + *
147.86 + * @todo Handle commenting out portions of imports
147.87 + * @todo If I can make this fast, consider highlighting unused imports.
147.88 + * @todo On code completion I should import the corresponding package+class (make the
147.89 + * class part optional)
147.90 + * @todo Watch out for commented out imports getting wiped out in organize imports
147.91 + * because it's between imports. These need to be moved to the end!!!
147.92 + * @todo Offer to group imports
147.93 + * @todo Don't import functions
147.94 + *
147.95 + * @author Tor Norbye
147.96 + */
147.97 +public final class ImportManager {
147.98 +
147.99 + private PythonParserResult info;
147.100 + private List<Import> imports;
147.101 + private List<ImportFrom> importsFrom;
147.102 + private PythonTree root;
147.103 + private BaseDocument doc;
147.104 + private List<PythonTree> mainImports;
147.105 + private Set<PythonTree> topLevelImports;
147.106 +
147.107 + // Settings
147.108 + private boolean systemLibsFirst = true;
147.109 + private boolean splitImports = true;
147.110 + private boolean sortImports = true;
147.111 + private boolean separateFromImps = false;
147.112 + private ImportCleanupStyle cleanup = ImportCleanupStyle.COMMENT_OUT;
147.113 + private boolean removeDuplicates;
147.114 + private int rightMargin;
147.115 +
147.116 + public ImportManager(PythonParserResult info) {
147.117 + this(info, GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false), null);
147.118 + }
147.119 +
147.120 + public ImportManager(PythonParserResult info, BaseDocument doc) {
147.121 + this(info, doc, null);
147.122 + }
147.123 +
147.124 + public ImportManager(PythonParserResult info, BaseDocument doc, CodeStyle codeStyle) {
147.125 + this.info = info;
147.126 +
147.127 + root = PythonAstUtils.getRoot(info);
147.128 +
147.129 + SymbolTable symbolTable = PythonAstUtils.getParseResult(info).getSymbolTable();
147.130 + imports = symbolTable.getImports();
147.131 + importsFrom = symbolTable.getImportsFrom();
147.132 + topLevelImports = symbolTable.getTopLevelImports();
147.133 + mainImports = symbolTable.getMainImports();
147.134 +
147.135 + this.doc = doc;
147.136 +
147.137 + if (codeStyle == null) {
147.138 + codeStyle = CodeStyle.getDefault(doc);
147.139 + }
147.140 + systemLibsFirst = codeStyle.systemLibsFirst();
147.141 + splitImports = codeStyle.oneImportPerLine();
147.142 + cleanup = codeStyle.cleanupImports();
147.143 + sortImports = codeStyle.sortImports();
147.144 + separateFromImps = codeStyle.separateFromImps();
147.145 + if (separateFromImps) {
147.146 + sortImports = true;
147.147 + }
147.148 + removeDuplicates = codeStyle.removeDuplicates();
147.149 + rightMargin = codeStyle.getRightMargin();
147.150 +
147.151 + }
147.152 +
147.153 + public static boolean isFutureImport(ImportFrom fromStatement) {
147.154 + return "__future__".equals(fromStatement.getInternalModule()); // NOI18N
147.155 + }
147.156 +
147.157 + public void setCleanup(ImportCleanupStyle cleanup) {
147.158 + this.cleanup = cleanup;
147.159 + }
147.160 +
147.161 + public void cleanup(EditList edits, int startOffset, int endOffset, boolean force) {
147.162 + OffsetRange lexRange = getMainImportsRange();
147.163 + if (lexRange == OffsetRange.NONE ||
147.164 + !(new OffsetRange(startOffset, endOffset).overlaps(lexRange))) {
147.165 + // Not touching imports
147.166 + return;
147.167 + }
147.168 +
147.169 + if (cleanup != ImportCleanupStyle.LEAVE_ALONE) {
147.170 + List<String> ambiguousSymbols = new ArrayList<>();
147.171 + Map<String, String> defaultLists = new HashMap<>();
147.172 + Map<String, List<String>> alternatives = new HashMap<>();
147.173 + Set<ImportEntry> unused = new HashSet<>();
147.174 + Set<ImportEntry> duplicates = new HashSet<>();
147.175 +
147.176 + computeImports(ambiguousSymbols, defaultLists, alternatives, unused, duplicates);
147.177 + if (ambiguousSymbols.size() == 0 || force) {
147.178 + apply(edits, new String[0], unused, duplicates);
147.179 + return;
147.180 + }
147.181 + } else if (removeDuplicates) {
147.182 + Set<ImportEntry> duplicates = findDuplicates();
147.183 + apply(edits, new String[0], Collections.<ImportEntry>emptySet(), duplicates);
147.184 + return;
147.185 + }
147.186 +
147.187 + apply(edits, new String[0], Collections.<ImportEntry>emptySet(), Collections.<ImportEntry>emptySet());
147.188 + }
147.189 +
147.190 + public List<Import> getImports() {
147.191 + return imports;
147.192 + }
147.193 +
147.194 + public List<ImportFrom> getImportsFrom() {
147.195 + return importsFrom;
147.196 + }
147.197 +
147.198 + private Set<ImportEntry> findDuplicates() {
147.199 + Set<ImportEntry> duplicates = new HashSet<>();
147.200 + // TODO!
147.201 +
147.202 + return duplicates;
147.203 + }
147.204 +
147.205 + public boolean computeImports(
147.206 + List<String> ambiguousSymbols,
147.207 + Map<String, String> defaults,
147.208 + Map<String, List<String>> alternatives, Set<ImportEntry> unused, Set<ImportEntry> duplicates) {
147.209 +
147.210 + boolean ambiguous = false;
147.211 +
147.212 + SymbolTable symbolTable = new SymbolTable(PythonAstUtils.getRoot(info), info.getSnapshot().getSource().getFileObject());
147.213 + Map<String, SymInfo> unresolved = symbolTable.getUnresolvedNames(info);
147.214 +
147.215 + if (unresolved.size() > 0) {
147.216 + ambiguousSymbols.addAll(unresolved.keySet());
147.217 + Collections.sort(ambiguousSymbols);
147.218 +
147.219 + // Try to compute suggestions.
147.220 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
147.221 + Set<IndexedElement> modules = index.getModules("", QuerySupport.Kind.PREFIX);
147.222 + for (IndexedElement module : modules) {
147.223 + String name = module.getName();
147.224 + if (unresolved.containsKey(name)) {
147.225 + List<String> list = new ArrayList<>(4);
147.226 + list.add(name);
147.227 + defaults.put(name, name);
147.228 + alternatives.put(name, list);
147.229 + }
147.230 + }
147.231 +
147.232 + List<String> unresolvedList = new ArrayList<>(unresolved.keySet());
147.233 + Collections.sort(unresolvedList);
147.234 + for (String symbol : unresolvedList) {
147.235 + // TODO - determine if it's a call or variable
147.236 + // TODO - track import usages too!
147.237 + Collection<String> importsFor = index.getImportsFor(symbol, true);
147.238 + // TODO - insert symbols + " (whole module)"
147.239 + if (importsFor.size() > 0) {
147.240 + if (importsFor.size() > 1) {
147.241 + List<String> l = new ArrayList<>(importsFor);
147.242 + Collections.sort(l);
147.243 + importsFor = l;
147.244 + }
147.245 + List<String> list = alternatives.get(symbol);
147.246 + if (list == null) {
147.247 + list = new ArrayList<>();
147.248 + alternatives.put(symbol, list);
147.249 + }
147.250 + for (String s : importsFor) {
147.251 + if (!list.contains(s)) {
147.252 + list.add(s);
147.253 + }
147.254 + }
147.255 + if (list.size() > 1) {
147.256 + ambiguous = true;
147.257 + }
147.258 +
147.259 + // TODO - if it's a call, try to match functions instead of imported symbols
147.260 + } else {
147.261 + ambiguous = true;
147.262 + }
147.263 + }
147.264 +
147.265 + // TODO - look up -functions- and -data- defined across all modules
147.266 + // that might define these guys
147.267 +
147.268 + }
147.269 +
147.270 + List<String> unambiguousNames = new ArrayList<>();
147.271 + for (Map.Entry<String, List<String>> entry : alternatives.entrySet()) {
147.272 + List<String> list = entry.getValue();
147.273 + if (list == null || list.size() == 0) {
147.274 + ambiguous = true;
147.275 + } else if (list.size() == 1) {
147.276 + String key = entry.getKey();
147.277 + unambiguousNames.add(key);
147.278 + }
147.279 + }
147.280 +
147.281 + // If we've had to choose certain libraries (e.g. because they're the
147.282 + // only choice available in some cases) then make those libraries default
147.283 + // for all the ambiguous cases as well
147.284 + if (!unambiguousNames.isEmpty()) {
147.285 + for (String name : alternatives.keySet()) {
147.286 + List<String> list = alternatives.get(name);
147.287 + for (String choice : list) {
147.288 + if (unambiguousNames.contains(choice)) {
147.289 + defaults.put(name, choice);
147.290 + }
147.291 + }
147.292 + }
147.293 + }
147.294 +
147.295 + unused.addAll(symbolTable.getUnusedImports());
147.296 +
147.297 +// During development
147.298 +//ambiguous = true;
147.299 +
147.300 + return ambiguous;
147.301 + }
147.302 +
147.303 + public void apply(EditList edits, String[] selections, Set<ImportEntry> removeEntries, Set<ImportEntry> duplicates) {
147.304 + // Update the imports
147.305 + // Sort the imports
147.306 + // Delete the unused imports
147.307 + boolean apply = false;
147.308 + if (edits == null) {
147.309 + edits = new EditList(doc);
147.310 + apply = true;
147.311 + }
147.312 +
147.313 + Set<PythonTree> removedAlready = new HashSet<>();
147.314 +
147.315 + Set<PythonTree> mainImport;
147.316 + //if (sortImports) {
147.317 + mainImport = new HashSet<>(mainImports);
147.318 + //} else {
147.319 + // mainImport = Collections.<PythonTree>emptySet();
147.320 + //}
147.321 + Set<PythonTree> topLevel = topLevelImports;
147.322 +
147.323 +//
147.324 +// // Remove duplicates. Note - these are always removed, not just commented out.
147.325 +// if (duplicates.size() > 0 && cleanup != ImportCleanupStyle.LEAVE_ALONE) {
147.326 +// Set<PythonTree> candidates = new HashSet<PythonTree>();
147.327 +// // Map from import node to list of names that should be removed, if only some are duplicates
147.328 +// Map<PythonTree,List<String>> names = new HashMap<PythonTree,List<String>>();
147.329 +// // Find the corresponding import
147.330 +// //List<PythonTree> candidates = new ArrayList<PythonTree>();
147.331 +// boolean foundFirst = false;
147.332 +// for (Import imp : imports) {
147.333 +// if (imp.names != null) {
147.334 +// boolean all = true;
147.335 +// boolean some = false;
147.336 +// for (alias at : imp.getInternalNames()) {
147.337 +// if (duplicates.contains(at.getInternalName())) {
147.338 +// if (!foundFirst) {
147.339 +// foundFirst = true;
147.340 +// } else {
147.341 +// some = true;
147.342 +// List<String> nameList = names.get(imp);
147.343 +// if (nameList == null) {
147.344 +// nameList = new ArrayList<String>();
147.345 +// names.put(imp, nameList);
147.346 +// }
147.347 +// nameList.add(at.getInternalName());
147.348 +// }
147.349 +// break;
147.350 +// } else {
147.351 +// all = false;
147.352 +// }
147.353 +// }
147.354 +// if (some) {
147.355 +// candidates.add(imp);
147.356 +// if (all) {
147.357 +// // No need to limit deletion to just one
147.358 +// names.put(imp, null);
147.359 +// }
147.360 +// }
147.361 +// }
147.362 +// }
147.363 +//
147.364 +// for (ImportFrom from : importsFrom) {
147.365 +// if (from.names != null) {
147.366 +// boolean all = true;
147.367 +// boolean some = false;
147.368 +// for (alias at : from.names) {
147.369 +// assert at.getInternalName() != null;
147.370 +// String value;
147.371 +// if (at.getInternalAsname() != null) {
147.372 +// value = from.module + ":" + at.getInternalName() + ":" + at.getInternalAsname();
147.373 +// } else {
147.374 +// value = from.module + ":" + at.getInternalName();
147.375 +// }
147.376 +// if (duplicates.contains(value)) {
147.377 +// if (!foundFirst) {
147.378 +// foundFirst = true;
147.379 +// } else {
147.380 +// some = true;
147.381 +// List<String> nameList = names.get(from);
147.382 +// if (nameList == null) {
147.383 +// nameList = new ArrayList<String>();
147.384 +// names.put(from, nameList);
147.385 +// }
147.386 +// nameList.add(at.getInternalName());
147.387 +// }
147.388 +// } else {
147.389 +// all = false;
147.390 +// }
147.391 +// }
147.392 +// if (some) {
147.393 +// candidates.add(from);
147.394 +// if (all) {
147.395 +// // No need to limit deletion to just one
147.396 +// names.put(from, null);
147.397 +// }
147.398 +// }
147.399 +// }
147.400 +// }
147.401 +//
147.402 +// Set<PythonTree> filtered = new HashSet<PythonTree>();
147.403 +// for (PythonTree node : candidates) {
147.404 +// if (!mainImport.contains(node) && topLevel.contains(node)) {
147.405 +// filtered.add(node);
147.406 +// }
147.407 +// }
147.408 +//
147.409 +// removedAlready.addAll(filtered);
147.410 +//
147.411 +// // Note - we always REMOVE duplicate imports rather than just commenting
147.412 +// // them out. We may sometimes be wrong about unused imports, so we let
147.413 +// // users leave them commented out when we clean up to make it easier
147.414 +// // to backtrack if we were wrong. However, duplicate imports is something
147.415 +// // we can accurately detect and leaving them commented out isn't something
147.416 +// // users will probably want.
147.417 +// removeImports(edits, filtered, /*commentOut*/false, names);
147.418 +// }
147.419 +
147.420 + if (cleanup == ImportCleanupStyle.LEAVE_ALONE) {
147.421 + removeEntries.clear();
147.422 + } else {
147.423 + Set<ImportEntry> newSet = new HashSet<>();
147.424 + Set<PythonTree> filtered = new HashSet<>();
147.425 + for (ImportEntry entry : removeEntries) {
147.426 + PythonTree node = entry.node;
147.427 + if (!mainImport.contains(node) && topLevel.contains(node)) {
147.428 + filtered.add(node);
147.429 + } else {
147.430 + if (removeDuplicates) {
147.431 + entry.node = null;
147.432 + }
147.433 + if (sortImports) {
147.434 + entry.ordinal = 0;
147.435 + }
147.436 + if (!separateFromImps) {
147.437 + entry.sortedFrom = false;
147.438 + }
147.439 + }
147.440 +
147.441 + newSet.add(entry);
147.442 + }
147.443 + removeEntries = newSet;
147.444 +// int ordinal = 0;
147.445 +// if (unused.size() > 0 && cleanup != ImportCleanupStyle.LEAVE_ALONE) {
147.446 +// Set<PythonTree> candidates = new HashSet<PythonTree>();
147.447 +// Map<PythonTree,List<String>> names = new HashMap<PythonTree,List<String>>();
147.448 +// // Find the corresponding import
147.449 +// //List<PythonTree> candidates = new ArrayList<PythonTree>();
147.450 +// for (Import imp : imports) {
147.451 +// if (imp.names != null) {
147.452 +// boolean all = true;
147.453 +// boolean some = false;
147.454 +// for (alias at : imp.getInternalNames()) {
147.455 +// if (unused.contains(at.getInternalName())) {
147.456 +// some = true;
147.457 +// List<String> nameList = names.get(imp);
147.458 +// if (nameList == null) {
147.459 +// nameList = new ArrayList<String>();
147.460 +// names.put(imp, nameList);
147.461 +// }
147.462 +// nameList.add(at.getInternalName());
147.463 +//
147.464 +// boolean isSystem = false; // Don't care what it is for deletion
147.465 +// removeEntries.add(new ImportEntry(at.getInternalName(), at.getInternalAsname(), isSystem,
147.466 +// removeDuplicates ? null : imp,
147.467 +// sortImports ? 0 : ordinal++));
147.468 +// break;
147.469 +// } else {
147.470 +// all = false;
147.471 +// }
147.472 +// }
147.473 +//
147.474 +// if (some) {
147.475 +// candidates.add(imp);
147.476 +// if (all) {
147.477 +// // No need to limit deletion to just one
147.478 +// names.put(imp, null);
147.479 +// }
147.480 +// }
147.481 +// }
147.482 +// }
147.483 +//
147.484 +// for (ImportFrom from : importsFrom) {
147.485 +// if (from.names != null) {
147.486 +// boolean all = true;
147.487 +// boolean some = false;
147.488 +// for (alias at : from.names) {
147.489 +// boolean isSystem = false; // Don't care what it is for deletion
147.490 +//
147.491 +// assert at.getInternalName() != null;
147.492 +// String value;
147.493 +// if (at.getInternalAsname() != null) {
147.494 +// value = from.module + ":" + at.getInternalName() + ":" + at.getInternalAsname();
147.495 +// } else {
147.496 +// value = from.module + ":" + at.getInternalName();
147.497 +// }
147.498 +// if (unused.contains(value)) {
147.499 +// removeEntries.add(new ImportEntry(from.module, at.getInternalName(), at.getInternalAsname(), isSystem,
147.500 +// removeDuplicates ? null : from,
147.501 +// sortImports ? 0 : ordinal++));
147.502 +// some = true;
147.503 +// List<String> nameList = names.get(from);
147.504 +// if (nameList == null) {
147.505 +// nameList = new ArrayList<String>();
147.506 +// names.put(from, nameList);
147.507 +// }
147.508 +// nameList.add(at.getInternalName());
147.509 +// } else {
147.510 +// all = false;
147.511 +// }
147.512 +// }
147.513 +// if (some) {
147.514 +// candidates.add(from);
147.515 +// if (all) {
147.516 +// // No need to limit deletion to just one
147.517 +// names.put(from, null);
147.518 +// }
147.519 +// }
147.520 +// }
147.521 +// }
147.522 +//
147.523 +// // Don't try to delete nodes we've already deleted or commented out
147.524 +// // because they are unused
147.525 +//
147.526 +// candidates.removeAll(removedAlready);
147.527 +//
147.528 +// Set<PythonTree> filtered = new HashSet<PythonTree>();
147.529 +// for (PythonTree node : candidates) {
147.530 +// if (!mainImport.contains(node) && topLevel.contains(node)) {
147.531 +// filtered.add(node);
147.532 +// }
147.533 +// }
147.534 +
147.535 + removeImports(edits, filtered, cleanup == ImportCleanupStyle.COMMENT_OUT, null);
147.536 + }
147.537 +
147.538 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
147.539 +
147.540 + Collection<ImportEntry> newEntries = new ArrayList<>();
147.541 + if (selections != null) {
147.542 + for (String module : selections) {
147.543 + if (module.startsWith("<html>")) { // NOI18N
147.544 + // Skip cannot resolve stuff
147.545 + continue;
147.546 + }
147.547 + int colon = module.indexOf(':');
147.548 + if (colon != -1) {
147.549 + int end = module.indexOf('(', colon + 1);
147.550 + if (end == -1) {
147.551 + end = module.indexOf(';', colon + 1);
147.552 + if (end == -1) {
147.553 + end = module.length();
147.554 + }
147.555 + }
147.556 + String symbol = module.substring(colon + 1, end).trim();
147.557 + module = module.substring(0, colon).trim();
147.558 + boolean isSystem = systemLibsFirst && index.isSystemModule(module);
147.559 + ImportEntry importEntry = new ImportEntry(module, symbol, null, isSystem, null, 0);
147.560 + if (!separateFromImps) {
147.561 + importEntry.sortedFrom = false;
147.562 + }
147.563 + newEntries.add(importEntry);
147.564 + } else {
147.565 + boolean isSystem = systemLibsFirst && index.isSystemModule(module);
147.566 + ImportEntry importEntry = new ImportEntry(module, null, null, isSystem, null, 0);
147.567 + if (!separateFromImps) {
147.568 + importEntry.sortedFrom = false;
147.569 + }
147.570 + newEntries.add(importEntry);
147.571 + }
147.572 + }
147.573 + }
147.574 +
147.575 + rewriteMainImports(edits, newEntries, removeEntries);
147.576 +
147.577 + if (apply) {
147.578 + edits.apply();
147.579 + }
147.580 + }
147.581 +
147.582 + public boolean isTopLevel(PythonTree node) {
147.583 + return topLevelImports.contains(node);
147.584 + }
147.585 +
147.586 + /**
147.587 + * Remove or comment out the given import statements (Import or ImportFrom).
147.588 + * @param edits The edit list to add edits for comment or removal
147.589 + * @param candidates The set of Import or ImportFrom nodes
147.590 + * @param commentOut If true, comment out the import, or else, delete it
147.591 + * @param onlyNames A map from nodes to lists where if the list is null,
147.592 + * remove or comment out the entire import, otherwise comment
147.593 + * or delete only the specified name portions.
147.594 + */
147.595 + public void removeImports(EditList edits, Set<PythonTree> candidates, boolean commentOut, Map<PythonTree, List<String>> onlyNames) {
147.596 + for (PythonTree node : candidates) {
147.597 + // Don't touch imports that aren't top level!!!
147.598 + // These can be inside If blocks and such so we don't
147.599 + // have enough knowledge to mess with them
147.600 + if (!isTopLevel(node)) {
147.601 + continue;
147.602 + }
147.603 +
147.604 + OffsetRange astRange = PythonAstUtils.getRange(node);
147.605 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
147.606 + if (lexRange == OffsetRange.NONE) {
147.607 + continue;
147.608 + }
147.609 +
147.610 + List<String> names = onlyNames.get(node);
147.611 + if (names != null) {
147.612 +
147.613 + // TODO Handle commenting out portions of a line! An idea which
147.614 + // might work is to replace the whole import with a new import
147.615 + // that moves the commented out portions to the end!!
147.616 +
147.617 + // Only delete/comment out a portion of the line
147.618 +// if (commentOut) {
147.619 +// TODO
147.620 +// } else {
147.621 + // Determine offsets within the line
147.622 + List<OffsetRange> ranges = new ArrayList<>();
147.623 + try {
147.624 + int start = lexRange.getStart();
147.625 + int end = lexRange.getEnd();
147.626 + if (end > doc.getLength()) {
147.627 + end = doc.getLength();
147.628 + if (start > doc.getLength()) {
147.629 + start = doc.getLength();
147.630 + }
147.631 + }
147.632 + String line = doc.getText(start, end - start);
147.633 + for (String name : names) {
147.634 + int index = line.indexOf(name);
147.635 + if (index != -1) {
147.636 + int nameEnd = index + name.length();
147.637 + boolean removedComma = false;
147.638 + for (int i = nameEnd; i < line.length(); i++) {
147.639 + char c = line.charAt(i);
147.640 + if (c == ',') {
147.641 + removedComma = true;
147.642 + nameEnd = i + 1;
147.643 + if (nameEnd < line.length() && line.charAt(nameEnd) == ' ') {
147.644 + // Include space after comma in deletion
147.645 + nameEnd++;
147.646 + }
147.647 + break;
147.648 + } else if (c == ' ' || c == '\t') {
147.649 + continue;
147.650 + } else {
147.651 + break;
147.652 + }
147.653 + }
147.654 + if (!removedComma) {
147.655 + // If I removed the last name on the line there is no
147.656 + // comma at the end, so I should try removing one -before-
147.657 + // the name instead
147.658 + for (int i = index - 1; i >= 0; i--) {
147.659 + char c = line.charAt(i);
147.660 + if (c == ',') {
147.661 + index = i;
147.662 + break;
147.663 + } else if (c == ' ' || c == '\t') {
147.664 + continue;
147.665 + } else {
147.666 + break;
147.667 + }
147.668 + }
147.669 + }
147.670 + OffsetRange remove = new OffsetRange(start + index, start + nameEnd);
147.671 +
147.672 + // Prevent overlaps
147.673 + for (OffsetRange range : ranges) {
147.674 + if (range.overlaps(remove)) {
147.675 + if (range.getStart() < remove.getStart()) {
147.676 + remove = new OffsetRange(range.getEnd(), Math.max(remove.getEnd(), range.getEnd()));
147.677 + } else {
147.678 + remove = new OffsetRange(Math.min(remove.getStart(), range.getStart()), range.getStart());
147.679 + }
147.680 + }
147.681 + }
147.682 +
147.683 + ranges.add(remove);
147.684 + }
147.685 + }
147.686 + int prio = 0;
147.687 + for (OffsetRange range : ranges) {
147.688 + edits.replace(range.getStart(), range.getLength(), null, false, prio++);
147.689 + }
147.690 + } catch (BadLocationException ex) {
147.691 + Exceptions.printStackTrace(ex);
147.692 + }
147.693 +// }
147.694 + } else {
147.695 + int start = lexRange.getStart();
147.696 + if (commentOut) {
147.697 + edits.replace(start, 0, "#", false, 0); // NOI18N
147.698 + } else {
147.699 + int length = lexRange.getLength();
147.700 + // See if this leaves an empty line and if so remove it
147.701 + int endPos = lexRange.getEnd();
147.702 + if (endPos < doc.getLength()) {
147.703 + try {
147.704 + char c = doc.getText(endPos, 1).charAt(0);
147.705 + if (c == '\n') {
147.706 + length++;
147.707 + }
147.708 + } catch (BadLocationException ex) {
147.709 + Exceptions.printStackTrace(ex);
147.710 + }
147.711 + }
147.712 + edits.replace(start, length, null, false, 0);
147.713 + }
147.714 + }
147.715 + }
147.716 + }
147.717 +
147.718 + private OffsetRange getMainImportsRange() {
147.719 + // Compute editor range required
147.720 + int begin = Integer.MAX_VALUE;
147.721 + int end = Integer.MIN_VALUE;
147.722 + OffsetRange lexRange;
147.723 + if (mainImports.size() == 0) {
147.724 + if (mainImports.size() == 1) {
147.725 + OffsetRange astRange = PythonAstUtils.getRange(mainImports.get(0));
147.726 + lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
147.727 + } else {
147.728 + assert mainImports.size() == 0;
147.729 + begin = getImportsLexOffset(null);
147.730 + end = begin;
147.731 + lexRange = new OffsetRange(begin, end);
147.732 + }
147.733 + } else {
147.734 + for (PythonTree node : mainImports) {
147.735 + OffsetRange range = PythonAstUtils.getRange(node);
147.736 + if (range.getStart() < begin) {
147.737 + begin = range.getStart();
147.738 + }
147.739 + if (range.getEnd() > end) {
147.740 + end = range.getEnd();
147.741 + }
147.742 + }
147.743 + OffsetRange astReplace = new OffsetRange(begin, end);
147.744 + lexRange = PythonLexerUtils.getLexerOffsets(info, astReplace);
147.745 + }
147.746 +
147.747 + return lexRange;
147.748 + }
147.749 +
147.750 + public void rewriteMainImports(EditList edits, Collection<ImportEntry> newEntries, Set<ImportEntry> remove) {
147.751 + // Items to be deleted should be deleted after this
147.752 +
147.753 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
147.754 +
147.755 + // TODO:
147.756 + // Look for comments to preserve
147.757 + // Replace the entire editor block
147.758 + Set<ImportEntry> entries = new HashSet<>();
147.759 + int ordinal = 0;
147.760 + for (PythonTree node : mainImports) {
147.761 + if (node instanceof Import) {
147.762 + Import imp = (Import)node;
147.763 + // TODO - look up for at.getInternalName()!
147.764 + List<alias> names = imp.getInternalNames();
147.765 + if (names != null) {
147.766 + for (alias at : names) {
147.767 + ImportEntry importEntry = new ImportEntry(at.getInternalName(), at.getInternalAsname(), systemLibsFirst && index.isSystemModule(at.getInternalName()),
147.768 + removeDuplicates ? null : imp, sortImports ? 0 : ordinal++);
147.769 + if (!separateFromImps) {
147.770 + importEntry.sortedFrom = false;
147.771 + }
147.772 + entries.add(importEntry);
147.773 + }
147.774 + }
147.775 + } else {
147.776 + assert node instanceof ImportFrom;
147.777 + ImportFrom imp = (ImportFrom)node;
147.778 + List<alias> names = imp.getInternalNames();
147.779 + if (names != null && names.size() > 0) {
147.780 + // TODO - look up for imp.getInternalModule()!
147.781 + boolean isSystemLibrary = systemLibsFirst && index.isSystemModule(imp.getInternalModule());
147.782 + for (alias at : names) {
147.783 + ImportEntry importEntry = new ImportEntry(imp.getInternalModule(), at.getInternalName(), at.getInternalAsname(), isSystemLibrary,
147.784 + removeDuplicates ? null : imp, sortImports ? 0 : ordinal++);
147.785 + if (!separateFromImps) {
147.786 + importEntry.sortedFrom = false;
147.787 + }
147.788 + entries.add(importEntry);
147.789 + }
147.790 + }
147.791 + }
147.792 + }
147.793 +
147.794 + // Add in entries discovered as needed by the import manager
147.795 + if (newEntries.size() > 0) {
147.796 + entries.addAll(newEntries);
147.797 + }
147.798 +
147.799 + // Remove any items that needs to be removed
147.800 + if (remove.size() > 0) {
147.801 + entries.removeAll(remove);
147.802 + }
147.803 +
147.804 + // Sort imports -- first by system/nonsystem, then alphabetically
147.805 + List<ImportEntry> sortedEntries = new ArrayList<>(entries);
147.806 + Collections.sort(sortedEntries);
147.807 +
147.808 + // Write out existing imports
147.809 + StringBuilder sb = new StringBuilder();
147.810 + int size = sortedEntries.size();
147.811 + if (size > 0) {
147.812 + boolean prevSystem = sortedEntries.get(0).isSystem;
147.813 +
147.814 + for (int i = 0; i < size; i++) {
147.815 + ImportEntry entry = sortedEntries.get(i);
147.816 + if (systemLibsFirst && entry.isSystem != prevSystem) {
147.817 + prevSystem = entry.isSystem;
147.818 + sb.append("\n"); // NOI18N Separate system and regular libs
147.819 + }
147.820 +
147.821 + if (entry.isFromImport) {
147.822 + int start = sb.length();
147.823 + sb.append("from "); // NOI18N
147.824 + sb.append(entry.module);
147.825 + sb.append(" import "); // NOI18N
147.826 + sb.append(entry.symbol);
147.827 + if (entry.asName != null) {
147.828 + sb.append(" as "); // NOI18N
147.829 + sb.append(entry.asName);
147.830 + }
147.831 +
147.832 + if (!splitImports) {
147.833 + // Look ahead and combine subsequent entries
147.834 + int lookahead = i + 1;
147.835 + for (; lookahead < size; lookahead++) {
147.836 + ImportEntry next = sortedEntries.get(lookahead);
147.837 + if (next.isFromImport != entry.isFromImport ||
147.838 + !next.module.equals(entry.module)) {
147.839 + break;
147.840 + }
147.841 + sb.append(", "); // NOI18N
147.842 +
147.843 + if (sb.length() - start > rightMargin && (rightMargin > 30)) {
147.844 + sb.append("\\\n");
147.845 + start = sb.length();
147.846 + sb.append(IndentUtils.createIndentString(doc, IndentUtils.indentLevelSize(doc)));
147.847 + }
147.848 +
147.849 + sb.append(next.symbol);
147.850 + if (next.asName != null) {
147.851 + sb.append(" as ");
147.852 + sb.append(next.asName);
147.853 + }
147.854 + }
147.855 + i = lookahead - 1;
147.856 + }
147.857 + sb.append("\n"); // NOI18N
147.858 + } else {
147.859 + // Plain import
147.860 + // We never combine imports
147.861 + sb.append("import "); // NOI18N
147.862 + sb.append(entry.module);
147.863 + if (entry.asName != null) {
147.864 + sb.append(" as "); // NOI18N
147.865 + sb.append(entry.asName);
147.866 + }
147.867 + sb.append("\n"); // NOI18N
147.868 + }
147.869 + }
147.870 + }
147.871 +
147.872 + // Write commented out deleted entries as well
147.873 + if (remove.size() > 0 && cleanup == ImportCleanupStyle.COMMENT_OUT) {
147.874 + size = remove.size();
147.875 + List<ImportEntry> sortedRemove = new ArrayList<>();
147.876 + sortedRemove.addAll(remove);
147.877 + Collections.sort(sortedRemove);
147.878 + for (ImportEntry entry : sortedRemove) {
147.879 + if (entry.isFromImport) {
147.880 + sb.append("#from "); // NOI18N
147.881 + sb.append(entry.module);
147.882 + sb.append(" import "); // NOI18N
147.883 + sb.append(entry.symbol);
147.884 + if (entry.asName != null) {
147.885 + sb.append(" as "); // NOI18N
147.886 + sb.append(entry.asName);
147.887 + }
147.888 + sb.append("\n"); // NOI18N
147.889 + } else {
147.890 + sb.append("#import "); // NOI18N
147.891 + sb.append(entry.module);
147.892 + if (entry.asName != null) {
147.893 + sb.append(" as "); // NOI18N
147.894 + sb.append(entry.asName);
147.895 + }
147.896 + sb.append("\n"); // NOI18N
147.897 + }
147.898 + }
147.899 + }
147.900 +
147.901 + // Compute editor range required
147.902 + OffsetRange lexRange = getMainImportsRange();
147.903 +
147.904 + // Replace final newline if it's there so we don't grow whitespace around the imports
147.905 + int lastNewlineDelta = 0;
147.906 + try {
147.907 + if (lexRange.getEnd() < doc.getLength() && doc.getText(lexRange.getEnd(), 1).charAt(0) == '\n') {
147.908 + lastNewlineDelta++;
147.909 + }
147.910 + } catch (BadLocationException ex) {
147.911 + Exceptions.printStackTrace(ex);
147.912 + }
147.913 +
147.914 + edits.replace(lexRange.getStart(), lexRange.getLength() + lastNewlineDelta, sb.toString(), false, 0);
147.915 + }
147.916 +
147.917 + /** Compute the location where the main import block should be located */
147.918 + public int getImportsLexOffset(String module) {
147.919 + int begin = 0;
147.920 +
147.921 + // First try computing a position in the standard imports
147.922 + if (module != null) {
147.923 + PythonTree last = null;
147.924 + for (PythonTree node : mainImports) {
147.925 + boolean stop = false;
147.926 + if (node instanceof Import) {
147.927 + Import imp = (Import)node;
147.928 + List<alias> names = imp.getInternalNames();
147.929 + if (names != null && names.size() > 0 &&
147.930 + names.get(0).getInternalName().compareTo(module) >= 0) {
147.931 + stop = true;
147.932 + }
147.933 + } else {
147.934 + assert node instanceof ImportFrom;
147.935 + ImportFrom imp = (ImportFrom)node;
147.936 + if (imp.getInternalModule().compareTo(module) >= 0) {
147.937 + stop = true;
147.938 + }
147.939 + }
147.940 +
147.941 + if (stop) {
147.942 + return PythonLexerUtils.getLexerOffsets(info,
147.943 + PythonAstUtils.getRange(node)).getStart();
147.944 + }
147.945 +
147.946 + last = node;
147.947 + }
147.948 +
147.949 + if (last != null) {
147.950 + return PythonLexerUtils.getLexerOffsets(info,
147.951 + PythonAstUtils.getRange(last)).getStart();
147.952 + }
147.953 + }
147.954 +
147.955 + Str documentationNode = PythonAstUtils.getDocumentationNode(root);
147.956 + if (documentationNode != null) {
147.957 + int astEnd = documentationNode.getCharStopIndex();
147.958 + begin = PythonLexerUtils.getLexerOffset(info, astEnd);
147.959 + if (begin == -1) {
147.960 + begin = 0;
147.961 + } else {
147.962 + begin = Math.min(doc.getLength(), begin);
147.963 + try {
147.964 + begin = Utilities.getRowEnd(doc, begin) + 1;
147.965 + begin = Math.min(begin, doc.getLength());
147.966 + } catch (BadLocationException ex) {
147.967 + Exceptions.printStackTrace(ex);
147.968 + begin = 0;
147.969 + }
147.970 + }
147.971 + }
147.972 +
147.973 + // TODO - I should even do a lexical lookup for this in case we're in an embedded scenario!
147.974 + return begin;
147.975 + }
147.976 +
147.977 + /** Determine if the given module is imported (for the given symbol) */
147.978 + public boolean isImported(String module, String ident) {
147.979 + for (Import imp : imports) {
147.980 + List<alias> names = imp.getInternalNames();
147.981 + if (names != null) {
147.982 + for (alias at : names) {
147.983 + if (module.equals(at.getInternalName()) && (ident == null || (ident.equals(module) || ident.equals(at.getInternalAsname())))) {
147.984 + return true;
147.985 + }
147.986 + }
147.987 + }
147.988 + }
147.989 +
147.990 + for (ImportFrom from : importsFrom) {
147.991 + if (module.equals(from.getInternalModule())) {
147.992 + // Make sure -this- symbol hasn't been imported!
147.993 + if (ident != null) {
147.994 + List<alias> names = from.getInternalNames();
147.995 + if (names != null) {
147.996 + for (alias at : names) {
147.997 + if (at.getInternalAsname() == null) {
147.998 + // If you have "from module1 import Class1 as Class2", then
147.999 + // "Class1" is not already imported, and "Class2" is.
147.1000 + if (ident.equals(at.getInternalName())) {
147.1001 + return true;
147.1002 + }
147.1003 + } else if (ident.equals(at.getInternalAsname())) {
147.1004 + return true;
147.1005 + }
147.1006 + }
147.1007 + }
147.1008 + }
147.1009 + }
147.1010 + }
147.1011 +
147.1012 + return false;
147.1013 + }
147.1014 +
147.1015 + public void ensureImported(String name, String ident, boolean packageImport, boolean useFqn, boolean warnIfExists) {
147.1016 + // TODO - look up the splitImports setting and add to existing import if possible...
147.1017 +
147.1018 + if (PythonIndex.isBuiltinModule(name)) {
147.1019 + return;
147.1020 + }
147.1021 +
147.1022 + // Test whether already imported
147.1023 + if (isImported(name, ident)) {
147.1024 + if (warnIfExists) {
147.1025 + Utilities.setStatusText(EditorRegistry.lastFocusedComponent(),
147.1026 + NbBundle.getMessage(
147.1027 + ImportManager.class,
147.1028 + packageImport ? "MSG_PackageAlreadyImported" : "MSG_ClassAlreadyImported",
147.1029 + name, ident));
147.1030 + Toolkit.getDefaultToolkit().beep();
147.1031 + }
147.1032 + return;
147.1033 + }
147.1034 +
147.1035 + int begin = getImportsLexOffset(ident);
147.1036 + try {
147.1037 + // TODO - warp to the new import and let you edit the "AS" part??
147.1038 +
147.1039 + if (useFqn || ident == null) {
147.1040 + doc.insertString(begin, "import " + name + "\n", null); // NOI18N
147.1041 + } else if (packageImport) {
147.1042 + //doc.insertString(begin, "import " + name + "\n", null); // NOI18N
147.1043 + doc.insertString(begin, "from " + name + " import *\n", null); // NOI18N
147.1044 + } else {
147.1045 + doc.insertString(begin, "from " + name + " import " + ident + "\n", null); // NOI18N
147.1046 + }
147.1047 + } catch (BadLocationException ble) {
147.1048 + Exceptions.printStackTrace(ble);
147.1049 + }
147.1050 + }
147.1051 +}
148.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
148.2 +++ b/python.source/src/org/netbeans/modules/python/source/NameStyle.java Wed Sep 02 20:31:18 2015 +0200
148.3 @@ -0,0 +1,198 @@
148.4 +/*
148.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
148.6 + *
148.7 + * Copyright 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 + * If you wish your version of this file to be governed by only the CDDL
148.31 + * or only the GPL Version 2, indicate your decision by adding
148.32 + * "[Contributor] elects to include this software in this distribution
148.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
148.34 + * single choice of license, a recipient has the option to distribute
148.35 + * your version of this file under either the CDDL, the GPL Version 2 or
148.36 + * to extend the choice of license to its licensees as provided above.
148.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
148.38 + * Version 2 license, then the option applies only if the new code is
148.39 + * made subject to such option by the copyright holder.
148.40 + *
148.41 + * Contributor(s):
148.42 + *
148.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
148.44 + */
148.45 +
148.46 +package org.netbeans.modules.python.source;
148.47 +
148.48 +import org.openide.util.NbBundle;
148.49 +
148.50 +/**
148.51 + *
148.52 + * @author Tor Norbye
148.53 + */
148.54 +public enum NameStyle {
148.55 + NO_PREFERENCE(NbBundle.getMessage(NameStyle.class, "NoPreference")),
148.56 + LOWERCASE("lowercase"),
148.57 + LOWERCASE_WITH_UNDERSCORES("lowercase_with_underscores"),
148.58 + UPPERCASE("UPPERCASE"),
148.59 + UPPERCASE_WITH_UNDERSCORES("UPPERCASE_WITH_UNDERSCORES"),
148.60 + CAPITALIZED_WORDS("CapitalizedWords"),
148.61 + MIXED_CASE("mixedCase"),
148.62 + CAPITALIZED_WITH_UNDERSCORES("Capitalized_With_Underscores");
148.63 +
148.64 + private String displayName;
148.65 +
148.66 + NameStyle(String displayName) {
148.67 + this.displayName = displayName;
148.68 + }
148.69 +
148.70 + public String getDisplayName() {
148.71 + return displayName;
148.72 + }
148.73 +
148.74 + public boolean complies(String name) {
148.75 + if (name.length() == 0) {
148.76 + return true;
148.77 + }
148.78 +
148.79 + // Always allow one or two "_" at the beginning and end of the name since
148.80 + // these are used to indicate private, builtin, etc.
148.81 + int start = 0;
148.82 + int end = name.length();
148.83 + if (name.startsWith("__")) { // NOI18N
148.84 + start = 2;
148.85 + } else if (name.startsWith("_")) { // NOI18N
148.86 + start = 1;
148.87 + }
148.88 +
148.89 + if (name.endsWith("__")) { // NOI18N
148.90 + end -= 2;
148.91 + } else if (name.endsWith("_")) { // NOI18N
148.92 + end -= 1;
148.93 + }
148.94 +
148.95 + if (start >= end) {
148.96 + return false;
148.97 + }
148.98 +
148.99 + switch (this) {
148.100 + case NO_PREFERENCE:
148.101 + return true;
148.102 +
148.103 + case LOWERCASE_WITH_UNDERSCORES:
148.104 + case LOWERCASE:
148.105 + for (int i = start; i < end; i++) {
148.106 + char c = name.charAt(i);
148.107 + if (c == '_') {
148.108 + if (this != LOWERCASE_WITH_UNDERSCORES) {
148.109 + return false;
148.110 + }
148.111 + } else if (Character.isDigit(c)) {
148.112 + } else if (!Character.isLowerCase(c)) {
148.113 + return false;
148.114 + }
148.115 + }
148.116 +
148.117 + return true;
148.118 +
148.119 +
148.120 + case UPPERCASE:
148.121 + case UPPERCASE_WITH_UNDERSCORES:
148.122 + for (int i = start; i < end; i++) {
148.123 + char c = name.charAt(i);
148.124 + if (c == '_') {
148.125 + if (this != UPPERCASE_WITH_UNDERSCORES) {
148.126 + return false;
148.127 + }
148.128 + } else if (Character.isDigit(c)) {
148.129 + } else if (!Character.isUpperCase(c)) {
148.130 + return false;
148.131 + }
148.132 + }
148.133 +
148.134 + return true;
148.135 +
148.136 + case MIXED_CASE:
148.137 + // TODO - require that characters after _ are capitalized?
148.138 + case CAPITALIZED_WORDS:
148.139 + case CAPITALIZED_WITH_UNDERSCORES:
148.140 + if (this == MIXED_CASE) {
148.141 + // Must begin with lowercase
148.142 + if (!Character.isLowerCase(name.charAt(start))) {
148.143 + return false;
148.144 + }
148.145 + } else if (this == CAPITALIZED_WORDS || this == CAPITALIZED_WITH_UNDERSCORES) {
148.146 + // Must begin with uppercase
148.147 + if (!Character.isUpperCase(name.charAt(start))) {
148.148 + return false;
148.149 + }
148.150 + }
148.151 + for (int i = start+1; i < end; i++) {
148.152 + char c = name.charAt(i);
148.153 + if (c == '_') {
148.154 + if (this != CAPITALIZED_WITH_UNDERSCORES) {
148.155 + return false;
148.156 + }
148.157 + } else if (Character.isDigit(c)) {
148.158 + } else if (!Character.isUpperCase(c) && !Character.isLowerCase(c)) {
148.159 + return false;
148.160 + }
148.161 +
148.162 + // What about digits?
148.163 + }
148.164 +
148.165 + return true;
148.166 + default:
148.167 + assert false : this;
148.168 + }
148.169 +
148.170 + return true;
148.171 + }
148.172 +
148.173 + public static boolean isProtectedName(String name) {
148.174 + // Protected variable starts with a single _
148.175 + // this is a convention only
148.176 + if (!name.startsWith("__")) {
148.177 + // NOI18N
148.178 + if (name.startsWith("_")) {
148.179 + // NOI18N
148.180 + return true;
148.181 + }
148.182 + }
148.183 + return false;
148.184 + }
148.185 +
148.186 + public static boolean isPrivateName(String name) {
148.187 + // Private variables: start with __ but doesn't end with __
148.188 + // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
148.189 + if (name != null && name.startsWith("__") && !name.endsWith("__")) {
148.190 + // NOI18N
148.191 + return true;
148.192 + } else if (name != null && name.startsWith("_") && !name.endsWith("_")) {
148.193 + // NOI18N
148.194 + // From PEP8: Single_leading_underscore: weak "internal use" indicator
148.195 + // (e.g. "from M import *" does not import objects whose name
148.196 + // starts with an underscore).
148.197 + return true;
148.198 + }
148.199 + return false;
148.200 + }
148.201 +}
149.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
149.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonAstUtils.java Wed Sep 02 20:31:18 2015 +0200
149.3 @@ -0,0 +1,1007 @@
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 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
149.33 + */
149.34 +package org.netbeans.modules.python.source;
149.35 +
149.36 +import java.util.ArrayList;
149.37 +import java.util.Collections;
149.38 +import java.util.HashSet;
149.39 +import java.util.Iterator;
149.40 +import java.util.List;
149.41 +import java.util.Set;
149.42 +import java.util.logging.Level;
149.43 +import java.util.logging.Logger;
149.44 +import javax.swing.text.BadLocationException;
149.45 +import javax.swing.text.Document;
149.46 +import org.netbeans.api.lexer.LanguagePath;
149.47 +import org.netbeans.api.lexer.TokenHierarchy;
149.48 +import org.netbeans.api.lexer.TokenSequence;
149.49 +import org.netbeans.api.lexer.TokenUtilities;
149.50 +import org.netbeans.editor.BaseDocument;
149.51 +import org.netbeans.editor.Finder;
149.52 +import org.netbeans.editor.FinderFactory;
149.53 +import org.netbeans.modules.csl.api.ElementKind;
149.54 +import org.netbeans.modules.csl.api.OffsetRange;
149.55 +import org.netbeans.modules.csl.api.StructureItem;
149.56 +import org.netbeans.modules.csl.spi.GsfUtilities;
149.57 +import org.netbeans.modules.csl.spi.ParserResult;
149.58 +import org.netbeans.modules.parsing.api.ParserManager;
149.59 +import org.netbeans.modules.parsing.api.ResultIterator;
149.60 +import org.netbeans.modules.parsing.api.Source;
149.61 +import org.netbeans.modules.parsing.api.UserTask;
149.62 +import org.netbeans.modules.parsing.spi.ParseException;
149.63 +import org.netbeans.modules.python.source.elements.IndexedElement;
149.64 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
149.65 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
149.66 +import org.netbeans.modules.python.source.lexer.PythonCommentTokenId;
149.67 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
149.68 +import org.netbeans.modules.python.source.scopes.SymbolTable;
149.69 +import org.netbeans.modules.python.source.scopes.SymInfo;
149.70 +import org.openide.filesystems.FileObject;
149.71 +import org.openide.util.Exceptions;
149.72 +import org.python.antlr.PythonTree;
149.73 +import org.python.antlr.Visitor;
149.74 +import org.python.antlr.ast.Assign;
149.75 +import org.python.antlr.ast.Attribute;
149.76 +import org.python.antlr.ast.Call;
149.77 +import org.python.antlr.ast.ClassDef;
149.78 +import org.python.antlr.ast.Expr;
149.79 +import org.python.antlr.ast.FunctionDef;
149.80 +import org.python.antlr.ast.Import;
149.81 +import org.python.antlr.ast.ImportFrom;
149.82 +import org.python.antlr.ast.Module;
149.83 +import org.python.antlr.ast.Name;
149.84 +import org.python.antlr.ast.Str;
149.85 +import org.python.antlr.ast.arguments;
149.86 +import org.python.antlr.base.expr;
149.87 +import org.python.antlr.base.stmt;
149.88 +
149.89 +/**
149.90 + * Utility functions for dealing with the Jython AST
149.91 + *
149.92 + * @author Tor Norbye
149.93 + */
149.94 +public class PythonAstUtils {
149.95 + private PythonAstUtils() {
149.96 + // This is just a utility class, no instances expected so private constructor
149.97 + }
149.98 +
149.99 + public static int getAstOffset(ParserResult result, int lexOffset) {
149.100 + if (result != null) {
149.101 + return result.getSnapshot().getEmbeddedOffset(lexOffset);
149.102 + }
149.103 +
149.104 + return lexOffset;
149.105 + }
149.106 +
149.107 + public static OffsetRange getAstOffsets(ParserResult result, OffsetRange lexicalRange) {
149.108 + if (result != null) {
149.109 + int rangeStart = lexicalRange.getStart();
149.110 + int start = result.getSnapshot().getEmbeddedOffset(rangeStart);
149.111 + if (start == rangeStart) {
149.112 + return lexicalRange;
149.113 + } else if (start == -1) {
149.114 + return OffsetRange.NONE;
149.115 + } else {
149.116 + // Assumes the translated range maintains size
149.117 + return new OffsetRange(start, start + lexicalRange.getLength());
149.118 + }
149.119 + }
149.120 + return lexicalRange;
149.121 + }
149.122 +
149.123 + public static PythonParserResult getParseResult(ParserResult result) {
149.124 + if(result == null || !(result instanceof PythonParserResult)) {
149.125 + return null;
149.126 + } else {
149.127 + return ((PythonParserResult)result);
149.128 + }
149.129 + }
149.130 +
149.131 + public static PythonTree getRoot(ParserResult r) {
149.132 + assert r instanceof PythonParserResult;
149.133 +
149.134 + PythonParserResult result = (PythonParserResult)r;
149.135 +
149.136 + return result.getRoot();
149.137 + }
149.138 +
149.139 + /**
149.140 + * Return a range that matches the given node's source buffer range
149.141 + */
149.142 + @SuppressWarnings("unchecked")
149.143 + public static OffsetRange getNameRange(PythonParserResult info, PythonTree node) {
149.144 +// final int type = node.getType();
149.145 +// switch (type) {
149.146 +// case Token.FUNCTION: {
149.147 +// if (node.hasChildren()) {
149.148 +// for (PythonTree child = node.getFirstChild(); child != null; child = child.getNext()) {
149.149 +// if (child.getType() == Token.FUNCNAME) {
149.150 +// return getNameRange(child);
149.151 +// }
149.152 +// }
149.153 +// }
149.154 +//
149.155 +// return getRange(node);
149.156 +// }
149.157 +// case Token.NAME:
149.158 +// case Token.BINDNAME:
149.159 +// case Token.FUNCNAME:
149.160 +// case Token.PARAMETER:
149.161 +// case Token.OBJLITNAME:
149.162 +// int start = node.getSourceStart();
149.163 +// String name = node.getString();
149.164 +// return new OffsetRange(start, start+name.length());
149.165 +// case Token.CALL:
149.166 +// PythonTree namePythonTree = findCallNamePythonTree(node);
149.167 +// if (namePythonTree != null) {
149.168 +// return getNameRange(namePythonTree);
149.169 +// }
149.170 +// }
149.171 +
149.172 + // XXX Is there a faster way to determine if it's a function,
149.173 + // e.g. some kind of "kind" or "id" or "type" enum attribute on the tree node
149.174 + if (node instanceof FunctionDef) {
149.175 + FunctionDef def = (FunctionDef)node;
149.176 + //node.getType();
149.177 +
149.178 + int defStart = def.getCharStartIndex();
149.179 +
149.180 + // Turns out that when you have decorators, the function start offset
149.181 + // -includes- the decorators which precede the "def" keyword, thus we
149.182 + // have to scan forwards to find the true beginning.
149.183 + List<expr> decorators = def.getInternalDecorator_list();
149.184 + if (decorators != null && decorators.size() > 0) {
149.185 + int maxEnd = 0;
149.186 + for (expr expr : decorators) {
149.187 + int exprEnd = expr.getCharStopIndex();
149.188 + if (exprEnd > maxEnd) {
149.189 + maxEnd = exprEnd;
149.190 + }
149.191 + }
149.192 + if (decorators.size() > 1) {
149.193 + maxEnd++;
149.194 + }
149.195 + defStart = maxEnd;
149.196 +
149.197 + // At first I was justlooking for the largest end offset of the decorators,
149.198 + // but if you have additional comments etc. that won't work right, so
149.199 + // in this case, go and look at the actual document
149.200 + if (info != null) {
149.201 + BaseDocument doc = GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false);
149.202 + if (doc != null) {
149.203 + int lexOffset = PythonLexerUtils.getLexerOffset(info, defStart);
149.204 + int limitOffset = PythonLexerUtils.getLexerOffset(info, def.getCharStopIndex());
149.205 + if (lexOffset != -1 && limitOffset != -1) {
149.206 + Finder finder = new FinderFactory.StringFwdFinder("def ", true);
149.207 + try {
149.208 + int foundOffset = doc.find(finder, lexOffset, limitOffset);
149.209 + if (foundOffset != -1) {
149.210 + defStart = foundOffset;
149.211 + }
149.212 + } catch (BadLocationException ex) {
149.213 + Exceptions.printStackTrace(ex);
149.214 + }
149.215 + }
149.216 + }
149.217 + }
149.218 + }
149.219 +
149.220 + // HACK: There's no separate node for the name offset itself, so I need
149.221 + // to figure it out. For now assume that it's exactly 4 characters away
149.222 + // from the beginning of "def" - def plus space. If there are multiple spaces
149.223 + // this won't work. I ought to look in the document and ensure that the character
149.224 + // there in fact is the start of the name, and if not, search forwards for it.
149.225 + int DELTA = 4; // HACK:
149.226 + int start = defStart + DELTA;
149.227 + int end = start + def.getInternalName().length();
149.228 +
149.229 + // TODO - look up offset
149.230 +
149.231 + return new OffsetRange(start, end);
149.232 + } else if (node instanceof ClassDef) {
149.233 + ClassDef def = (ClassDef)node;
149.234 + //node.getType();
149.235 +
149.236 + // HACK: There's no separate node for the name offset itself, so I need
149.237 + // to figure it out. For now assume that it's exactly 6 characters away
149.238 + // from the beginning of "class" - class plus space. If there are multiple spaces
149.239 + // this won't work. I ought to look in the document and ensure that the character
149.240 + // there in fact is the start of the name, and if not, search forwards for it.
149.241 + int DELTA = 6; // HACK:
149.242 + int start = def.getCharStartIndex() + DELTA;
149.243 + int end = start + def.getInternalName().length();
149.244 +
149.245 + // TODO - look up offset
149.246 +
149.247 + return new OffsetRange(start, end);
149.248 + } else if (node instanceof Attribute) {
149.249 + Attribute attr = (Attribute)node;
149.250 + return getNameRange(info, attr.getInternalValue());
149.251 + } else if (node instanceof Call) {
149.252 + Call call = (Call)node;
149.253 + if (call.getInternalFunc() instanceof Name) {
149.254 + return getNameRange(info, call.getInternalFunc());
149.255 + } else if (call.getInternalFunc() instanceof Attribute) {
149.256 + // The call name is in the value part of the name.value part
149.257 + Attribute attr = (Attribute)call.getInternalFunc();
149.258 + int start = attr.getInternalValue().getCharStopIndex() + 1; // +1: Skip .
149.259 + String name = attr.getInternalAttr();
149.260 + return new OffsetRange(start, start + name.length());
149.261 + } else {
149.262 + String name = getCallName(call);
149.263 + if (name != null) {
149.264 + int start = call.getCharStartIndex();
149.265 + return new OffsetRange(start, start + name.length());
149.266 + }
149.267 + }
149.268 + }
149.269 +
149.270 + return getRange(node);
149.271 + }
149.272 +
149.273 + /**
149.274 + * Return a range that matches the given node's source buffer range
149.275 + */
149.276 + @SuppressWarnings("unchecked")
149.277 + public static OffsetRange getRange(PythonTree node) {
149.278 + final int start = node.getCharStartIndex();
149.279 + final int end = node.getCharStopIndex();
149.280 +
149.281 +// assert end >= start : "Invalid offsets for " + node + ": start=" + start + " and end=" + end;
149.282 + if (end < start) {
149.283 + Logger logger = Logger.getLogger(PythonAstUtils.class.getName());
149.284 + logger.log(Level.WARNING, "Invalid offsets for " + node + ": start=" + start + " and end=" + end);
149.285 + return new OffsetRange(start, start);
149.286 + }
149.287 +
149.288 + return new OffsetRange(start, end);
149.289 + }
149.290 +
149.291 + public static boolean isNameNode(PythonTree node) {
149.292 + if (node instanceof Name) {
149.293 + return true;
149.294 + }
149.295 +
149.296 + return false;
149.297 + }
149.298 +
149.299 + /** Return if a function is a staticmethod **/
149.300 + public static boolean isStaticMethod(PythonTree node) {
149.301 + if (node instanceof FunctionDef) {
149.302 + FunctionDef def = (FunctionDef)node;
149.303 + List<expr> decorators = def.getInternalDecorator_list();
149.304 + if (decorators != null && decorators.size() > 0) {
149.305 + for (expr decorator : decorators) {
149.306 + if (decorator instanceof Name) {
149.307 + String decoratorName = ((Name)decorator).getText();
149.308 + if (decoratorName.equals("staticmethod")) { // NOI18N
149.309 + return true;
149.310 + }
149.311 + }
149.312 + }
149.313 + }
149.314 + }
149.315 +
149.316 + return false;
149.317 + }
149.318 +
149.319 + /** Compute the module/class name for the given node path */
149.320 + public static String getFqnName(AstPath path) {
149.321 + StringBuilder sb = new StringBuilder();
149.322 +
149.323 + Iterator<PythonTree> it = path.rootToLeaf();
149.324 +
149.325 + while (it.hasNext()) {
149.326 + PythonTree node = it.next();
149.327 +
149.328 + if (node instanceof ClassDef) {
149.329 + if (sb.length() > 0) {
149.330 + sb.append('.'); // NOI18N
149.331 + }
149.332 + ClassDef cls = (ClassDef)node;
149.333 + sb.append(cls.getInternalName());
149.334 + }
149.335 + }
149.336 +
149.337 + return sb.toString();
149.338 + }
149.339 +
149.340 + /** Return the node for the local scope containing the given node */
149.341 + public static PythonTree getLocalScope(AstPath path) {
149.342 + for (PythonTree node : path) {
149.343 + if (node instanceof FunctionDef) {
149.344 + return node;
149.345 + }
149.346 + }
149.347 +
149.348 + return path.root();
149.349 + }
149.350 +
149.351 + public static PythonTree getClassScope(AstPath path) {
149.352 + for (PythonTree node : path) {
149.353 + if (node instanceof ClassDef) {
149.354 + return node;
149.355 + }
149.356 + }
149.357 +
149.358 + return path.root();
149.359 + }
149.360 +
149.361 + public static ClassDef getClassDef(AstPath path) {
149.362 + for (PythonTree node : path) {
149.363 + if (node instanceof ClassDef) {
149.364 + return (ClassDef)node;
149.365 + }
149.366 + }
149.367 +
149.368 + return null;
149.369 + }
149.370 +
149.371 + public static boolean isClassMethod(AstPath path, FunctionDef def) {
149.372 + // Check to see if (a) the function is inside a class, and (b) it's
149.373 + // not nested in a function
149.374 + for (PythonTree node : path) {
149.375 + if (node instanceof ClassDef) {
149.376 + return true;
149.377 + }
149.378 + // Nested method private to this one?
149.379 + if (node instanceof FunctionDef && node != def) {
149.380 + return false;
149.381 + }
149.382 + }
149.383 +
149.384 + return false;
149.385 + }
149.386 +
149.387 + public static FunctionDef getFuncDef(AstPath path) {
149.388 + for (PythonTree node : path) {
149.389 + if (node instanceof FunctionDef) {
149.390 + return (FunctionDef)node;
149.391 + }
149.392 + }
149.393 +
149.394 + return null;
149.395 + }
149.396 +
149.397 + /**
149.398 + * Return true iff this call looks like a "getter". If we're not sure,
149.399 + * return the default value passed into this method, unknownDefault.
149.400 + */
149.401 + public static boolean isGetter(Call call, boolean unknownDefault) {
149.402 + String name = PythonAstUtils.getCallName(call);
149.403 + if (name == null) {
149.404 + return unknownDefault;
149.405 + }
149.406 +
149.407 + return name.startsWith("get") || name.startsWith("_get"); // NOI18N
149.408 + }
149.409 +
149.410 + public static String getCallName(Call call) {
149.411 + expr func = call.getInternalFunc();
149.412 +
149.413 + return getExprName(func);
149.414 + }
149.415 +
149.416 + public static String getExprName(expr type) {
149.417 + if (type instanceof Attribute) {
149.418 + Attribute attr = (Attribute)type;
149.419 + return attr.getInternalAttr();
149.420 + } else if (type instanceof Name) {
149.421 + return ((Name)type).getInternalId();
149.422 + } else if (type instanceof Call) {
149.423 + Call call = (Call)type;
149.424 + return getExprName(call.getInternalFunc());
149.425 + //} else if (type instanceof Str) {
149.426 + // return ((Str)type).getText();
149.427 + } else {
149.428 + return null;
149.429 + }
149.430 + }
149.431 +
149.432 + public static String getName(PythonTree node) {
149.433 + if (node instanceof Name) {
149.434 + return ((Name)node).getInternalId();
149.435 + }
149.436 + if (node instanceof Attribute) {
149.437 + Attribute attrib = (Attribute)node;
149.438 + String prefix = getName(attrib.getInternalValue());
149.439 + return (prefix + '.' + attrib.getInternalAttr());
149.440 + }
149.441 + NameVisitor visitor = new NameVisitor();
149.442 + try {
149.443 + Object result = visitor.visit(node);
149.444 + if (result instanceof String) {
149.445 + return (String)result;
149.446 + } else {
149.447 + // TODO HANDLE THIS!
149.448 + }
149.449 + } catch (Exception ex) {
149.450 + Exceptions.printStackTrace(ex);
149.451 + }
149.452 +
149.453 + return null;
149.454 + }
149.455 +
149.456 + public static List<String> getParameters(FunctionDef def) {
149.457 + arguments args = def.getInternalArgs();
149.458 + List<String> params = new ArrayList<>();
149.459 +
149.460 + NameVisitor visitor = new NameVisitor();
149.461 +
149.462 + for (expr e : args.getInternalArgs()) {
149.463 + try {
149.464 + Object result = visitor.visit(e);
149.465 + if (result instanceof String) {
149.466 + params.add((String)result);
149.467 + } else {
149.468 + // TODO HANDLE THIS!
149.469 + }
149.470 + } catch (Exception ex) {
149.471 + Exceptions.printStackTrace(ex);
149.472 + }
149.473 + }
149.474 +
149.475 + String vararg = args.getInternalVararg();
149.476 + if (vararg != null) {
149.477 + params.add(vararg);
149.478 + }
149.479 + String kwarg = args.getInternalKwarg();
149.480 + if (kwarg != null) {
149.481 + params.add(kwarg);
149.482 + }
149.483 +
149.484 + return params;
149.485 + }
149.486 +
149.487 + private static Str searchForDocNode(stmt stmt) {
149.488 + if (stmt instanceof Expr) {
149.489 + Expr expr = (Expr)stmt;
149.490 + expr value = expr.getInternalValue();
149.491 + if (value instanceof Str) {
149.492 + return (Str)value;
149.493 + }
149.494 + }
149.495 +
149.496 + return null;
149.497 + }
149.498 +
149.499 + public static Str getDocumentationNode(PythonTree node) {
149.500 + // DocString processing.
149.501 + // See http://www.python.org/dev/peps/pep-0257/
149.502 +
149.503 + // For modules, it's the first Str in the document.
149.504 + // For classes and methods, it's the first Str in the object.
149.505 + // For others, nothing.
149.506 +
149.507 + if (node instanceof FunctionDef) {
149.508 + // Function
149.509 + FunctionDef def = (FunctionDef)node;
149.510 + List<stmt> body = def.getInternalBody();
149.511 + if (body != null && body.size() > 0) {
149.512 + return searchForDocNode(body.get(0));
149.513 + }
149.514 + } else if (node instanceof ClassDef) {
149.515 + // Class
149.516 + ClassDef def = (ClassDef)node;
149.517 + List<stmt> body = def.getInternalBody();
149.518 + if (body != null && body.size() > 0) {
149.519 + return searchForDocNode(body.get(0));
149.520 + }
149.521 + } else if (node instanceof Module) {
149.522 + // Module
149.523 + Module module = (Module)node;
149.524 + List<stmt> body = module.getInternalBody();
149.525 + if (body != null && body.size() > 0) {
149.526 + return searchForDocNode(body.get(0));
149.527 + }
149.528 + }
149.529 + // TODO: As per http://www.python.org/dev/peps/pep-0257/ I should
149.530 + // also look for "additional docstrings" (Str node following a Str node)
149.531 + // and Assign str nodes
149.532 +
149.533 + return null;
149.534 + }
149.535 +
149.536 + public static String getStrContent(Str str) {
149.537 + String doc = str.getText();
149.538 +
149.539 + // Strip quotes
149.540 + // and U and/or R for unicode/raw string. U must always preceede r if present.
149.541 + if (doc.startsWith("ur") || doc.startsWith("UR") || // NOI18N
149.542 + doc.startsWith("Ur") || doc.startsWith("uR")) { // NOI18N
149.543 + doc = doc.substring(2);
149.544 + } else if (doc.startsWith("r") || doc.startsWith("u") || // NOI18N
149.545 + doc.startsWith("R") || doc.startsWith("U")) { // NOI18N
149.546 + doc = doc.substring(1);
149.547 + }
149.548 +
149.549 + if (doc.startsWith("\"\"\"") && doc.endsWith("\"\"\"")) { // NOI18N
149.550 + doc = doc.substring(3, doc.length() - 3);
149.551 + } else if (doc.startsWith("r\"\"\"") && doc.endsWith("\"\"\"")) { // NOI18N
149.552 + doc = doc.substring(4, doc.length() - 3);
149.553 + } else if (doc.startsWith("'''") && doc.endsWith("'''")) { // NOI18N
149.554 + doc = doc.substring(3, doc.length() - 3);
149.555 + } else if (doc.startsWith("r'''") && doc.endsWith("'''")) { // NOI18N
149.556 + doc = doc.substring(4, doc.length() - 3);
149.557 + } else if (doc.startsWith("\"") && doc.endsWith("\"")) { // NOI18N
149.558 + doc = doc.substring(1, doc.length() - 1);
149.559 + } else if (doc.startsWith("'") && doc.endsWith("'")) { // NOI18N
149.560 + doc = doc.substring(1, doc.length() - 1);
149.561 + }
149.562 +
149.563 + return doc;
149.564 + }
149.565 +
149.566 + public static String getDocumentation(PythonTree node) {
149.567 + Str str = getDocumentationNode(node);
149.568 + if (str != null) {
149.569 + return getStrContent(str);
149.570 + }
149.571 +
149.572 + return null;
149.573 + }
149.574 +
149.575 + public static PythonTree getForeignNode(final IndexedElement o, PythonParserResult[] parserResultRet) {
149.576 + FileObject fo = o.getFileObject();
149.577 +
149.578 + if (fo == null) {
149.579 + return null;
149.580 + }
149.581 +
149.582 + Source source = Source.create(fo);
149.583 + if(source == null) {
149.584 + return null;
149.585 + }
149.586 + final PythonParserResult[] resultHolder = new PythonParserResult[1];
149.587 + try {
149.588 + ParserManager.parse(Collections.singleton(source), new UserTask() {
149.589 +
149.590 + @Override
149.591 + public void run(ResultIterator resultIterator) throws Exception {
149.592 + resultHolder[0] = (PythonParserResult) resultIterator.getParserResult();
149.593 + }
149.594 + });
149.595 + } catch (ParseException ex) {
149.596 + Exceptions.printStackTrace(ex);
149.597 + }
149.598 +
149.599 + PythonParserResult info = resultHolder[0];
149.600 + if (parserResultRet != null) {
149.601 + parserResultRet[0] = info;
149.602 + }
149.603 + PythonParserResult result = getParseResult(info);
149.604 + if (result == null) {
149.605 + return null;
149.606 + }
149.607 +
149.608 + PythonTree root = getRoot(result);
149.609 + if (root == null) {
149.610 + return null;
149.611 + }
149.612 +
149.613 + if (o.getKind() == ElementKind.MODULE && root instanceof Module) {
149.614 + return root;
149.615 + }
149.616 +
149.617 + String signature = o.getSignature();
149.618 +
149.619 + if (signature == null) {
149.620 + return null;
149.621 + }
149.622 +
149.623 + SymbolTable symbolTable = result.getSymbolTable();
149.624 + SymInfo sym = symbolTable.findBySignature(o.getKind(), signature);
149.625 + if (sym != null && sym.node != null) {
149.626 + // Temporary diagnostic checking
149.627 + //assert ((o.getKind() != ElementKind.CONSTRUCTOR && o.getKind() != ElementKind.METHOD) ||
149.628 + // sym.node instanceof FunctionDef);
149.629 + //assert o.getKind() != ElementKind.CLASS || sym.node instanceof ClassDef;
149.630 +
149.631 + return sym.node;
149.632 + }
149.633 +
149.634 + // TODO - check args etc.
149.635 +// String name = o.getName();
149.636 +// boolean lookForFunction = o.getKind() == ElementKind.CONSTRUCTOR || o.getKind() == ElementKind.METHOD;
149.637 +// if (lookForFunction) {
149.638 +// for (AstElement element : result.getStructure().getElements()) {
149.639 +// if (element.getName().equals(name) && element.getSignature().equals(signature)) {
149.640 +// return element.getNode();
149.641 +// }
149.642 +// }
149.643 +// }
149.644 +// }
149.645 +
149.646 + ElementKind kind = o.getKind();
149.647 + List<PythonStructureItem> items = PythonStructureScanner.analyze(info).getElements();
149.648 + if (items != null) {
149.649 + return find(items, signature, kind);
149.650 + } else {
149.651 + return null;
149.652 + }
149.653 + }
149.654 +
149.655 + private static PythonTree find(List<? extends StructureItem> items, String signature, ElementKind kind) {
149.656 + for (StructureItem item : items) {
149.657 + ElementKind childKind = item.getKind();
149.658 + if (childKind == kind &&
149.659 + item instanceof PythonStructureItem &&
149.660 + signature.equals(((PythonStructureItem)item).getSignature())) {
149.661 + return ((PythonStructureItem)item).getNode();
149.662 + }
149.663 + if (childKind == ElementKind.CLASS && signature.contains(item.getName())) {
149.664 + @SuppressWarnings("unchecked")
149.665 + List<? extends StructureItem> children = item.getNestedItems();
149.666 + PythonTree result = find(children, signature, kind);
149.667 + if (result != null) {
149.668 + return result;
149.669 + }
149.670 + }
149.671 + }
149.672 +
149.673 + return null;
149.674 + }
149.675 +
149.676 + public static Set<OffsetRange> getAllOffsets(PythonParserResult info, AstPath path, int lexOffset, String name, boolean abortOnFree) {
149.677 + if (path == null) {
149.678 + path = AstPath.get(PythonAstUtils.getRoot(info), lexOffset);
149.679 + }
149.680 + PythonTree scope = PythonAstUtils.getLocalScope(path);
149.681 + SymbolTable symbolTable = PythonAstUtils.getParseResult(info).getSymbolTable();
149.682 + List<PythonTree> nodes = symbolTable.getOccurrences(scope, name, abortOnFree);
149.683 + if (nodes == null) {
149.684 + return null;
149.685 + }
149.686 + Set<OffsetRange> offsets = new HashSet<>();
149.687 + Document doc = GsfUtilities.getDocument(info.getSnapshot().getSource().getFileObject(), false);
149.688 + if (doc == null) {
149.689 + return Collections.emptySet();
149.690 + }
149.691 + for (PythonTree node : nodes) {
149.692 + OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
149.693 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
149.694 +
149.695 + if (node instanceof Import || node instanceof ImportFrom) {
149.696 + // Try to find the exact spot
149.697 + if (abortOnFree) {
149.698 + return null;
149.699 + } else {
149.700 + lexRange = PythonLexerUtils.getImportNameOffset((BaseDocument)doc, lexRange, node, name);
149.701 + }
149.702 + } else if (abortOnFree && (node instanceof FunctionDef || node instanceof ClassDef)) {
149.703 + return null;
149.704 + }
149.705 +
149.706 + if (lexRange != OffsetRange.NONE) {
149.707 + offsets.add(lexRange);
149.708 + }
149.709 + }
149.710 + // Look for type variables
149.711 + ScopeInfo scopeInfo = symbolTable.getScopeInfo(scope);
149.712 + if (scopeInfo != null) {
149.713 + SymInfo sym = scopeInfo.tbl.get(name);
149.714 + if (sym != null && sym.isVariable(false)) {
149.715 + // Look for type declarations that can apply to this variable
149.716 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, PythonAstUtils.getRange(scope));
149.717 + if (lexRange != OffsetRange.NONE) {
149.718 + BaseDocument bdoc = (BaseDocument)doc;
149.719 + try {
149.720 + bdoc.readLock(); // For TokenHierarchy usage
149.721 + TokenHierarchy hi = TokenHierarchy.get(doc);
149.722 + LanguagePath languagePath = LanguagePath.get(LanguagePath.get(PythonTokenId.language()), PythonCommentTokenId.language());
149.723 + int startOffset = Math.min(lexRange.getStart(), doc.getLength());
149.724 + if (scope instanceof Module) {
149.725 + startOffset = 0; // Pick up comments before code starts
149.726 + }
149.727 + int endOffset = Math.min(lexRange.getEnd(), doc.getLength());
149.728 + @SuppressWarnings("unchecked")
149.729 + List<TokenSequence<? extends PythonCommentTokenId>> tsl = hi.tokenSequenceList(languagePath, startOffset, endOffset);
149.730 + for (TokenSequence<? extends PythonCommentTokenId> ts : tsl) {
149.731 + ts.moveStart();
149.732 + while (ts.moveNext()) {
149.733 + PythonCommentTokenId id = ts.token().id();
149.734 + if (id == PythonCommentTokenId.TYPEKEY) {
149.735 + if (ts.moveNext() && // skip separator
149.736 + ts.moveNext()) {
149.737 + if (ts.token().id() == PythonCommentTokenId.VARNAME) {
149.738 + if (TokenUtilities.equals(ts.token().text(), name)) {
149.739 + int start = ts.offset();
149.740 + OffsetRange nameRange = new OffsetRange(start, start + name.length());
149.741 + offsets.add(nameRange);
149.742 + }
149.743 + }
149.744 + }
149.745 + }
149.746 + }
149.747 + }
149.748 + } finally {
149.749 + bdoc.readUnlock();
149.750 + }
149.751 +
149.752 + }
149.753 + }
149.754 + }
149.755 +
149.756 + return offsets;
149.757 + }
149.758 +
149.759 + private static final class NameVisitor extends Visitor {
149.760 + @Override
149.761 + public Object visitName(Name name) throws Exception {
149.762 + return name.getInternalId();
149.763 + }
149.764 + }
149.765 +
149.766 + public static Set<OffsetRange> getLocalVarOffsets(PythonParserResult info, int lexOffset) {
149.767 + int astOffset = getAstOffset(info, lexOffset);
149.768 + if (astOffset != -1) {
149.769 + PythonTree root = getRoot(info);
149.770 + if (root != null) {
149.771 + AstPath path = AstPath.get(root, astOffset);
149.772 + if (path != null) {
149.773 + PythonTree closest = path.leaf();
149.774 + PythonTree scope = getLocalScope(path);
149.775 + String name = ((Name)closest).getInternalId();
149.776 +
149.777 + return getLocalVarOffsets(info, scope, name);
149.778 + }
149.779 + }
149.780 + }
149.781 +
149.782 + return Collections.emptySet();
149.783 + }
149.784 +
149.785 + public static Set<OffsetRange> getLocalVarOffsets(PythonParserResult info, PythonTree scope, String name) {
149.786 + LocalVarVisitor visitor = new LocalVarVisitor(info, name, false, true);
149.787 + try {
149.788 + visitor.visit(scope);
149.789 + return visitor.getOffsets();
149.790 + } catch (Exception ex) {
149.791 + Exceptions.printStackTrace(ex);
149.792 + return Collections.emptySet();
149.793 + }
149.794 + }
149.795 +
149.796 + public static List<Name> getLocalVarNodes(PythonParserResult info, PythonTree scope, String name) {
149.797 + LocalVarVisitor visitor = new LocalVarVisitor(info, name, true, false);
149.798 + try {
149.799 + visitor.visit(scope);
149.800 + return visitor.getVars();
149.801 + } catch (Exception ex) {
149.802 + Exceptions.printStackTrace(ex);
149.803 + return Collections.emptyList();
149.804 + }
149.805 + }
149.806 +
149.807 + public static List<Name> getLocalVarAssignNodes(PythonParserResult info, PythonTree scope, String name) {
149.808 + LocalVarAssignVisitor visitor = new LocalVarAssignVisitor(info, name, true, false);
149.809 + try {
149.810 + visitor.visit(scope);
149.811 + return visitor.getVars();
149.812 + } catch (Exception ex) {
149.813 + Exceptions.printStackTrace(ex);
149.814 + return Collections.emptyList();
149.815 + }
149.816 + }
149.817 +
149.818 + private static class LocalVarVisitor extends Visitor {
149.819 + private List<Name> vars = new ArrayList<>();
149.820 + private Set<OffsetRange> offsets = new HashSet<>();
149.821 + private String name;
149.822 + private PythonParserResult info;
149.823 + private boolean collectNames;
149.824 + private boolean collectOffsets;
149.825 + private PythonTree parent;
149.826 +
149.827 + private LocalVarVisitor(PythonParserResult info, String name, boolean collectNames, boolean collectOffsets) {
149.828 + this.info = info;
149.829 + this.name = name;
149.830 + this.collectNames = collectNames;
149.831 + this.collectOffsets = collectOffsets;
149.832 + }
149.833 +
149.834 + @Override
149.835 + public void traverse(PythonTree node) throws Exception {
149.836 + PythonTree oldParent = parent;
149.837 + parent = node;
149.838 + super.traverse(node);
149.839 + parent = oldParent;
149.840 + }
149.841 +
149.842 + @Override
149.843 + public Object visitName(Name node) throws Exception {
149.844 + if (parent instanceof Call && ((Call)parent).getInternalFunc() == node) {
149.845 + return super.visitName(node);
149.846 + }
149.847 +
149.848 + if ((name == null && !PythonUtils.isClassName(node.getInternalId(), false)) ||
149.849 + (name != null && name.equals(node.getInternalId()))) {
149.850 + if (collectOffsets) {
149.851 + OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
149.852 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
149.853 + if (lexRange != OffsetRange.NONE) {
149.854 + offsets.add(astRange);
149.855 + }
149.856 + }
149.857 + if (collectNames) {
149.858 + vars.add(node);
149.859 + }
149.860 + }
149.861 +
149.862 + return super.visitName(node);
149.863 + }
149.864 +
149.865 + public Set<OffsetRange> getOffsets() {
149.866 + return offsets;
149.867 + }
149.868 +
149.869 + public List<Name> getVars() {
149.870 + return vars;
149.871 + }
149.872 + }
149.873 +
149.874 + private static class LocalVarAssignVisitor extends Visitor {
149.875 + private List<Name> vars = new ArrayList<>();
149.876 + private Set<OffsetRange> offsets = new HashSet<>();
149.877 + private String name;
149.878 + private PythonParserResult info;
149.879 + private boolean collectNames;
149.880 + private boolean collectOffsets;
149.881 + private PythonTree parent;
149.882 +
149.883 + private LocalVarAssignVisitor(PythonParserResult info, String name, boolean collectNames, boolean collectOffsets) {
149.884 + this.info = info;
149.885 + this.name = name;
149.886 + this.collectNames = collectNames;
149.887 + this.collectOffsets = collectOffsets;
149.888 + }
149.889 +
149.890 + @Override
149.891 + public Object visitName(Name node) throws Exception {
149.892 + if (parent instanceof FunctionDef || parent instanceof Assign) {
149.893 + if ((name == null && !PythonUtils.isClassName(node.getInternalId(), false)) ||
149.894 + (name != null && name.equals(node.getInternalId()))) {
149.895 + if (collectOffsets) {
149.896 + OffsetRange astRange = PythonAstUtils.getNameRange(info, node);
149.897 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
149.898 + if (lexRange != OffsetRange.NONE) {
149.899 + offsets.add(astRange);
149.900 + }
149.901 + }
149.902 + if (collectNames) {
149.903 + vars.add(node);
149.904 + }
149.905 + }
149.906 + }
149.907 +
149.908 + return super.visitName(node);
149.909 + }
149.910 +
149.911 + @Override
149.912 + public void traverse(PythonTree node) throws Exception {
149.913 + PythonTree oldParent = parent;
149.914 + parent = node;
149.915 + super.traverse(node);
149.916 + parent = oldParent;
149.917 + }
149.918 +
149.919 + public Set<OffsetRange> getOffsets() {
149.920 + return offsets;
149.921 + }
149.922 +
149.923 + public List<Name> getVars() {
149.924 + return vars;
149.925 + }
149.926 + }
149.927 +
149.928 + /** Collect nodes of the given types (node.nodeId==NodeTypes.x) under the given root */
149.929 + public static void addNodesByType(PythonTree root, Class[] nodeClasses, List<PythonTree> result) {
149.930 + try {
149.931 + new NodeTypeVisitor(result, nodeClasses).visit(root);
149.932 + } catch (Exception ex) {
149.933 + Exceptions.printStackTrace(ex);
149.934 + }
149.935 + }
149.936 +
149.937 + private static class NodeTypeVisitor extends Visitor {
149.938 + private Class[] nodeClasses;
149.939 + private List<PythonTree> result;
149.940 +
149.941 + NodeTypeVisitor(List<PythonTree> result, Class[] nodeClasses) {
149.942 + this.result = result;
149.943 + this.nodeClasses = nodeClasses;
149.944 + }
149.945 +
149.946 + @Override
149.947 + public void traverse(PythonTree node) throws Exception {
149.948 + for (Class nodeClasse : nodeClasses) {
149.949 + if (node.getClass() == nodeClasse) {
149.950 + result.add(node);
149.951 + break;
149.952 + }
149.953 + }
149.954 +
149.955 + super.traverse(node);
149.956 + }
149.957 + }
149.958 +
149.959 + public static Name getParentClassFromNode(AstPath path, PythonTree from, String name) {
149.960 + ClassDef curClass = (ClassDef)path.getTypedAncestor(ClassDef.class, from);
149.961 + if (curClass == null) {
149.962 + return null;
149.963 + }
149.964 +
149.965 + List<expr> baseClasses = curClass.getInternalBases();
149.966 + if (baseClasses == null) {
149.967 + return null; // no inheritance ;
149.968 + }
149.969 + int ii = 0;
149.970 + while (ii < baseClasses.size()) {
149.971 + if (baseClasses.get(ii) instanceof Name) {
149.972 + Name cur = (Name)baseClasses.get(ii);
149.973 + if (cur.getInternalId().equals(name)) {
149.974 + return cur;
149.975 + }
149.976 + }
149.977 + ii++;
149.978 + }
149.979 + return null;
149.980 + }
149.981 +
149.982 + /**
149.983 + * Look for the caret offset in the parameter list; return the
149.984 + * index of the parameter that contains it.
149.985 + */
149.986 + public static int findArgumentIndex(Call call, int astOffset, AstPath path) {
149.987 +
149.988 + // On the name part in the call rather than the args?
149.989 + if (astOffset <= call.getInternalFunc().getCharStopIndex()) {
149.990 + return -1;
149.991 + }
149.992 + List<expr> args = call.getInternalArgs();
149.993 + if (args != null) {
149.994 + int index = 0;
149.995 + for (; index < args.size(); index++) {
149.996 + expr et = args.get(index);
149.997 + if (et.getCharStopIndex() >= astOffset) {
149.998 + return index;
149.999 + }
149.1000 + }
149.1001 + }
149.1002 +
149.1003 + // TODO what about the other stuff in there --
149.1004 + //call.keywords;
149.1005 + //call.kwargs;
149.1006 + //call.starargs;
149.1007 +
149.1008 + return -1;
149.1009 + }
149.1010 +}
150.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonExample.py Wed Sep 02 20:31:18 2015 +0200
150.3 @@ -0,0 +1,10 @@
150.4 +"""Sample Module"""
150.5 +import foo
150.6 +CONSTANT = "VALUE"
150.7 +
150.8 +class Foo(Bar):
150.9 + """Class doc"""
150.10 +
150.11 + def __init__(self,args=''):
150.12 + # Comment
150.13 + print 1+2.0
151.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonFormatter.java Wed Sep 02 20:31:18 2015 +0200
151.3 @@ -0,0 +1,655 @@
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 +package org.netbeans.modules.python.source;
151.46 +
151.47 +import java.util.ArrayList;
151.48 +import java.util.Collections;
151.49 +import java.util.HashMap;
151.50 +import java.util.List;
151.51 +import java.util.Map;
151.52 +import javax.swing.text.BadLocationException;
151.53 +import javax.swing.text.Document;
151.54 +import javax.swing.text.JTextComponent;
151.55 +import org.netbeans.api.editor.EditorRegistry;
151.56 +import org.netbeans.api.lexer.TokenSequence;
151.57 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
151.58 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
151.59 +import org.netbeans.api.lexer.Token;
151.60 +import org.netbeans.api.lexer.TokenId;
151.61 +import org.netbeans.api.lexer.TokenUtilities;
151.62 +import org.netbeans.editor.BaseDocument;
151.63 +import org.netbeans.editor.Utilities;
151.64 +import org.netbeans.modules.csl.api.EditList;
151.65 +import org.netbeans.modules.csl.api.Formatter;
151.66 +import org.netbeans.modules.csl.spi.GsfUtilities;
151.67 +import org.netbeans.modules.csl.spi.ParserResult;
151.68 +import org.netbeans.modules.editor.indent.api.IndentUtils;
151.69 +import org.netbeans.modules.editor.indent.spi.Context;
151.70 +import org.openide.util.Exceptions;
151.71 +
151.72 +/**
151.73 + * Implement formatting for Python. Since there are no {}'s etc. to uniquely
151.74 + * impose indentation on Python, this formatter really just tries to enforce
151.75 + * spaces-versus-tabs, and indentation width. E.g. it uses the existing indentation
151.76 + * to determine whether the next line should be idented more, same or less as the
151.77 + * current line and then enforces the current space and indent size settings.
151.78 + *
151.79 + * @todo Implement pretty printing: inserting newlines, removing spaces inside
151.80 + * parentheses, etc. See the recommendations in
151.81 + * http://www.python.org/dev/peps/pep-0008/
151.82 + * Do import statement cleanup too.
151.83 + * @todo Line up comment lines (# as a suffix, continued from a previous line)
151.84 + * @todo Handle continuation lines with extra indentation
151.85 + * @todo Line up list initializations better?
151.86 + *
151.87 + * @author Tor Norbye
151.88 + */
151.89 +public class PythonFormatter implements Formatter {
151.90 + private int indentSize;
151.91 + private int continuationIndentSize;
151.92 + private CodeStyle codeStyle;
151.93 +
151.94 + public PythonFormatter() {
151.95 + }
151.96 +
151.97 + public PythonFormatter(CodeStyle codeStyle) {
151.98 + this.codeStyle = codeStyle;
151.99 + }
151.100 +
151.101 + @Override
151.102 + public void reformat(Context context, ParserResult compilationInfo) {
151.103 +
151.104 + // No AST pretty printing yet
151.105 + // I should offer to go and do space insert/removal around commas, parentheses, etc.
151.106 + // as well as balancing long argument lists across lines
151.107 + Document document = context.document();
151.108 + int startOffset = context.startOffset();
151.109 + int endOffset = context.endOffset();
151.110 +
151.111 + reformat(context, document, startOffset, endOffset, (PythonParserResult) compilationInfo);
151.112 + }
151.113 +
151.114 + public void reformat(final Context context, Document document, int startOffset, int endOffset, PythonParserResult info) {
151.115 + if (codeStyle == null) {
151.116 + codeStyle = CodeStyle.getDefault(context.document());
151.117 + }
151.118 + if (info != null && codeStyle != null && codeStyle.formatImports() && !GsfUtilities.isCodeTemplateEditing(document) &&
151.119 + PythonAstUtils.getParseResult(info) != null) {
151.120 + new ImportManager(info, (BaseDocument)document, codeStyle).cleanup(null, startOffset, endOffset, false);
151.121 + }
151.122 +
151.123 + if (codeStyle != null) {
151.124 + cleanup(document, info, startOffset, endOffset);
151.125 + }
151.126 +
151.127 + reindent(context, document, startOffset, endOffset);
151.128 + }
151.129 +
151.130 + @Override
151.131 + public boolean needsParserResult() {
151.132 +// if (SourceUtils.isScanInProgress()) {
151.133 +// return false;
151.134 +// }
151.135 +
151.136 + // If we're going to format imports, then yes, we need the parser result
151.137 + JTextComponent target = EditorRegistry.lastFocusedComponent();
151.138 + if (target != null) {
151.139 + CodeStyle cs = CodeStyle.getDefault(target.getDocument());
151.140 + return cs != null ? cs.formatImports() : false;
151.141 + }
151.142 + return false;
151.143 + }
151.144 +
151.145 + @Override
151.146 + public int indentSize() {
151.147 + // 4 spaces: See http://www.python.org/dev/peps/pep-0008/
151.148 + return 4;
151.149 + }
151.150 +
151.151 + @Override
151.152 + public int hangingIndentSize() {
151.153 + return 4;
151.154 + }
151.155 +
151.156 + // Challenge: Two inconsistently formatted
151.157 + // Idea: Given a list of offsets and indentation, produce a graph (or recurse) where I mark all
151.158 + // siblings the exact same level
151.159 +
151.160 + // Algorithm:
151.161 + // Find smallest indent: That's the top level
151.162 + // Build a graph? Each indent line.
151.163 + //
151.164 + @Override
151.165 + public void reindent(final Context context) {
151.166 + Document document = context.document();
151.167 + int startOffset = context.startOffset();
151.168 + int endOffset = context.endOffset();
151.169 +
151.170 + reindent(context, document, startOffset, endOffset);
151.171 + }
151.172 +
151.173 + @SuppressWarnings("deprecation") // For doc.getFormatter()
151.174 + public void reindent(final Context context, Document document, int startOffset, int endOffset) {
151.175 + endOffset = Math.min(endOffset, document.getLength());
151.176 + startOffset = Math.min(startOffset, endOffset);
151.177 +
151.178 + continuationIndentSize = indentSize = IndentUtils.indentLevelSize(document);
151.179 +
151.180 +
151.181 + final BaseDocument doc = (BaseDocument)document;
151.182 + try {
151.183 + // Plan: Go through the lines, one by one, and compute the indentation levels relative to each other,
151.184 + // then normalize them (except inside strings), then apply!!
151.185 + // Also track whether we are used for newline indentation and if so, do smart bracket stuff
151.186 +
151.187 + // Current indentation for the given line. -1 means that it should be left alone (e.g.
151.188 + // we don't mess with multiline string literals.
151.189 + final List<Integer> offsets = new ArrayList<>();
151.190 +
151.191 + // Current indentation for the given line. -1 means that it should be left alone (e.g.
151.192 + // we don't mess with multiline string literals. Other negative numbers are offsets
151.193 + // pointing at a particular left parenthesis that this line should be aligned with
151.194 + final List<Integer> indentation = new ArrayList<>();
151.195 + final List<Integer> lParenOffsets = new ArrayList<>();
151.196 +
151.197 + try {
151.198 + doc.readLock(); // For token hierarchy usage
151.199 +
151.200 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, startOffset);
151.201 +
151.202 + int currentOffset = Utilities.getRowStart(doc, startOffset);
151.203 + int balance = 0;
151.204 + while (currentOffset <= endOffset) {
151.205 + if (!(Utilities.isRowEmpty(doc, currentOffset) || Utilities.isRowWhite(doc, currentOffset))) {
151.206 + Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, currentOffset);
151.207 + int indent = GsfUtilities.getLineIndent(doc, currentOffset);
151.208 + if (token != null) {
151.209 + if (token.id() == PythonTokenId.STRING_LITERAL || token.id() == PythonTokenId.STRING_END) {
151.210 + indent = -1;
151.211 + }
151.212 + }
151.213 +
151.214 + if (indent != -1) {
151.215 + if (balance <= 0) {
151.216 + indentation.add(indent);
151.217 + offsets.add(currentOffset);
151.218 + } else {
151.219 + assert balance <= lParenOffsets.size();
151.220 + int parenOffset = lParenOffsets.get(lParenOffsets.size()-balance);
151.221 + indentation.add(-parenOffset);
151.222 + offsets.add(currentOffset);
151.223 + }
151.224 + }
151.225 + }
151.226 +
151.227 + // TODO - look up the tokens to make sure we don't have a problem with literal nodes
151.228 +
151.229 + if (currentOffset > doc.getLength()) {
151.230 + break;
151.231 + }
151.232 +
151.233 + // Update the line balance
151.234 + int begin = Utilities.getRowStart(doc, currentOffset);
151.235 + int end = Utilities.getRowEnd(doc, currentOffset);
151.236 +
151.237 + ts.move(begin);
151.238 +
151.239 + if (ts.moveNext()) {
151.240 + do {
151.241 + Token<? extends PythonTokenId> token = ts.token();
151.242 + TokenId id = token.id();
151.243 +
151.244 + if (id == PythonTokenId.LPAREN) {
151.245 + balance++;
151.246 + lParenOffsets.add(ts.offset());
151.247 + } else if (id == PythonTokenId.RPAREN) {
151.248 + balance--;
151.249 + if (!lParenOffsets.isEmpty()) {
151.250 + lParenOffsets.remove(lParenOffsets.size()-1);
151.251 + }
151.252 + }
151.253 + } while (ts.moveNext() && (ts.offset() <= end));
151.254 + }
151.255 +
151.256 + currentOffset = Utilities.getRowEnd(doc, currentOffset) + 1;
151.257 + }
151.258 + } finally {
151.259 + doc.readUnlock();
151.260 + }
151.261 +
151.262 + // Nothing to do
151.263 + if (offsets.size() == 0) {
151.264 + return;
151.265 + }
151.266 +
151.267 + assert indentation.size() == offsets.size();
151.268 +
151.269 + final Map<Integer, Integer> offsetToLevel = new HashMap<>();
151.270 + final Map<Integer,Integer> offsetToIndex = new HashMap<>();
151.271 + List<Integer> parentIndentations = new ArrayList<>();
151.272 + int currentParentIndent = -1;
151.273 + int currentLevel = -1;
151.274 +
151.275 + int firstIndent = indentation.get(0);
151.276 + List<Integer> sorted = new ArrayList<>(indentation);
151.277 + Collections.sort(sorted);
151.278 + // Attempt to shift the computed indentation to fit the right indentation levels
151.279 + // that are currently in the file?
151.280 + int firstNonNeg = 0;
151.281 + for (; firstNonNeg < sorted.size(); firstNonNeg++) {
151.282 + if (sorted.get(firstNonNeg) >= 0) {
151.283 + break;
151.284 + }
151.285 + }
151.286 + boolean shiftToCurrent = true;
151.287 + if (firstIndent > sorted.get(firstNonNeg)) {
151.288 + shiftToCurrent = false;
151.289 + // The start is not at the top level... e.g. we have something like
151.290 + // foo
151.291 + // else
151.292 + // bar
151.293 + // (e.g. we are formatting a fragment of code which doesn't include
151.294 + // the top). Here we need to find the "true" top levels, so we
151.295 + // push levels on to the stack
151.296 + int prev = -1;
151.297 + for (int indent : sorted) {
151.298 + if (prev == indent) {
151.299 + continue;
151.300 + }
151.301 + prev = indent;
151.302 + if (indent < firstIndent) {
151.303 + parentIndentations.add(currentParentIndent);
151.304 + currentParentIndent = indent;
151.305 + currentLevel++;
151.306 + } else {
151.307 + break;
151.308 + }
151.309 + }
151.310 + }
151.311 +
151.312 +
151.313 + // TODO: What if I start in the middle of an expression such that I outdent
151.314 + // more than I indent? I have to build up the index levels if necessary
151.315 + // Go count popping levels
151.316 +
151.317 + for (int i = 0, n = offsets.size(); i < n; i++) {
151.318 + int offset = offsets.get(i);
151.319 + int indent = indentation.get(i);
151.320 + if (indent == -1) {
151.321 + // Leave line alone
151.322 + offsetToLevel.put(offset, -1);
151.323 + continue;
151.324 + }
151.325 + offsetToIndex.put(offset, i);
151.326 +
151.327 + if (indent < 0) {
151.328 + // Want to keep everything the same as the prev, plus delta
151.329 + } else if (indent > currentParentIndent) {
151.330 + // New level
151.331 + currentLevel++;
151.332 + parentIndentations.add(currentParentIndent);
151.333 + currentParentIndent = indent;
151.334 + } else if (indent < currentParentIndent) {
151.335 + while (currentParentIndent > indent) {
151.336 + currentLevel--;
151.337 + if (parentIndentations.size() > 0) {
151.338 + currentParentIndent = parentIndentations.remove(parentIndentations.size() - 1);
151.339 + } else {
151.340 + currentParentIndent = indent;
151.341 + }
151.342 + }
151.343 + }
151.344 +
151.345 + offsetToLevel.put(offset, currentLevel);
151.346 + }
151.347 +
151.348 + // Compute relative shift
151.349 + int firstLineIndent = indentation.get(0);
151.350 + int firstLineLevel = offsetToLevel.get(offsets.get(0));
151.351 + int computedIndent = firstLineLevel * indentSize;
151.352 + final int relativeShift = shiftToCurrent ? computedIndent - firstLineIndent : 0;
151.353 +
151.354 + doc.runAtomic(new Runnable() {
151.355 + @Override
151.356 + public void run() {
151.357 + int[] computedIndents = new int[offsets.size()];
151.358 + // Process backwards so I don't have to worry about updating offsets affected by
151.359 + // indentation changes
151.360 + for (int i = offsets.size() - 1; i >= 0; i--) {
151.361 + int indent = indentation.get(i);
151.362 + if (indent == -1) {
151.363 + // Leave line alone
151.364 + continue;
151.365 + }
151.366 + if (indent >= 0) {
151.367 + int offset = offsets.get(i);
151.368 + int level = offsetToLevel.get(offset);
151.369 + int computedIndent = level * indentSize - relativeShift;
151.370 + if (computedIndent < 0) {
151.371 + computedIndent = 0;
151.372 + }
151.373 + computedIndents[i] =computedIndent;
151.374 + } else {
151.375 + computedIndents[i] = -1;
151.376 + }
151.377 + }
151.378 +
151.379 + for (int i = offsets.size() - 1; i >= 0; i--) {
151.380 + int indent = indentation.get(i);
151.381 + if (indent < -1) {
151.382 + try {
151.383 + // Negative offset pointing to a left parenthesis we should align with
151.384 + int parenOffset = -indent;
151.385 + int lineStart = Utilities.getRowStart(doc, parenOffset);
151.386 + if (lineStart != -1) {
151.387 + int parenLineIndent = computedIndents[offsetToIndex.get(lineStart)];
151.388 + assert parenLineIndent >= 0;
151.389 + int textBegin = Utilities.getRowFirstNonWhite(doc, lineStart);
151.390 + assert textBegin != -1;
151.391 + // Indent to new indentation + text up to paren plus the paren itself
151.392 + int newIndent = parenLineIndent + (parenOffset-textBegin) + 1;
151.393 + computedIndents[i] = newIndent;
151.394 + }
151.395 + } catch (BadLocationException ble) {
151.396 + Exceptions.printStackTrace(ble);
151.397 + }
151.398 + }
151.399 + }
151.400 +
151.401 + // Process backwards so I don't have to worry about updating offsets affected by
151.402 + // indentation changes
151.403 + for (int i = offsets.size() - 1; i >= 0; i--) {
151.404 + int indent = indentation.get(i);
151.405 + if (indent == -1) {
151.406 + // Leave line alone
151.407 + continue;
151.408 + }
151.409 + int offset = offsets.get(i);
151.410 + int computedIndent = computedIndents[i];
151.411 + if (computedIndent < 0) {
151.412 + computedIndent = 0;
151.413 + }
151.414 +
151.415 + if (computedIndent != indent) {
151.416 + try {
151.417 + context.modifyIndent(offset, computedIndent);
151.418 + } catch (BadLocationException ex) {
151.419 + Exceptions.printStackTrace(ex);
151.420 + }
151.421 + }
151.422 + }
151.423 + }
151.424 + });
151.425 + } catch (BadLocationException ble) {
151.426 + Exceptions.printStackTrace(ble);
151.427 + }
151.428 + }
151.429 +
151.430 + private boolean isLinePrefix(BaseDocument doc, int offset) throws BadLocationException {
151.431 + return Utilities.getRowFirstNonWhite(doc, offset) == offset;
151.432 + }
151.433 +
151.434 + private void cleanup(Document document, PythonParserResult info, int startOffset, int endOffset) {
151.435 + BaseDocument doc = (BaseDocument)document;
151.436 + final EditList edits = new EditList(doc);
151.437 + try {
151.438 + doc.readLock(); // For token hierarchy usage
151.439 +
151.440 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, startOffset);
151.441 + if (ts == null) {
151.442 + return;
151.443 + }
151.444 +
151.445 + ts.move(startOffset);
151.446 +
151.447 +
151.448 +
151.449 + // TODO:
151.450 + // Control whether I collapse spaces to a single space, or just ensure there is at least one
151.451 + // "None", "1", "At least 1", "Leave Alone"
151.452 +
151.453 + // TODO: Insert and remove needed or unnecessary parentheses!
151.454 + // TODO: Alignment! Especially of trailing line comments on adjacent lines!
151.455 + // TODO: Collapse blank newlines!
151.456 + boolean addSpaceAroundOperators = true;
151.457 + boolean removeSpaceInsideParens = true; // also applies to braces and brackets
151.458 + boolean addSpaceAfterComma = true;
151.459 + // boolean spaceArondParens = false;
151.460 + // boolean spaceBeforeArgs = false; // before parentheses in a call
151.461 + boolean removeSpaceBeforeSep = true; // before comma, semicolon or colon
151.462 + // boolean alignAssignments = false; // Only one space around assignments
151.463 + boolean removeSpaceInParamAssign = true; // Around assignment in parameter list, e.g.
151.464 + boolean collapseSpaces = true;
151.465 + //def complex(real, imag=0.0):
151.466 + // return magic(r=real, i=imag)
151.467 + if (codeStyle != null) {
151.468 + addSpaceAroundOperators = codeStyle.addSpaceAroundOperators();
151.469 + removeSpaceInsideParens = codeStyle.removeSpaceInsideParens();
151.470 + addSpaceAfterComma = codeStyle.addSpaceAfterComma();
151.471 + removeSpaceBeforeSep = codeStyle.removeSpaceBeforeSep();
151.472 + removeSpaceInParamAssign = codeStyle.removeSpaceInParamAssign();
151.473 + collapseSpaces = codeStyle.collapseSpaces();
151.474 + }
151.475 +
151.476 + // TODO - back up to the nearest function or class or beginning of the document to get the right
151.477 + // parenthesis balance.
151.478 + int parenBalance = 0;
151.479 +
151.480 + Token<? extends PythonTokenId> prev = null;
151.481 + Token<? extends PythonTokenId> token = null;
151.482 + Token<? extends PythonTokenId> next = null;
151.483 + int tokenOffset = 0;
151.484 + int nextOffset = 0;
151.485 + int prevOffset = -1;
151.486 + if (ts.moveNext()) {
151.487 + token = ts.token();
151.488 + tokenOffset = ts.offset();
151.489 + if (ts.moveNext()) {
151.490 + next = ts.token();
151.491 + nextOffset = ts.offset();
151.492 + } else {
151.493 + return;
151.494 + }
151.495 + }
151.496 + boolean prevRemoved = false;
151.497 + boolean tokenRemoved = false;
151.498 + boolean nextRemoved = false;
151.499 + while (token != null) {
151.500 + TokenId prevId = prev != null ? prev.id() : null;
151.501 + TokenId id = token.id();
151.502 + TokenId nextId = next != null ? next.id() : null;
151.503 +
151.504 + if (id == PythonTokenId.LPAREN) {
151.505 + parenBalance++;
151.506 + } else if (id == PythonTokenId.RPAREN) {
151.507 + parenBalance--;
151.508 + }
151.509 +
151.510 + if (removeSpaceInsideParens) {
151.511 + if (id == PythonTokenId.LPAREN) {
151.512 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
151.513 + edits.replace(nextOffset, next.length(), null, false, 0);
151.514 + nextRemoved = true;
151.515 + }
151.516 + } else if (id == PythonTokenId.RPAREN) {
151.517 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
151.518 + // I don't remove space in front of paren's at the beginning of the line; these might have
151.519 + // been aligned with indented content above
151.520 + edits.replace(prevOffset, prev.length(), null, false, 0);
151.521 + prevRemoved = true;
151.522 + }
151.523 + } else if (id == PythonTokenId.LBRACKET) {
151.524 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
151.525 + edits.replace(nextOffset, next.length(), null, false, 0);
151.526 + nextRemoved = true;
151.527 + }
151.528 + } else if (id == PythonTokenId.RBRACKET) {
151.529 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
151.530 + edits.replace(prevOffset, prev.length(), null, false, 0);
151.531 + prevRemoved = true;
151.532 + }
151.533 + } else if (id == PythonTokenId.LBRACE) {
151.534 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
151.535 + edits.replace(nextOffset, next.length(), null, false, 0);
151.536 + nextRemoved = true;
151.537 + }
151.538 + } else if (id == PythonTokenId.RBRACE) {
151.539 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
151.540 + edits.replace(prevOffset, prev.length(), null, false, 0);
151.541 + prevRemoved = true;
151.542 + }
151.543 + }
151.544 + }
151.545 +
151.546 + if (addSpaceAfterComma) {
151.547 + if (id == PythonTokenId.COMMA) {
151.548 + if (collapseSpaces && nextId == PythonTokenId.WHITESPACE && next.length() > 1) {
151.549 + edits.replace(nextOffset, next.length() - 1, null, false, 1); // NOI18N
151.550 + } else if (next == null ||
151.551 + (nextId != PythonTokenId.WHITESPACE && nextId != PythonTokenId.NEWLINE)) {
151.552 + edits.replace(nextOffset, 0, " ", false, 1); // NOI18N
151.553 + }
151.554 + }
151.555 + }
151.556 +
151.557 + if (removeSpaceBeforeSep &&
151.558 + (id == PythonTokenId.COMMA || id == PythonTokenId.COLON ||
151.559 + (id == PythonTokenId.ANY_OPERATOR && TokenUtilities.equals(token.text(), ";"))) && // NOI18N
151.560 + prevId == PythonTokenId.WHITESPACE && !prevRemoved && !isLinePrefix(doc, tokenOffset)) {
151.561 + edits.replace(prevOffset, prev.length(), null, false, 2);
151.562 + prevRemoved = true;
151.563 + }
151.564 +
151.565 + if (addSpaceAroundOperators && id == PythonTokenId.ANY_OPERATOR) {
151.566 + CharSequence seq = token.text();
151.567 +
151.568 + // These aren't binary, and ; isn't really an operator and has its own setting
151.569 + if (!(TokenUtilities.equals(seq, "@") || // NOI18N
151.570 + TokenUtilities.equals(seq, "`") || // NOI18N
151.571 + TokenUtilities.equals(seq, ";"))) { // NOI18N
151.572 +
151.573 + boolean insertSpace = true;
151.574 + if (removeSpaceInParamAssign && TokenUtilities.equals(seq, "=")) { // NOI18N
151.575 + // Special handling: keyword arguments should typically NOT
151.576 + // have space inserted
151.577 + if (parenBalance > 0) {
151.578 + insertSpace = false;
151.579 + // Remove spaces around the =
151.580 + if (prevId == PythonTokenId.WHITESPACE && !prevRemoved) {
151.581 + edits.replace(prevOffset, prev.length(), null, false, 5); // NOI18N
151.582 + prevRemoved = true;
151.583 + }
151.584 + if (nextId == PythonTokenId.WHITESPACE && !nextRemoved) {
151.585 + edits.replace(nextOffset, next.length(), null, false, 6); // NOI18N
151.586 + nextRemoved = true;
151.587 + }
151.588 + }
151.589 + }
151.590 +
151.591 + if (insertSpace && TokenUtilities.equals(seq, "-")/* && (nextId == PythonTokenId.FLOAT_LITERAL || nextId == PythonTokenId.INT_LITERAL)*/) {
151.592 + // Leave -'s alone for now. The code is a little unclear on the difference between
151.593 + // x-1 and =-1 etc. For numbers (floating and integer) the minus isn't part of the lexical token for the number;
151.594 + // it's a separate operator. However, it's tricky to tell this apart from the binary subtraction, since it depends
151.595 + // on what came before. For now play it safe an leave these alone.
151.596 + // TODO - implement this properly.
151.597 + insertSpace = false;
151.598 + }
151.599 +
151.600 + if (insertSpace && TokenUtilities.equals(seq, "*")) { // NOI18N
151.601 + // "*" in (*foo) doesn't mean multiplication; it's not a binary operator here,
151.602 + // it's many args.
151.603 + if (prevId == PythonTokenId.COMMA || prevId == PythonTokenId.LPAREN) {
151.604 + insertSpace = false;
151.605 + }
151.606 + }
151.607 +
151.608 + if (insertSpace) {
151.609 + // Ensure that we have space on both sides
151.610 + if (collapseSpaces && prevId == PythonTokenId.WHITESPACE && next.length() > 1 &&
151.611 + !isLinePrefix(doc, tokenOffset)) {
151.612 + edits.replace(prevOffset, prev.length() - 1, null, false, 1); // NOI18N
151.613 + } else if (prevId != PythonTokenId.WHITESPACE) {
151.614 + edits.replace(tokenOffset, 0, " ", false, 3); // NOI18N
151.615 + }
151.616 +
151.617 + if (collapseSpaces && nextId == PythonTokenId.WHITESPACE && next.length() > 1) {
151.618 + edits.replace(nextOffset, next.length() - 1, null, false, 1); // NOI18N
151.619 + } else if (nextId != PythonTokenId.WHITESPACE && nextId != PythonTokenId.NEWLINE) {
151.620 + edits.replace(nextOffset, 0, " ", false, 4); // NOI18N
151.621 + }
151.622 + }
151.623 + }
151.624 + }
151.625 +
151.626 + if (tokenOffset + token.length() >= endOffset) {
151.627 + break;
151.628 + }
151.629 +
151.630 + prevRemoved = tokenRemoved;
151.631 + tokenRemoved = nextRemoved;
151.632 + nextRemoved = false;
151.633 +
151.634 + prev = token;
151.635 + token = next;
151.636 + prevOffset = tokenOffset;
151.637 + tokenOffset = nextOffset;
151.638 + if (ts.moveNext()) {
151.639 + next = ts.token();
151.640 + nextOffset = ts.offset();
151.641 + } else {
151.642 + next = null;
151.643 + }
151.644 + }
151.645 + } catch (BadLocationException ble) {
151.646 + Exceptions.printStackTrace(ble);
151.647 + } finally {
151.648 + doc.readUnlock();
151.649 + }
151.650 +
151.651 + doc.runAtomic(new Runnable() {
151.652 + @Override
151.653 + public void run() {
151.654 + edits.apply();
151.655 + }
151.656 + });
151.657 + }
151.658 +}
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
152.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndex.java Wed Sep 02 20:31:18 2015 +0200
152.3 @@ -0,0 +1,1470 @@
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.io.File;
152.37 +import java.io.IOException;
152.38 +import java.net.MalformedURLException;
152.39 +import java.net.URL;
152.40 +import java.util.ArrayList;
152.41 +import java.util.Arrays;
152.42 +import java.util.Collection;
152.43 +import java.util.Collections;
152.44 +import java.util.EnumSet;
152.45 +import java.util.HashMap;
152.46 +import java.util.HashSet;
152.47 +import java.util.Iterator;
152.48 +import java.util.List;
152.49 +import java.util.Map;
152.50 +import java.util.Set;
152.51 +import java.util.WeakHashMap;
152.52 +import java.util.logging.Level;
152.53 +import java.util.logging.Logger;
152.54 +import org.netbeans.api.project.Project;
152.55 +import org.netbeans.modules.csl.api.ElementKind;
152.56 +import org.netbeans.modules.parsing.spi.indexing.PathRecognizer;
152.57 +import org.netbeans.modules.parsing.spi.indexing.support.IndexResult;
152.58 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
152.59 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CAMEL_CASE;
152.60 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CASE_INSENSITIVE_PREFIX;
152.61 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.CASE_INSENSITIVE_REGEXP;
152.62 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.PREFIX;
152.63 +import static org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind.REGEXP;
152.64 +import org.netbeans.modules.python.source.elements.IndexedElement;
152.65 +import org.netbeans.modules.python.api.PythonPlatform;
152.66 +import org.netbeans.modules.python.api.PythonPlatformManager;
152.67 +import org.netbeans.modules.python.source.impl.QuerySupportFactory;
152.68 +import org.netbeans.modules.python.source.elements.IndexedPackage;
152.69 +import org.openide.filesystems.FileObject;
152.70 +import org.openide.filesystems.FileStateInvalidException;
152.71 +import org.openide.filesystems.URLMapper;
152.72 +import org.openide.modules.InstalledFileLocator;
152.73 +import org.openide.util.Exceptions;
152.74 +import org.openide.util.Lookup;
152.75 +import org.python.antlr.ast.Import;
152.76 +import org.python.antlr.ast.ImportFrom;
152.77 +import org.python.antlr.ast.alias;
152.78 +
152.79 +/**
152.80 + *
152.81 + * @author alley
152.82 + * @author Tor Norbye
152.83 + */
152.84 +public class PythonIndex {
152.85 +// public static final Set<SearchScope> ALL_SCOPE = EnumSet.allOf(SearchScope.class);
152.86 +// public static final Set<SearchScope> SOURCE_SCOPE = EnumSet.of(SearchScope.SOURCE);
152.87 + static final String CLUSTER_URL = "cluster:"; // NOI18N
152.88 + static final String PYTHONHOME_URL = "python:"; // NOI18N
152.89 + private static final String STUB_MISSING = "stub_missing"; // NOI18N
152.90 +
152.91 + // The "functions" module is always imported by the interpreter, and ditto
152.92 + // for exceptions, constants, etc.
152.93 + public static Set<String> BUILTIN_MODULES = new HashSet<>();
152.94 +
152.95 +
152.96 + private static final Logger LOG = Logger.getLogger(PythonIndex.class.getName());
152.97 + public static final String OBJECT = "object"; // NOI18N
152.98 + static Map<String, Set<String>> wildcardImports = new HashMap<>();
152.99 + static Set<String> systemModules;
152.100 + // TODO - make weak?
152.101 + static Set<String> availableClasses;
152.102 + private static String clusterUrl = null;
152.103 + static {
152.104 + //BUILTIN_MODULES.add("objects"); // NOI18N -- just links to the others
152.105 + BUILTIN_MODULES.add("stdtypes"); // NOI18N
152.106 + //BUILTIN_MODULES.add("types"); // NOI18N
152.107 + BUILTIN_MODULES.add("exceptions"); // NOI18N
152.108 + BUILTIN_MODULES.add("functions"); // NOI18N
152.109 + BUILTIN_MODULES.add("constants"); // NOI18N
152.110 + }
152.111 +
152.112 + public static PythonIndex get(Collection<FileObject> roots) {
152.113 + // XXX no cache - is it needed?
152.114 + LOG.log(Level.FINE, "PythonIndex for roots: {0}", roots); //NOI18N
152.115 + return new PythonIndex(QuerySupportFactory.getQuerySupport(roots), false);
152.116 + }
152.117 +
152.118 + public static PythonIndex get(Project project) {
152.119 + Set<String> sourceIds = new HashSet<>();
152.120 + Set<String> libraryIds = new HashSet<>();
152.121 + Collection<? extends PathRecognizer> lookupAll = Lookup.getDefault().lookupAll(PathRecognizer.class);
152.122 + for (PathRecognizer pathRecognizer : lookupAll) {
152.123 + Set<String> source = pathRecognizer.getSourcePathIds();
152.124 + if (source != null) {
152.125 + sourceIds.addAll(source);
152.126 + }
152.127 + Set<String> library = pathRecognizer.getLibraryPathIds();
152.128 + if (library != null) {
152.129 + libraryIds.addAll(library);
152.130 + }
152.131 + }
152.132 +
152.133 + final Collection<FileObject> findRoots = QuerySupport.findRoots(project,
152.134 + sourceIds,
152.135 + libraryIds,
152.136 + Collections.<String>emptySet());
152.137 + return PythonIndex.get(findRoots);
152.138 + }
152.139 +
152.140 + private static final WeakHashMap<FileObject, PythonIndex> INDEX_CACHE = new WeakHashMap<>();
152.141 + public static PythonIndex get(FileObject fo) {
152.142 + PythonIndex index = INDEX_CACHE.get(fo);
152.143 + if (index == null) {
152.144 + LOG.log(Level.FINE, "Creating PythonIndex for FileObject: {0}", fo); //NOI18N
152.145 + index = new PythonIndex(QuerySupportFactory.getQuerySupport(fo), true);
152.146 + INDEX_CACHE.put(fo, index);
152.147 + }
152.148 + return index;
152.149 + }
152.150 +
152.151 + public static boolean isBuiltinModule(String module) {
152.152 + return BUILTIN_MODULES.contains(module) || STUB_MISSING.equals(module);
152.153 + }
152.154 +
152.155 + // For testing only
152.156 + public static void setClusterUrl(String url) {
152.157 + clusterUrl = url;
152.158 + }
152.159 +
152.160 + static String getPreindexUrl(String url) {
152.161 + // TODO - look up the correct platform to use!
152.162 + final PythonPlatformManager manager = PythonPlatformManager.getInstance();
152.163 + final String platformName = manager.getDefaultPlatform();
152.164 + PythonPlatform platform = manager.getPlatform(platformName);
152.165 + if (platform != null) {
152.166 + String s = platform.getHomeUrl();
152.167 + if (s != null) {
152.168 + if (url.startsWith(s)) {
152.169 + url = PYTHONHOME_URL + url.substring(s.length());
152.170 + return url;
152.171 + }
152.172 + }
152.173 + }
152.174 +
152.175 + String s = getClusterUrl();
152.176 +
152.177 + if (url.startsWith(s)) {
152.178 + return CLUSTER_URL + url.substring(s.length());
152.179 + }
152.180 +
152.181 + if (url.startsWith("jar:file:")) { // NOI18N
152.182 + String sub = url.substring(4);
152.183 + if (sub.startsWith(s)) {
152.184 + return CLUSTER_URL + sub.substring(s.length());
152.185 + }
152.186 + }
152.187 +
152.188 + return url;
152.189 + }
152.190 +
152.191 +/** Get the FileObject corresponding to a URL returned from the index */
152.192 + public static FileObject getFileObject(String url) {
152.193 + return getFileObject(url, null);
152.194 + }
152.195 +
152.196 + public static FileObject getFileObject(String url, FileObject context) {
152.197 + try {
152.198 + if (url.startsWith(PYTHONHOME_URL)) {
152.199 + Iterator<String> it = null;
152.200 +
152.201 + // TODO - look up the right platform for the given project
152.202 + //if (context != null) {
152.203 + // Project project = FileOwnerQuery.getOwner(context);
152.204 + // if (project != null) {
152.205 + // PythonPlatform platform = PythonPlatform.platformFor(project);
152.206 + // if (platform != null) {
152.207 + // it = Collections.singleton(platform).iterator();
152.208 + // }
152.209 + // }
152.210 + //}
152.211 +
152.212 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
152.213 + if (it == null) {
152.214 + it = manager.getPlatformList().iterator();
152.215 + }
152.216 + while (it.hasNext()) {
152.217 + String name = it.next();
152.218 + PythonPlatform platform = manager.getPlatform(name);
152.219 + if (platform != null) {
152.220 + String u = platform.getHomeUrl();
152.221 + if (u != null) {
152.222 + try {
152.223 + u = u + url.substring(PYTHONHOME_URL.length());
152.224 + FileObject fo = URLMapper.findFileObject(new URL(u));
152.225 + if (fo != null) {
152.226 + return fo;
152.227 + }
152.228 + } catch (MalformedURLException mue) {
152.229 + Exceptions.printStackTrace(mue);
152.230 + }
152.231 + }
152.232 + }
152.233 + }
152.234 +
152.235 + return null;
152.236 + } else if (url.startsWith(CLUSTER_URL)) {
152.237 + url = getClusterUrl() + url.substring(CLUSTER_URL.length()); // NOI18N
152.238 + if (url.contains(".egg!/")) { // NOI18N
152.239 + url = "jar:" + url; // NOI18N
152.240 + }
152.241 + }
152.242 +
152.243 + return URLMapper.findFileObject(new URL(url));
152.244 + } catch (MalformedURLException ex) {
152.245 + Exceptions.printStackTrace(ex);
152.246 + }
152.247 +
152.248 + return null;
152.249 + }
152.250 +
152.251 + static String getClusterUrl() {
152.252 + if (clusterUrl == null) {
152.253 + File f =
152.254 + InstalledFileLocator.getDefault().locate("modules/org-netbeans-modules-python-editor.jar", null, false); // NOI18N
152.255 +
152.256 + if (f == null) {
152.257 + throw new RuntimeException("Can't find cluster");
152.258 + }
152.259 +
152.260 + f = new File(f.getParentFile().getParentFile().getAbsolutePath());
152.261 +
152.262 + try {
152.263 + f = f.getCanonicalFile();
152.264 + clusterUrl = f.toURI().toURL().toExternalForm();
152.265 + } catch (IOException ioe) {
152.266 + Exceptions.printStackTrace(ioe);
152.267 + }
152.268 + }
152.269 +
152.270 + return clusterUrl;
152.271 + }
152.272 +
152.273 + private final QuerySupport index;
152.274 + private final boolean updateCache;
152.275 +
152.276 + /** Creates a new instance of PythonIndex */
152.277 + private PythonIndex(QuerySupport index, boolean updateCache) {
152.278 + this.index = index;
152.279 + this.updateCache = updateCache;
152.280 + }
152.281 +
152.282 + private boolean search(String fieldName, String fieldValue, QuerySupport.Kind kind, Set<? super IndexResult> result, final String... fieldsToLoad) {
152.283 + try {
152.284 + result.addAll(index.query(fieldName, fieldValue, kind, fieldsToLoad));
152.285 + return true;
152.286 + } catch (IOException ioe) {
152.287 + Exceptions.printStackTrace(ioe);
152.288 +
152.289 + return false;
152.290 + } catch (UnsupportedOperationException iuoe) {
152.291 + return false;
152.292 + }
152.293 + }
152.294 +
152.295 + public Set<IndexedElement> getModules(String name, final QuerySupport.Kind kind) {
152.296 + final Set<IndexResult> result = new HashSet<>();
152.297 +
152.298 + // if (!isValid()) {
152.299 + // LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
152.300 + // return;
152.301 + // }
152.302 +
152.303 + // TODO - handle case insensitive searches etc?
152.304 + String field = PythonIndexer.FIELD_MODULE_NAME;
152.305 +
152.306 + search(field, name, kind, result, PythonIndexer.FIELD_MODULE_ATTR_NAME, PythonIndexer.FIELD_MODULE_NAME);
152.307 +
152.308 + final Set<IndexedElement> modules = new HashSet<>();
152.309 +
152.310 + for (IndexResult map : result) {
152.311 + URL url = map.getUrl();
152.312 + if (url == null) {
152.313 + continue;
152.314 + }
152.315 + String path = url.toExternalForm();
152.316 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
152.317 + if (STUB_MISSING.equals(module)) {
152.318 + continue;
152.319 + }
152.320 +
152.321 + IndexedElement element = new IndexedElement(module, ElementKind.MODULE, path, null, null, null);
152.322 +
152.323 + String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
152.324 + if (attrs != null && attrs.indexOf('D') != -1) {
152.325 + element.setFlags(IndexedElement.DEPRECATED);
152.326 + }
152.327 +
152.328 + String rhs = path.substring(path.lastIndexOf('/') + 1);
152.329 + element.setRhs(rhs);
152.330 + modules.add(element);
152.331 + }
152.332 +
152.333 + return modules;
152.334 + }
152.335 +
152.336 + public Set<IndexedPackage> getPackages(String name, final QuerySupport.Kind kind) {
152.337 + final Set<IndexResult> result = new HashSet<>();
152.338 +
152.339 + String field = PythonIndexer.FIELD_MODULE_NAME;
152.340 + search(field, name, kind, result, PythonIndexer.FIELD_MODULE_NAME);
152.341 +
152.342 + final Set<IndexedPackage> packages = new HashSet<>();
152.343 +
152.344 + for (IndexResult map : result) {
152.345 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
152.346 +
152.347 + String pkgName = null;
152.348 + String pkg = null;
152.349 +
152.350 + int nextNextDot = -1;
152.351 + int lastDot = module.lastIndexOf('.');
152.352 + int nameLength = name.length();
152.353 + if (nameLength < lastDot) {
152.354 + int nextDot = module.indexOf('.', nameLength);
152.355 + if (nextDot != -1) {
152.356 + pkg = module.substring(0, nextDot);
152.357 + nextNextDot = module.indexOf('.', nextDot + 1);
152.358 + int start = module.lastIndexOf('.', name.length());
152.359 + if (start == -1) {
152.360 + start = 0;
152.361 + } else {
152.362 + start++;
152.363 + }
152.364 + pkgName = module.substring(start, nextDot);
152.365 + }
152.366 + } else if (lastDot != -1) {
152.367 + pkgName = module.substring(lastDot + 1);
152.368 + pkg = module;
152.369 + }
152.370 +
152.371 + if (pkgName != null) {
152.372 + String url = map.getUrl().toExternalForm();
152.373 + IndexedPackage element = new IndexedPackage(pkgName, pkg, url, nextNextDot != -1);
152.374 + element.setRhs("");
152.375 + packages.add(element);
152.376 + }
152.377 + }
152.378 +
152.379 + return packages;
152.380 + }
152.381 +
152.382 + public Set<IndexedElement> getClasses(String name, final QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
152.383 + final Set<IndexResult> result = new HashSet<>();
152.384 +
152.385 + // if (!isValid()) {
152.386 + // LOGGER.fine(String.format("LuceneIndex[%s] is invalid!\n", this.toString()));
152.387 + // return;
152.388 + // }
152.389 + String field;
152.390 +
152.391 + switch (kind) {
152.392 + case EXACT:
152.393 + case PREFIX:
152.394 + case CAMEL_CASE:
152.395 + case REGEXP:
152.396 + field = PythonIndexer.FIELD_CLASS_NAME;
152.397 +
152.398 + break;
152.399 +
152.400 + case CASE_INSENSITIVE_PREFIX:
152.401 + case CASE_INSENSITIVE_REGEXP:
152.402 + case CASE_INSENSITIVE_CAMEL_CASE:
152.403 + field = PythonIndexer.FIELD_CASE_INSENSITIVE_CLASS_NAME;
152.404 +
152.405 + break;
152.406 +
152.407 + default:
152.408 + throw new UnsupportedOperationException(kind.toString());
152.409 + }
152.410 +
152.411 + search(field, name, kind, result, PythonIndexer.FIELD_IN, PythonIndexer.FIELD_CLASS_ATTR_NAME, PythonIndexer.FIELD_CLASS_NAME);
152.412 +
152.413 + Set<String> uniqueClasses = includeDuplicates ? null : new HashSet<String>();
152.414 +
152.415 + final Set<IndexedElement> classes = new HashSet<>();
152.416 +
152.417 + for (IndexResult map : result) {
152.418 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.419 + if (clz == null) {
152.420 + // A module without classes
152.421 + continue;
152.422 + }
152.423 + String url = map.getUrl().toExternalForm();
152.424 + String module = map.getValue(PythonIndexer.FIELD_IN);
152.425 + boolean isBuiltin = isBuiltinModule(module);
152.426 +
152.427 + String fqn = clz; // No further namespaces in Python, right?
152.428 + if (!includeDuplicates) {
152.429 + if (!uniqueClasses.contains(fqn)) { // use a map to point right to the class
152.430 + uniqueClasses.add(fqn);
152.431 + IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
152.432 + if (isBuiltin) {
152.433 + element.setRhs("<i>builtin</i>");
152.434 + }
152.435 + String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
152.436 + if (attrs != null) {
152.437 + int flags = IndexedElement.decode(attrs, 0, 0);
152.438 + element.setFlags(flags);
152.439 + }
152.440 + element.setInherited(true);
152.441 +
152.442 + classes.add(element);
152.443 + } // else: Possibly pick the best version... based on which items have documentation attributes etc.
152.444 + } else {
152.445 + IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
152.446 + classes.add(element);
152.447 + }
152.448 + }
152.449 +
152.450 + return classes;
152.451 + }
152.452 +
152.453 +// /** Return the most distant method in the hierarchy that is overriding the given method, or null
152.454 +// * @todo Make this method actually compute most distant ancestor
152.455 +// * @todo Use arglist arity comparison to reject methods that are not overrides...
152.456 +// */
152.457 +// public IndexedMethod getOverridingMethod(String className, String methodName) {
152.458 +// Set<IndexedElement> methods = getInheritedElements(className, methodName, QuerySupport.Kind.EXACT);
152.459 +//
152.460 +// // TODO - this is only returning ONE match, not the most distant one. I really need to
152.461 +// // produce a PythonIndex method for this which can walk in there and do a decent job!
152.462 +//
152.463 +// for (IndexedElement method : methods) {
152.464 +// if (method.getKind() == ElementKind.METHOD || method.getKind() == ElementKind.CONSTRUCTOR) {
152.465 +// // getInheritedMethods may return methods ON fqn itself
152.466 +// if (!method.getIn().equals(className)) {
152.467 +// return (IndexedMethod)method;
152.468 +// }
152.469 +// }
152.470 +// }
152.471 +//
152.472 +// return null;
152.473 +// }
152.474 + /** Get the super implementation of the given method */
152.475 + public Set<IndexedElement> getOverridingMethods(String className, String function) {
152.476 + Set<IndexedElement> methods = getInheritedElements(className, function, QuerySupport.Kind.EXACT, true);
152.477 +
152.478 + // TODO - remove all methods that are in the same file
152.479 + if (methods.size() > 0) {
152.480 + Set<IndexedElement> result = new HashSet<>(methods.size());
152.481 + for (IndexedElement element : methods) {
152.482 + if (!className.equals(element.getClz())) {
152.483 + result.add(element);
152.484 + }
152.485 + }
152.486 + methods = result;
152.487 + }
152.488 +
152.489 + return methods;
152.490 +// // TODO - this is only returning ONE match, not the most distant one. I really need to
152.491 +// // produce a PythonIndex method for this which can walk in there and do a decent job!
152.492 +//
152.493 +// for (IndexedElement method : methods) {
152.494 +// if (method.getKind() == ElementKind.METHOD || method.getKind() == ElementKind.CONSTRUCTOR) {
152.495 +// // getInheritedMethods may return methods ON fqn itself
152.496 +// if (!method.getIn().equals(className)) {
152.497 +// return (IndexedMethod)method;
152.498 +// }
152.499 +// }
152.500 +// }
152.501 +//
152.502 +// return null;
152.503 + }
152.504 +
152.505 + /** Get the super class of the given class */
152.506 + public Set<IndexedElement> getSuperClasses(String className) {
152.507 + final Set<IndexResult> result = new HashSet<>();
152.508 +
152.509 + search(PythonIndexer.FIELD_CLASS_NAME, className, QuerySupport.Kind.EXACT, result, PythonIndexer.FIELD_EXTENDS_NAME, PythonIndexer.FIELD_CLASS_NAME);
152.510 +
152.511 + Set<String> classNames = new HashSet<>();
152.512 + for (IndexResult map : result) {
152.513 + String[] extendsClasses = map.getValues(PythonIndexer.FIELD_EXTENDS_NAME);
152.514 + if (extendsClasses != null && extendsClasses.length > 0) {
152.515 + for (String clzName : extendsClasses) {
152.516 + classNames.add(clzName);
152.517 + }
152.518 + }
152.519 + }
152.520 +
152.521 + String[] terms = { PythonIndexer.FIELD_IN, PythonIndexer.FIELD_CLASS_NAME };
152.522 +
152.523 + Set<IndexedElement> superClasses = new HashSet<>();
152.524 +
152.525 + for (String superClz : classNames) {
152.526 + result.clear();
152.527 + search(PythonIndexer.FIELD_CLASS_NAME, superClz, QuerySupport.Kind.EXACT, result, terms);
152.528 + for (IndexResult map : result) {
152.529 + assert superClz.equals(map.getValue(PythonIndexer.FIELD_CLASS_NAME));
152.530 + String url = map.getUrl().toExternalForm();
152.531 + String module = map.getValue(PythonIndexer.FIELD_IN);
152.532 + IndexedElement clz = new IndexedElement(superClz, ElementKind.CLASS, url, module, null, null);
152.533 + superClasses.add(clz);
152.534 + }
152.535 + }
152.536 +
152.537 + return superClasses;
152.538 + }
152.539 +
152.540 + /**
152.541 + * Get the set of inherited (through super classes and mixins) for the given fully qualified class name.
152.542 + * @param classFqn FQN: module1::module2::moduleN::class
152.543 + * @param prefix If kind is QuerySupport.Kind.PREFIX/CASE_INSENSITIVE_PREFIX, a prefix to filter methods by. Else,
152.544 + * if kind is QuerySupport.Kind.EXACT filter methods by the exact name.
152.545 + * @param kind Whether the prefix field should be taken as a prefix or a whole name
152.546 + */
152.547 + public Set<IndexedElement> getInheritedElements(String classFqn, String prefix, QuerySupport.Kind kind) {
152.548 + return getInheritedElements(classFqn, prefix, kind, false);
152.549 + }
152.550 +
152.551 + public Set<IndexedElement> getInheritedElements(String classFqn, String prefix, QuerySupport.Kind kind, boolean includeOverrides) {
152.552 + boolean haveRedirected = false;
152.553 +
152.554 + if (classFqn == null) {
152.555 + classFqn = OBJECT;
152.556 + haveRedirected = true;
152.557 + }
152.558 +
152.559 + //String field = PythonIndexer.FIELD_FQN_NAME;
152.560 + Set<IndexedElement> elements = new HashSet<>();
152.561 + Set<String> scannedClasses = new HashSet<>();
152.562 + Set<String> seenSignatures = new HashSet<>();
152.563 +
152.564 + if (prefix == null) {
152.565 + prefix = "";
152.566 + }
152.567 +
152.568 +// String searchUrl = null;
152.569 +// if (context != null) {
152.570 +// try {
152.571 +// searchUrl = context.getFile().getFileObject().getURL().toExternalForm();
152.572 +// } catch (FileStateInvalidException ex) {
152.573 +// Exceptions.printStackTrace(ex);
152.574 +// }
152.575 +// }
152.576 +
152.577 + addMethodsFromClass(prefix, kind, classFqn, elements, seenSignatures, scannedClasses,
152.578 + haveRedirected, false, includeOverrides, 0);
152.579 +
152.580 + return elements;
152.581 + }
152.582 +
152.583 + /** Return whether the specific class referenced (classFqn) was found or not. This is
152.584 + * not the same as returning whether any classes were added since it may add
152.585 + * additional methods from parents (Object/Class).
152.586 + */
152.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) {
152.588 + // Prevent problems with circular includes or redundant includes
152.589 + if (scannedClasses.contains(classFqn)) {
152.590 + return false;
152.591 + }
152.592 +
152.593 + scannedClasses.add(classFqn);
152.594 +
152.595 + String searchField = PythonIndexer.FIELD_CLASS_NAME;
152.596 +
152.597 + Set<IndexResult> result = new HashSet<>();
152.598 +
152.599 + String[] terms = {PythonIndexer.FIELD_IN,
152.600 + PythonIndexer.FIELD_EXTENDS_NAME,
152.601 + PythonIndexer.FIELD_MEMBER,
152.602 + PythonIndexer.FIELD_CLASS_NAME};
152.603 +
152.604 +
152.605 + search(searchField, classFqn, QuerySupport.Kind.EXACT, result, terms);
152.606 +
152.607 + boolean foundIt = result.size() > 0;
152.608 +
152.609 + // If this is a bogus class entry (no search rsults) don't continue
152.610 + if (!foundIt) {
152.611 + return foundIt;
152.612 + }
152.613 +
152.614 + List<String> extendsClasses = null;
152.615 +
152.616 + String classIn = null;
152.617 + int fqnIndex = classFqn.lastIndexOf("::"); // NOI18N
152.618 +
152.619 + if (fqnIndex != -1) {
152.620 + classIn = classFqn.substring(0, fqnIndex);
152.621 + }
152.622 + int prefixLength = prefix.length();
152.623 +
152.624 + for (IndexResult map : result) {
152.625 + assert map != null;
152.626 +
152.627 + String url = map.getUrl().toExternalForm();
152.628 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.629 + String module = map.getValue(PythonIndexer.FIELD_IN);
152.630 +
152.631 + if (extendsClasses == null) {
152.632 + String[] ext = map.getValues(PythonIndexer.FIELD_EXTENDS_NAME);
152.633 + if (ext != null && ext.length > 0) {
152.634 + if (extendsClasses == null) {
152.635 + extendsClasses = Arrays.asList(ext);
152.636 + } else {
152.637 + extendsClasses = new ArrayList<>(extendsClasses);
152.638 + extendsClasses.addAll(Arrays.asList(ext));
152.639 + }
152.640 + }
152.641 + }
152.642 +
152.643 + String[] members = map.getValues(PythonIndexer.FIELD_MEMBER);
152.644 +
152.645 + if (members != null) {
152.646 + for (String signature : members) {
152.647 + // Prevent duplicates when method is redefined
152.648 + if (includeOverrides || !seenSignatures.contains(signature)) {
152.649 + if (signature.startsWith(prefix)) {
152.650 + if (kind == QuerySupport.Kind.EXACT) {
152.651 + if (signature.charAt(prefixLength) != ';') {
152.652 + continue;
152.653 + }
152.654 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, prefix, 0, prefix.length())) {
152.655 + continue;
152.656 + } else {
152.657 + // REGEXP, CAMELCASE filtering etc. not supported here
152.658 + assert (kind == QuerySupport.Kind.PREFIX) ||
152.659 + (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
152.660 + }
152.661 +
152.662 + if (!includeOverrides) {
152.663 + seenSignatures.add(signature);
152.664 + }
152.665 + IndexedElement element = IndexedElement.create(signature, module, url, clz);
152.666 + // TODO - filter out private? Or let code completer do that? Probably should, in case
152.667 + // we have more rights when inheriting
152.668 + element.setSmart(!haveRedirected);
152.669 + element.setInherited(inheriting);
152.670 + if (includeOverrides) {
152.671 + element.setOrder(depth);
152.672 + }
152.673 + elements.add(element);
152.674 + }
152.675 + }
152.676 + }
152.677 + }
152.678 + }
152.679 +
152.680 + if (classFqn.equals(OBJECT)) {
152.681 + return foundIt;
152.682 + }
152.683 +
152.684 + if (extendsClasses == null || extendsClasses.size() == 0) {
152.685 + addMethodsFromClass(prefix, kind, OBJECT, elements, seenSignatures, scannedClasses,
152.686 + true, true, includeOverrides, depth + 1);
152.687 + } else {
152.688 + // We're not sure we have a fully qualified path, so try some different candidates
152.689 + for (String extendsClass : extendsClasses) {
152.690 + if (!addMethodsFromClass(prefix, kind, extendsClass, elements, seenSignatures,
152.691 + scannedClasses, haveRedirected, true, includeOverrides, depth + 1)) {
152.692 + // Search by classIn
152.693 + String fqn = classIn;
152.694 +
152.695 + while (fqn != null) {
152.696 + if (addMethodsFromClass(prefix, kind, fqn + "::" + extendsClass, elements,
152.697 + seenSignatures, scannedClasses, haveRedirected, true, includeOverrides, depth + 1)) {
152.698 + break;
152.699 + }
152.700 +
152.701 + int f = fqn.lastIndexOf("::"); // NOI18N
152.702 +
152.703 + if (f == -1) {
152.704 + break;
152.705 + } else {
152.706 + fqn = fqn.substring(0, f);
152.707 + }
152.708 + }
152.709 + }
152.710 + }
152.711 + }
152.712 +
152.713 + return foundIt;
152.714 + }
152.715 +
152.716 +
152.717 + public Set<IndexedElement> getAllMembers(String name, QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
152.718 + final Set<IndexResult> result = new HashSet<>();
152.719 + // TODO - handle case sensitivity better...
152.720 + String field = PythonIndexer.FIELD_MEMBER;
152.721 + QuerySupport.Kind originalKind = kind;
152.722 + if (kind == QuerySupport.Kind.EXACT) {
152.723 + // I can't do exact searches on methods because the method
152.724 + // entries include signatures etc. So turn this into a prefix
152.725 + // search and then compare chopped off signatures with the name
152.726 + kind = QuerySupport.Kind.PREFIX;
152.727 + }
152.728 +
152.729 + String searchUrl = null;
152.730 + if (context != null) {
152.731 + searchUrl = context.getSnapshot().getSource().getFileObject().toURL().toExternalForm();
152.732 + }
152.733 +
152.734 + String[] terms = {PythonIndexer.FIELD_IN,
152.735 + PythonIndexer.FIELD_EXTENDS_NAME,
152.736 + PythonIndexer.FIELD_MEMBER,
152.737 + PythonIndexer.FIELD_CLASS_NAME};
152.738 +
152.739 + search(field, name, kind, result, terms);
152.740 +
152.741 +// Set<String> uniqueClasses = null;
152.742 +// if (includeDuplicates) {
152.743 +// uniqueClasses = null;
152.744 +// } else if (uniqueClasses == null) {
152.745 +// uniqueClasses = new HashSet<String>();
152.746 +// }
152.747 +
152.748 + final Set<IndexedElement> members = new HashSet<>();
152.749 + int nameLength = name.length();
152.750 +
152.751 + for (IndexResult map : result) {
152.752 + String[] signatures = map.getValues(PythonIndexer.FIELD_MEMBER);
152.753 + if (signatures != null && signatures.length > 0) {
152.754 + String url = map.getUrl().toExternalForm();
152.755 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.756 + String module = map.getValue(PythonIndexer.FIELD_IN);
152.757 + boolean inherited = searchUrl == null || !searchUrl.equals(url);
152.758 +
152.759 + for (String signature : signatures) {
152.760 + if (originalKind == QuerySupport.Kind.EXACT) {
152.761 + if (signature.charAt(nameLength) != ';') {
152.762 + continue;
152.763 + }
152.764 + } else if (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, name, 0, name.length())) {
152.765 + continue;
152.766 + } else {
152.767 + // REGEXP, CAMELCASE filtering etc. not supported here
152.768 + assert (originalKind == QuerySupport.Kind.PREFIX) ||
152.769 + (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
152.770 + }
152.771 +
152.772 + IndexedElement element = IndexedElement.create(signature, module, url, clz);
152.773 + element.setInherited(inherited);
152.774 + members.add(element);
152.775 + }
152.776 + }
152.777 + }
152.778 +
152.779 + return members;
152.780 + }
152.781 +
152.782 + public Set<IndexedElement> getAllElements(String name, QuerySupport.Kind kind, PythonParserResult context, boolean includeDuplicates) {
152.783 + final Set<IndexResult> result = new HashSet<>();
152.784 + // TODO - handle case sensitivity better...
152.785 + String field = PythonIndexer.FIELD_ITEM;
152.786 + QuerySupport.Kind originalKind = kind;
152.787 + if (kind == QuerySupport.Kind.EXACT) {
152.788 + // I can't do exact searches on methods because the method
152.789 + // entries include signatures etc. So turn this into a prefix
152.790 + // search and then compare chopped off signatures with the name
152.791 + kind = QuerySupport.Kind.PREFIX;
152.792 + }
152.793 +
152.794 + String searchUrl = null;
152.795 + if (context != null) {
152.796 + searchUrl = context.getSnapshot().getSource().getFileObject().toURL().toExternalForm();
152.797 + }
152.798 +
152.799 + String[] terms = { PythonIndexer.FIELD_ITEM,
152.800 + PythonIndexer.FIELD_MODULE_NAME };
152.801 +
152.802 + search(field, name, kind, result, terms);
152.803 +
152.804 + final Set<IndexedElement> elements = new HashSet<>();
152.805 + int nameLength = name.length();
152.806 +
152.807 + for (IndexResult map : result) {
152.808 + String[] signatures = map.getValues(PythonIndexer.FIELD_ITEM);
152.809 + if (signatures != null && signatures.length > 0) {
152.810 + String url = map.getUrl().toExternalForm();
152.811 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
152.812 + boolean inherited = searchUrl == null || !searchUrl.equals(url);
152.813 +
152.814 + for (String signature : signatures) {
152.815 + if (originalKind == QuerySupport.Kind.EXACT) {
152.816 + if (signature.charAt(nameLength) != ';') {
152.817 + continue;
152.818 + }
152.819 + } else if (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, name, 0, name.length())) {
152.820 + continue;
152.821 + } else {
152.822 + // REGEXP, CAMELCASE filtering etc. not supported here
152.823 + assert (originalKind == QuerySupport.Kind.PREFIX) ||
152.824 + (originalKind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
152.825 + }
152.826 +
152.827 + IndexedElement element = IndexedElement.create(signature, module, url, null);
152.828 + if (element.isPrivate() && !url.equals(searchUrl)) {
152.829 + continue;
152.830 + }
152.831 + element.setInherited(inherited);
152.832 + elements.add(element);
152.833 + }
152.834 + }
152.835 + }
152.836 +
152.837 + return elements;
152.838 + }
152.839 +
152.840 + public Set<String> getBuiltinSymbols() {
152.841 + Set<String> modules = new HashSet<>();
152.842 +
152.843 + // The "functions" module is always imported by the interpreter, and ditto
152.844 + // for exceptions, constants, etc.
152.845 + //modules.add("objects"); // NOI18N -- just links to the others
152.846 + modules.addAll(BUILTIN_MODULES);
152.847 +
152.848 + Set<String> symbols = new HashSet<>(250);
152.849 +
152.850 + String[] terms = { PythonIndexer.FIELD_MODULE_NAME,
152.851 + PythonIndexer.FIELD_ITEM };
152.852 +
152.853 + // Look up all symbols
152.854 + for (String module : modules) {
152.855 + final Set<IndexResult> result = new HashSet<>();
152.856 + // TODO - handle case sensitivity better...
152.857 + String field = PythonIndexer.FIELD_MODULE_NAME;
152.858 + QuerySupport.Kind kind = QuerySupport.Kind.EXACT;
152.859 +
152.860 + search(field, module, kind, result, terms);
152.861 +
152.862 + for (IndexResult map : result) {
152.863 + String[] signatures = map.getValues(PythonIndexer.FIELD_ITEM);
152.864 + if (signatures != null) {
152.865 + for (String signature : signatures) {
152.866 + int semi = signature.indexOf(';');
152.867 + assert semi != -1;
152.868 + int flags = IndexedElement.decode(signature, semi + 3, 0);
152.869 + if ((flags & IndexedElement.PRIVATE) != 0) {
152.870 + // Skip private symbols - can't import those
152.871 + continue;
152.872 + }
152.873 + String name = signature.substring(0, semi);
152.874 + symbols.add(name);
152.875 + }
152.876 + }
152.877 + }
152.878 + }
152.879 +
152.880 + // Computed as described below
152.881 + String[] MISSING = {
152.882 + "Ellipsis", "False", "IndentationError", "None", "NotImplemented", "TabError", // NOI18N
152.883 + "True", "__debug__", "__doc__", "__name__", "copyright", "credits", "exit", "license", // NOI18N
152.884 + "quit" // NOI18N
152.885 + };
152.886 + for (String s : MISSING) {
152.887 + symbols.add(s);
152.888 + }
152.889 + symbols.add("__builtins__"); // NOI18N
152.890 + symbols.add("__file__"); // NOI18N
152.891 +
152.892 + //// COMPUTING MISSING SYMBOLS:
152.893 + //// My builtin .rst files don't seem to define all the builtin symbols that the Python
152.894 + //// interpreter is configured with. I generated these pretty trivially; run
152.895 + //// python and type "dir(__builtins__)" and you end up a list like the below:
152.896 + ////String[] EXTRA_BUILTINS = {"ArithmeticError", "AssertionError", "AttributeError", "BaseException",
152.897 + // "DeprecationWarning", "EOFError", "Ellipsis", "EnvironmentError", "Exception", "False",
152.898 + // "FloatingPointError", "FutureWarning", "GeneratorExit", "IOError", "ImportError",
152.899 + // "ImportWarning", "IndentationError", "IndexError", "KeyError", "KeyboardInterrupt",
152.900 + // "LookupError", "MemoryError", "NameError", "None", "NotImplemented", "NotImplementedError",
152.901 + // "OSError", "OverflowError", "PendingDeprecationWarning", "ReferenceError", "RuntimeError",
152.902 + // "RuntimeWarning", "StandardError", "StopIteration", "SyntaxError", "SyntaxWarning", "SystemError",
152.903 + // "SystemExit", "TabError", "True", "TypeError", "UnboundLocalError", "UnicodeDecodeError",
152.904 + // "UnicodeEncodeError", "UnicodeError", "UnicodeTranslateError", "UnicodeWarning", "UserWarning",
152.905 + // "ValueError", "Warning", "ZeroDivisionError", "__debug__", "__doc__", "__import__", "__name__",
152.906 + // "abs", "all", "any", "apply", "basestring", "bool", "buffer", "callable", "chr", "classmethod",
152.907 + // "cmp", "coerce", "compile", "complex", "copyright", "credits", "delattr", "dict", "dir", "divmod",
152.908 + // "enumerate", "eval", "execfile", "exit", "file", "filter", "float", "frozenset", "getattr",
152.909 + // "globals", "hasattr", "hash", "help", "hex", "id", "input", "int", "intern", "isinstance",
152.910 + // "issubclass", "iter", "len", "license", "list", "locals", "long", "map", "max", "min", "object",
152.911 + // "oct", "open", "ord", "pow", "property", "quit", "range", "raw_input", "reduce", "reload",
152.912 + // "repr", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum",
152.913 + // "super", "tuple", "type", "unichr", "unicode", "vars", "xrange", "zip"};
152.914 + //// Most of these will be defined by my index search. However, for the missing ones, let's add them
152.915 + //// in. The following code computes the delta and produces a source-like string for it.
152.916 + //// It also counts the total symbol map size so we can pick a reasonable default:
152.917 + //List<String> asList = Arrays.asList(EXTRA_BUILTINS);
152.918 + //Set<String> asSet = new HashSet<String>(asList);
152.919 + //asSet.removeAll(symbols);
152.920 + //List<String> missing = new ArrayList<String>(asSet);
152.921 + //Collections.sort(missing);
152.922 + //int width = 0;
152.923 + //StringBuilder sb = new StringBuilder();
152.924 + //for (String s : missing) {
152.925 + // sb.append('"');
152.926 + // sb.append(s);
152.927 + // sb.append('"');
152.928 + // sb.append(',');
152.929 + // sb.append(' ');
152.930 + // width += s.length()+4;
152.931 + // if (width > 70) {
152.932 + // sb.append("\n");
152.933 + // width = 0;
152.934 + // }
152.935 + //}
152.936 + //String missingCode = "String[] MISSING = {\n" + sb.toString() + "\n};\n";
152.937 + //symbols.addAll(asList);
152.938 + //int requiredSetSize = symbols.size();
152.939 +
152.940 + return symbols;
152.941 + }
152.942 +
152.943 + @SuppressWarnings("unchecked")
152.944 + public Set<String> getImportsFor(String ident, boolean includeSymbol) {
152.945 + Set<String> modules = new HashSet<>(10);
152.946 +
152.947 + final Set<IndexResult> result = new HashSet<>();
152.948 + search(PythonIndexer.FIELD_MODULE_NAME, ident, QuerySupport.Kind.EXACT, result, PythonIndexer.FIELD_MODULE_NAME);
152.949 + for (IndexResult map : result) {
152.950 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
152.951 + if (module != null) {
152.952 + // TODO - record more information about this, such as the FQN
152.953 + // so it's easier for the user to disambiguate
152.954 + modules.add(module);
152.955 + }
152.956 + }
152.957 +
152.958 + // TODO - handle case sensitivity better...
152.959 + String field = PythonIndexer.FIELD_ITEM;
152.960 + QuerySupport.Kind kind = QuerySupport.Kind.PREFIX; // We're storing encoded signatures so not exact matches
152.961 +
152.962 + String[] terms = { PythonIndexer.FIELD_ITEM,
152.963 + PythonIndexer.FIELD_MODULE_NAME };
152.964 +
152.965 + result.clear();
152.966 + search(field, ident, kind, result, terms);
152.967 + String match = ident + ";";
152.968 +
152.969 + MapSearch:
152.970 + for (IndexResult map : result) {
152.971 + String module = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
152.972 + if (module == null) {
152.973 + continue;
152.974 + }
152.975 +
152.976 + if (module.indexOf('-') != -1) {
152.977 + // Don't include modules with -; these aren't real module
152.978 + // names (usually python scripts in directories containing a dash
152.979 + // that I incorrectly compute a module name for
152.980 + continue;
152.981 + }
152.982 +
152.983 + String[] members = map.getValues(PythonIndexer.FIELD_ITEM);
152.984 + if (members == null || members.length == 0) {
152.985 + continue;
152.986 + }
152.987 +
152.988 + int semi = match.length() - 1;
152.989 +
152.990 + for (String signature : members) {
152.991 + if (signature.startsWith(match)) {
152.992 + if (includeSymbol) {
152.993 + int flags = IndexedElement.decode(signature, semi + 3, 0);
152.994 + if ((flags & IndexedElement.PRIVATE) != 0) {
152.995 + // Skip private symbols - can't import those
152.996 + continue;
152.997 + }
152.998 + String sig = ident;
152.999 + char type = signature.charAt(semi + 1);
152.1000 + if (type == 'F') {
152.1001 + int sigStart = signature.indexOf(';', semi + 3) + 1;
152.1002 + int sigEnd = signature.indexOf(';', sigStart);
152.1003 + sig = ident + "(" + signature.substring(sigStart, sigEnd) + ")"; // NOI18N
152.1004 + } else if (type == 'I') {
152.1005 + // Don't provide modules that just -import- the symbol
152.1006 + continue;
152.1007 + }
152.1008 + if (!sig.equals(module)) {
152.1009 + modules.add(module + ": " + sig); // NOI18N
152.1010 + } else {
152.1011 + modules.add(module);
152.1012 + }
152.1013 + } else {
152.1014 + modules.add(module);
152.1015 + }
152.1016 + continue MapSearch;
152.1017 + }
152.1018 + }
152.1019 + }
152.1020 +
152.1021 + return modules;
152.1022 + }
152.1023 +
152.1024 + public Set<IndexedElement> getImportedElements(String prefix, QuerySupport.Kind kind, PythonParserResult context, List<Import> imports, List<ImportFrom> importsFrom) {
152.1025 + // TODO - separate methods from variables?? E.g. if you have method Foo() and class Foo
152.1026 + // coming from different places
152.1027 +
152.1028 +
152.1029 +// Set<String> imported = new HashSet<String>();
152.1030 +//
152.1031 + Set<IndexedElement> elements = new HashSet<>();
152.1032 +
152.1033 + // Look up the imports and compute all the symbols we get from the import
152.1034 + Set<String> modules = new HashSet<>();
152.1035 +
152.1036 + // ImportsFrom require no index lookup
152.1037 + for (ImportFrom from : importsFrom) {
152.1038 + if (ImportManager.isFutureImport(from)) {
152.1039 + continue;
152.1040 + }
152.1041 + List<alias> names = from.getInternalNames();
152.1042 + if (names != null) {
152.1043 + for (alias at : names) {
152.1044 + if ("*".equals(at.getInternalName())) { // NOI18N
152.1045 + modules.add(from.getInternalModule());
152.1046 +// } else {
152.1047 +// String name = at.getInternalAsname() != null ? at.getInternalAsname() : at.getInternalName();
152.1048 +// assert name.length() > 0;
152.1049 +// imported.add(name);
152.1050 + }
152.1051 + }
152.1052 + }
152.1053 + }
152.1054 +
152.1055 +// for (Import imp : imports) {
152.1056 +// if (imp.names != null) {
152.1057 +// for (alias at : imp.getInternalNames()) {
152.1058 +// if (at.getInternalAsname() != null) {
152.1059 +// String name = at.getInternalAsname();
152.1060 +// assert name.length() > 0;
152.1061 +// imported.add(name);
152.1062 +// } else {
152.1063 +// imported.add(at.getInternalName());
152.1064 +// }
152.1065 +// }
152.1066 +// }
152.1067 +// }
152.1068 +//
152.1069 +//
152.1070 +// // Create variable items for the locally imported symbols
152.1071 +// for (String name : imported) {
152.1072 +// if (name.startsWith(prefix)) {
152.1073 +// if (kind == QuerySupport.Kind.EXACT) {
152.1074 +// // Ensure that the method is not longer than the prefix
152.1075 +// if ((name.length() > prefix.length()) &&
152.1076 +// (name.charAt(prefix.length()) != '(') &&
152.1077 +// (name.charAt(prefix.length()) != ';')) {
152.1078 +// continue;
152.1079 +// }
152.1080 +// } else {
152.1081 +// // REGEXP, CAMELCASE filtering etc. not supported here
152.1082 +// assert (kind == QuerySupport.Kind.PREFIX) ||
152.1083 +// (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
152.1084 +// }
152.1085 +// String url = null;
152.1086 +// ElementKind elementKind = ElementKind.VARIABLE;
152.1087 +// if (Character.isUpperCase(name.charAt(0))) {
152.1088 +// // Class?
152.1089 +// elementKind = ElementKind.CLASS;
152.1090 +// }
152.1091 +// IndexedElement element = new IndexedElement(name, elementKind, url, null);
152.1092 +// element.setSmart(true);
152.1093 +// elements.add(element);
152.1094 +// // TODO - imported class symbls should be shown as classes!
152.1095 +// }
152.1096 +// }
152.1097 +
152.1098 + // Always include the current file as imported
152.1099 + String moduleName = null;
152.1100 + if (context != null) {
152.1101 + moduleName = PythonUtils.getModuleName(context.getSnapshot().getSource().getFileObject());
152.1102 + modules.add(moduleName);
152.1103 + }
152.1104 +
152.1105 + modules.addAll(BUILTIN_MODULES);
152.1106 +
152.1107 + addImportedElements(prefix, kind, modules, elements, null);
152.1108 +
152.1109 + return elements;
152.1110 + }
152.1111 + public Set<String> getImportedFromWildcards(List<ImportFrom> importsFrom) {
152.1112 + Set<String> symbols = new HashSet<>(100);
152.1113 +
152.1114 + // Look up the imports and compute all the symbols we get from the import
152.1115 + Set<String> modules = new HashSet<>();
152.1116 +
152.1117 + // ImportsFrom require no index lookup
152.1118 + for (ImportFrom from : importsFrom) {
152.1119 + List<alias> names = from.getInternalNames();
152.1120 + if (names != null) {
152.1121 + for (alias at : names) {
152.1122 + if ("*".equals(at.getInternalName())) { // NOI18N
152.1123 + modules.add(from.getInternalModule());
152.1124 + }
152.1125 + }
152.1126 + }
152.1127 + }
152.1128 +
152.1129 + String[] terms = { PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MODULE_NAME };
152.1130 +
152.1131 + // Look up all symbols
152.1132 + for (String module : modules) {
152.1133 + // TODO - cache builtins?
152.1134 + Set<String> moduleSymbols = symbols;
152.1135 + boolean isSystem = isSystemModule(module);
152.1136 + if (isSystem) {
152.1137 + Set<String> s = wildcardImports.get(module);
152.1138 + if (s != null) {
152.1139 + symbols.addAll(s);
152.1140 + continue;
152.1141 + } else {
152.1142 + moduleSymbols = new HashSet<>(100);
152.1143 + }
152.1144 + }
152.1145 +
152.1146 +
152.1147 + final Set<IndexResult> result = new HashSet<>();
152.1148 + // TODO - handle case sensitivity better...
152.1149 +
152.1150 + search(PythonIndexer.FIELD_MODULE_NAME, module, QuerySupport.Kind.EXACT, result, terms);
152.1151 +
152.1152 + for (IndexResult map : result) {
152.1153 + String[] items = map.getValues(PythonIndexer.FIELD_ITEM);
152.1154 + if (items != null) {
152.1155 + for (String signature : items) {
152.1156 + int semi = signature.indexOf(';');
152.1157 + assert semi != -1;
152.1158 + int flags = IndexedElement.decode(signature, semi + 3, 0);
152.1159 + if ((flags & IndexedElement.PRIVATE) != 0) {
152.1160 + // Skip private symbols - can't import those
152.1161 + continue;
152.1162 + }
152.1163 +
152.1164 + String name = signature.substring(0, semi);
152.1165 + moduleSymbols.add(name);
152.1166 + }
152.1167 + }
152.1168 + }
152.1169 +
152.1170 + if (isSystem) {
152.1171 + assert moduleSymbols != symbols;
152.1172 + symbols.addAll(moduleSymbols);
152.1173 + wildcardImports.put(module, moduleSymbols);
152.1174 + }
152.1175 + }
152.1176 +
152.1177 + return symbols;
152.1178 + }
152.1179 +
152.1180 + public Set<IndexedElement> getImportedElements(String prefix, QuerySupport.Kind kind, Set<String> modules, Set<String> systemModuleHolder) {
152.1181 + Set<IndexedElement> elements = new HashSet<>();
152.1182 +
152.1183 + addImportedElements(prefix, kind, modules, elements, systemModuleHolder);
152.1184 +
152.1185 + return elements;
152.1186 + }
152.1187 +
152.1188 + public boolean isSystemModule(String module) {
152.1189 + if (systemModules == null) {
152.1190 + systemModules = new HashSet<>(800); // measured: 623
152.1191 + String[] terms = { PythonIndexer.FIELD_MODULE_ATTR_NAME,
152.1192 + PythonIndexer.FIELD_MODULE_NAME };
152.1193 + final Set<IndexResult> result = new HashSet<>();
152.1194 +
152.1195 + // This doesn't work because the attrs field isn't searchable:
152.1196 + //search(PythonIndexer.FIELD_MODULE_ATTR_NAME, "S", QuerySupport.Kind.PREFIX, result, ALL_SCOPE, terms);
152.1197 + //for (IndexResult map : result) {
152.1198 + // assert map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME).indexOf("S") != -1;
152.1199 + // systemModules.add(map.getValue(PythonIndexer.FIELD_MODULE_NAME));
152.1200 + //}
152.1201 +
152.1202 + search(PythonIndexer.FIELD_MODULE_NAME, "", QuerySupport.Kind.PREFIX, result, terms);
152.1203 +
152.1204 + for (IndexResult map : result) {
152.1205 + String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
152.1206 + if (attrs != null && attrs.indexOf('S') != -1) {
152.1207 + String mod = map.getValue(PythonIndexer.FIELD_MODULE_NAME);
152.1208 + systemModules.add(mod);
152.1209 + }
152.1210 + }
152.1211 + }
152.1212 +
152.1213 + return systemModules.contains(module);
152.1214 + }
152.1215 +
152.1216 + public boolean isLowercaseClassName(String clz) {
152.1217 + if (availableClasses == null) {
152.1218 + availableClasses = new HashSet<>(300); // measured: 193
152.1219 + final Set<IndexResult> result = new HashSet<>();
152.1220 +
152.1221 + search(PythonIndexer.FIELD_CLASS_NAME, "", QuerySupport.Kind.PREFIX, result, PythonIndexer.FIELD_CLASS_NAME);
152.1222 +
152.1223 + for (IndexResult map : result) {
152.1224 + String c = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.1225 + if (c != null && !Character.isUpperCase(c.charAt(0))) {
152.1226 + availableClasses.add(c);
152.1227 + }
152.1228 + }
152.1229 + }
152.1230 +
152.1231 + return availableClasses.contains(clz);
152.1232 + }
152.1233 +
152.1234 + public void addImportedElements(String prefix, QuerySupport.Kind kind, Set<String> modules, Set<IndexedElement> elements, Set<String> systemModuleHolder) {
152.1235 +
152.1236 + String[] terms = { PythonIndexer.FIELD_ITEM,
152.1237 + PythonIndexer.FIELD_MODULE_ATTR_NAME,
152.1238 + PythonIndexer.FIELD_MODULE_NAME };
152.1239 +
152.1240 + // Look up all symbols
152.1241 + for (String module : modules) {
152.1242 + boolean isBuiltin = isBuiltinModule(module);
152.1243 + boolean isSystem = isBuiltin;
152.1244 +
152.1245 + final Set<IndexResult> result = new HashSet<>();
152.1246 + // TODO - handle case sensitivity better...
152.1247 +
152.1248 + search(PythonIndexer.FIELD_MODULE_NAME, module, QuerySupport.Kind.EXACT, result, terms);
152.1249 + int prefixLength = prefix.length();
152.1250 +
152.1251 + for (IndexResult map : result) {
152.1252 + String url = map.getUrl().toExternalForm();
152.1253 + String[] items = map.getValues(PythonIndexer.FIELD_ITEM);
152.1254 + if (items != null) {
152.1255 + String attrs = map.getValue(PythonIndexer.FIELD_MODULE_ATTR_NAME);
152.1256 + if (attrs != null && attrs.indexOf('S') != -1) {
152.1257 + isSystem = true;
152.1258 + }
152.1259 + for (String signature : items) {
152.1260 + if (signature.startsWith(prefix)) {
152.1261 + if (kind == QuerySupport.Kind.EXACT) {
152.1262 + if (signature.charAt(prefixLength) != ';') {
152.1263 + continue;
152.1264 + }
152.1265 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !signature.regionMatches(true, 0, prefix, 0, prefix.length())) {
152.1266 + continue;
152.1267 + } else {
152.1268 + // REGEXP, CAMELCASE filtering etc. not supported here
152.1269 + assert (kind == QuerySupport.Kind.PREFIX) ||
152.1270 + (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX);
152.1271 + }
152.1272 +
152.1273 + IndexedElement element = IndexedElement.create(signature, module, url, null);
152.1274 + if (element.isPrivate()) {
152.1275 + continue;
152.1276 + }
152.1277 + if (isBuiltin) {
152.1278 + element.setRhs("<i>builtin</i>");
152.1279 + } else {
152.1280 + element.setSmart(true);
152.1281 + }
152.1282 + element.setInherited(true);
152.1283 + elements.add(element);
152.1284 + }
152.1285 + }
152.1286 + }
152.1287 + }
152.1288 +
152.1289 + if (systemModuleHolder != null && isSystem) {
152.1290 + systemModuleHolder.add(module);
152.1291 + }
152.1292 + }
152.1293 + }
152.1294 +
152.1295 + public Set<IndexedElement> getExceptions(String prefix, QuerySupport.Kind kind) {
152.1296 + final Set<IndexResult> result = new HashSet<>();
152.1297 + String[] terms = { PythonIndexer.FIELD_EXTENDS_NAME,
152.1298 + PythonIndexer.FIELD_CLASS_NAME,
152.1299 + PythonIndexer.FIELD_CLASS_ATTR_NAME,
152.1300 + PythonIndexer.FIELD_IN };
152.1301 + search(PythonIndexer.FIELD_EXTENDS_NAME, "", QuerySupport.Kind.PREFIX, result, terms); // NOI18N
152.1302 + Map<String, String> extendsMap = new HashMap<>(100);
152.1303 + // First iteration: Compute inheritance hierarchy
152.1304 + for (IndexResult map : result) {
152.1305 +
152.1306 + String superClass = map.getValue(PythonIndexer.FIELD_EXTENDS_NAME);
152.1307 + if (superClass != null) {
152.1308 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.1309 + if (clz != null) {
152.1310 + extendsMap.put(clz, superClass);
152.1311 + }
152.1312 + }
152.1313 + }
152.1314 +
152.1315 + // Compute set of classes that extend Exception
152.1316 +
152.1317 + Set<String> exceptionClasses = new HashSet<>();
152.1318 + Set<String> notExceptionClasses = new HashSet<>();
152.1319 + exceptionClasses.add("Exception"); // NOI18N
152.1320 + Outer:
152.1321 + for (String cls : extendsMap.keySet()) {
152.1322 + if (notExceptionClasses.contains(cls)) {
152.1323 + continue;
152.1324 + } else if (!exceptionClasses.contains(cls)) {
152.1325 + // See if this extends exception:
152.1326 + String c = cls;
152.1327 + int depth = 0;
152.1328 + while (c != null) {
152.1329 + c = extendsMap.get(c);
152.1330 + String prev = null;
152.1331 + if (c != null) {
152.1332 + if (exceptionClasses.contains(c)) {
152.1333 + exceptionClasses.add(cls);
152.1334 + continue Outer;
152.1335 + }
152.1336 + depth++;
152.1337 + if (depth == 15) {
152.1338 + // we're probably going in circles, perhaps a extends b extends a.
152.1339 + // This doesn't really happen in Python, but can happen when there
152.1340 + // are unrelated classes with the same name getting treated as one here -
152.1341 + // class a in library X, and class a in library Y,
152.1342 + break;
152.1343 + }
152.1344 + } else if (prev != null) {
152.1345 + notExceptionClasses.add(prev);
152.1346 + break;
152.1347 + }
152.1348 + }
152.1349 + notExceptionClasses.add(cls);
152.1350 + }
152.1351 + }
152.1352 +
152.1353 + // Next add elements for all the exceptions
152.1354 + final Set<IndexedElement> classes = new HashSet<>();
152.1355 + for (IndexResult map : result) {
152.1356 + String clz = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.1357 + if (clz == null || !exceptionClasses.contains(clz)) {
152.1358 + continue;
152.1359 + }
152.1360 +
152.1361 + if ((kind == QuerySupport.Kind.PREFIX) && !clz.startsWith(prefix)) {
152.1362 + continue;
152.1363 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX && !clz.regionMatches(true, 0, prefix, 0, prefix.length())) {
152.1364 + continue;
152.1365 + } else if (kind == QuerySupport.Kind.EXACT && !clz.equals(prefix)) {
152.1366 + continue;
152.1367 + }
152.1368 +
152.1369 + String url = map.getUrl().toExternalForm();
152.1370 + String module = map.getValue(PythonIndexer.FIELD_IN);
152.1371 + IndexedElement element = new IndexedElement(clz, ElementKind.CLASS, url, module, null, null);
152.1372 + String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
152.1373 + if (attrs != null) {
152.1374 + int flags = IndexedElement.decode(attrs, 0, 0);
152.1375 + element.setFlags(flags);
152.1376 + }
152.1377 + classes.add(element);
152.1378 + }
152.1379 +
152.1380 + return classes;
152.1381 + }
152.1382 +
152.1383 + /** Find the subclasses of the given class name, with the POSSIBLE fqn from the
152.1384 + * context of the usage. */
152.1385 + public Set<IndexedElement> getSubClasses(String fqn, String possibleFqn, String name, boolean directOnly) {
152.1386 + //String field = PythonIndexer.FIELD_FQN_NAME;
152.1387 + Set<IndexedElement> classes = new HashSet<>();
152.1388 + Set<String> scannedClasses = new HashSet<>();
152.1389 + Set<String> seenClasses = new HashSet<>();
152.1390 +
152.1391 + if (fqn != null) {
152.1392 + addSubclasses(fqn, classes, seenClasses, scannedClasses, directOnly);
152.1393 + } else {
152.1394 + fqn = possibleFqn;
152.1395 + if (name.equals(possibleFqn)) {
152.1396 + fqn = null;
152.1397 + }
152.1398 +
152.1399 + // Try looking at the libraries too
152.1400 + while ((classes.size() == 0) && (fqn != null && fqn.length() > 0)) {
152.1401 + // TODO - use the boolvalue from addclasses instead!
152.1402 + boolean found = addSubclasses(fqn + "::" + name, classes, seenClasses, scannedClasses, directOnly);
152.1403 + if (found) {
152.1404 + return classes;
152.1405 + }
152.1406 +
152.1407 + int f = fqn.lastIndexOf("::");
152.1408 +
152.1409 + if (f == -1) {
152.1410 + break;
152.1411 + } else {
152.1412 + fqn = fqn.substring(0, f);
152.1413 + }
152.1414 + }
152.1415 +
152.1416 + if (classes.size() == 0) {
152.1417 + addSubclasses(name, classes, seenClasses, scannedClasses, directOnly);
152.1418 + }
152.1419 + }
152.1420 +
152.1421 + return classes;
152.1422 + }
152.1423 +
152.1424 + private boolean addSubclasses(String classFqn, Set<IndexedElement> classes, Set<String> seenClasses, Set<String> scannedClasses, boolean directOnly) {
152.1425 + // Prevent problems with circular includes or redundant includes
152.1426 + if (scannedClasses.contains(classFqn)) {
152.1427 + return false;
152.1428 + }
152.1429 +
152.1430 + scannedClasses.add(classFqn);
152.1431 +
152.1432 + String searchField = PythonIndexer.FIELD_EXTENDS_NAME;
152.1433 +
152.1434 + Set<IndexResult> result = new HashSet<>();
152.1435 +
152.1436 + String[] terms = { PythonIndexer.FIELD_IN,
152.1437 + PythonIndexer.FIELD_EXTENDS_NAME,
152.1438 + PythonIndexer.FIELD_CLASS_ATTR_NAME,
152.1439 + PythonIndexer.FIELD_CLASS_NAME };
152.1440 +
152.1441 + search(searchField, classFqn, QuerySupport.Kind.EXACT, result, terms);
152.1442 +
152.1443 + boolean foundIt = result.size() > 0;
152.1444 +
152.1445 + // If this is a bogus class entry (no search rsults) don't continue
152.1446 + if (!foundIt) {
152.1447 + return foundIt;
152.1448 + }
152.1449 +
152.1450 + for (IndexResult map : result) {
152.1451 + String className = map.getValue(PythonIndexer.FIELD_CLASS_NAME);
152.1452 + if (className != null && !seenClasses.contains(className)) {
152.1453 + String url = map.getUrl().toExternalForm();
152.1454 + String module = map.getValue(PythonIndexer.FIELD_IN);
152.1455 + IndexedElement clz = new IndexedElement(className, ElementKind.CLASS, url, module, null, null);
152.1456 + String attrs = map.getValue(PythonIndexer.FIELD_CLASS_ATTR_NAME);
152.1457 + if (attrs != null) {
152.1458 + int flags = IndexedElement.decode(attrs, 0, 0);
152.1459 + clz.setFlags(flags);
152.1460 + }
152.1461 + classes.add(clz);
152.1462 +
152.1463 + seenClasses.add(className);
152.1464 +
152.1465 + if (!directOnly) {
152.1466 + addSubclasses(className, classes, seenClasses, scannedClasses, directOnly);
152.1467 + }
152.1468 + }
152.1469 + }
152.1470 +
152.1471 + return foundIt;
152.1472 + }
152.1473 +}
153.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
153.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndexSearcher.java Wed Sep 02 20:31:18 2015 +0200
153.3 @@ -0,0 +1,252 @@
153.4 +/*
153.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
153.6 + *
153.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
153.8 + *
153.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
153.10 + * Other names may be trademarks of their respective owners.
153.11 + *
153.12 + * The contents of this file are subject to the terms of either the GNU
153.13 + * General Public License Version 2 only ("GPL") or the Common
153.14 + * Development and Distribution License("CDDL") (collectively, the
153.15 + * "License"). You may not use this file except in compliance with the
153.16 + * License. You can obtain a copy of the License at
153.17 + * http://www.netbeans.org/cddl-gplv2.html
153.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
153.19 + * specific language governing permissions and limitations under the
153.20 + * License. When distributing the software, include this License Header
153.21 + * Notice in each file and include the License file at
153.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
153.23 + * particular file as subject to the "Classpath" exception as provided
153.24 + * by Oracle in the GPL Version 2 section of the License file that
153.25 + * accompanied this code. If applicable, add the following below the
153.26 + * License Header, with the fields enclosed by brackets [] replaced by
153.27 + * your own identifying information:
153.28 + * "Portions Copyrighted [year] [name of copyright owner]"
153.29 + *
153.30 + * Contributor(s):
153.31 + *
153.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
153.33 + */
153.34 +package org.netbeans.modules.python.source;
153.35 +
153.36 +import java.awt.Toolkit;
153.37 +import java.util.HashSet;
153.38 +import java.util.Set;
153.39 +import java.util.logging.Logger;
153.40 +import javax.swing.Icon;
153.41 +import org.netbeans.modules.python.source.elements.IndexedElement;
153.42 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
153.43 +import org.netbeans.api.project.FileOwnerQuery;
153.44 +import org.netbeans.api.project.Project;
153.45 +import org.netbeans.api.project.ProjectInformation;
153.46 +import org.netbeans.api.project.ProjectUtils;
153.47 +import org.netbeans.modules.csl.api.ElementHandle;
153.48 +import org.netbeans.modules.csl.api.IndexSearcher;
153.49 +import org.netbeans.modules.csl.api.IndexSearcher.Descriptor;
153.50 +import org.netbeans.modules.csl.api.IndexSearcher.Helper;
153.51 +import org.netbeans.modules.csl.spi.GsfUtilities;
153.52 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
153.53 +import org.openide.filesystems.FileObject;
153.54 +import org.openide.util.ImageUtilities;
153.55 +import org.python.antlr.PythonTree;
153.56 +
153.57 +/**
153.58 + *
153.59 + * @author Tor Norbye
153.60 + */
153.61 +public class PythonIndexSearcher implements IndexSearcher {
153.62 +
153.63 + @Override
153.64 + public Set<? extends Descriptor> getTypes(Project prjct, String textForQuery, QuerySupport.Kind kind, Helper helper) {
153.65 + PythonIndex index = PythonIndex.get(prjct);
153.66 + Set<PythonSymbol> result = new HashSet<>();
153.67 + Set<? extends IndexedElement> elements;
153.68 +
153.69 + // TODO - do some filtering if you use ./#
153.70 + // int dot = textForQuery.lastIndexOf('.');
153.71 + // if (dot != -1 && (kind == QuerySupport.Kind.PREFIX || kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX)) {
153.72 + // String prefix = textForQuery.substring(dot+1);
153.73 + // String in = textForQuery.substring(0, dot);
153.74 +
153.75 + elements = index.getClasses(textForQuery, kind, null, true);
153.76 + for (IndexedElement element : elements) {
153.77 + result.add(new PythonSymbol(element, helper));
153.78 + }
153.79 +
153.80 + return result;
153.81 + }
153.82 +
153.83 + @Override
153.84 + public Set<? extends Descriptor> getSymbols(Project prjct, String textForQuery, QuerySupport.Kind kind, Helper helper) {
153.85 + PythonIndex index = PythonIndex.get(prjct);
153.86 + Set<PythonSymbol> result = new HashSet<>();
153.87 + Set<? extends IndexedElement> elements;
153.88 +
153.89 + // TODO - do some filtering if you use ./#
153.90 + // int dot = textForQuery.lastIndexOf('.');
153.91 + // if (dot != -1 && (kind == QuerySupport.Kind.PREFIX || kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX)) {
153.92 + // String prefix = textForQuery.substring(dot+1);
153.93 + // String in = textForQuery.substring(0, dot);
153.94 +
153.95 + elements = index.getAllMembers(textForQuery, kind, null, true);
153.96 + for (IndexedElement element : elements) {
153.97 + result.add(new PythonSymbol(element, helper));
153.98 + }
153.99 + elements = index.getClasses(textForQuery, kind, null, true);
153.100 + for (IndexedElement element : elements) {
153.101 + result.add(new PythonSymbol(element, helper));
153.102 + }
153.103 + elements = index.getModules(textForQuery, kind);
153.104 + for (IndexedElement element : elements) {
153.105 + result.add(new PythonSymbol(element, helper));
153.106 + }
153.107 +
153.108 + return result;
153.109 + }
153.110 +
153.111 + private class PythonSymbol extends Descriptor {
153.112 + private final IndexedElement element;
153.113 + private String projectName;
153.114 + private Icon projectIcon;
153.115 + private final Helper helper;
153.116 + private boolean isLibrary;
153.117 + private static final String ICON_PATH = "org/netbeans/modules/python/editor/resources/pyc_16.png"; //NOI18N
153.118 +
153.119 + public PythonSymbol(IndexedElement element, Helper helper) {
153.120 + this.element = element;
153.121 + this.helper = helper;
153.122 + }
153.123 +
153.124 + @Override
153.125 + public Icon getIcon() {
153.126 + if (projectName == null) {
153.127 + initProjectInfo();
153.128 + }
153.129 + //if (isLibrary) {
153.130 + // return new ImageIcon(org.openide.util.ImageUtilities.loadImage(PYTHON_KEYWORD));
153.131 + //}
153.132 + return helper.getIcon(element);
153.133 + }
153.134 +
153.135 + @Override
153.136 + public String getTypeName() {
153.137 + return element.getName();
153.138 + }
153.139 +
153.140 + @Override
153.141 + public String getProjectName() {
153.142 + if (projectName == null) {
153.143 + initProjectInfo();
153.144 + }
153.145 + return projectName;
153.146 + }
153.147 +
153.148 + private void initProjectInfo() {
153.149 + FileObject fo = element.getFileObject();
153.150 + if (fo != null) {
153.151 +// File f = FileUtil.toFile(fo);
153.152 + Project p = FileOwnerQuery.getOwner(fo);
153.153 + if (p != null) {
153.154 +// JsPlatform platform = JsPlatform.platformFor(p);
153.155 +// if (platform != null) {
153.156 +// String lib = platform.getLib();
153.157 +// if (lib != null && f.getPath().startsWith(lib)) {
153.158 +// projectName = "Js Library";
153.159 +// isLibrary = true;
153.160 +// }
153.161 +// } else {
153.162 + ProjectInformation pi = ProjectUtils.getInformation(p);
153.163 + projectName = pi.getDisplayName();
153.164 + projectIcon = pi.getIcon();
153.165 +// }
153.166 + }
153.167 + } else {
153.168 + isLibrary = true;
153.169 + Logger.getLogger(PythonIndexSearcher.class.getName()).fine("No fileobject for " + element.toString() + " with fileurl=" + element.getFilenameUrl());
153.170 + }
153.171 + if (projectName == null) {
153.172 + projectName = "";
153.173 + }
153.174 + }
153.175 +
153.176 + @Override
153.177 + public Icon getProjectIcon() {
153.178 + if (projectName == null) {
153.179 + initProjectInfo();
153.180 + }
153.181 + if (isLibrary) {
153.182 + return ImageUtilities.loadImageIcon(ICON_PATH, false);
153.183 + }
153.184 + return projectIcon;
153.185 + }
153.186 +
153.187 + @Override
153.188 + public FileObject getFileObject() {
153.189 + return element.getFileObject();
153.190 + }
153.191 +
153.192 + @Override
153.193 + public void open() {
153.194 + PythonParserResult[] parserResultRet = new PythonParserResult[1];
153.195 + PythonTree node = PythonAstUtils.getForeignNode(element, parserResultRet);
153.196 +
153.197 + if (node != null) {
153.198 + int astOffset = PythonAstUtils.getRange(node).getStart();
153.199 + int lexOffset = PythonLexerUtils.getLexerOffset(parserResultRet[0], astOffset);
153.200 + if (lexOffset == -1) {
153.201 + lexOffset = 0;
153.202 + }
153.203 + GsfUtilities.open(element.getFileObject(), lexOffset, element.getName());
153.204 + return;
153.205 + }
153.206 +
153.207 + FileObject fileObject = element.getFileObject();
153.208 + if (fileObject == null) {
153.209 + // This should no longer be needed - we perform auto deletion in GSF
153.210 + Toolkit.getDefaultToolkit().beep();
153.211 + return;
153.212 + }
153.213 +
153.214 + helper.open(fileObject, element);
153.215 + }
153.216 +
153.217 + @Override
153.218 + public String getContextName() {
153.219 + // XXX This is lame - move formatting logic to the goto action!
153.220 +// StringBuilder sb = new StringBuilder();
153.221 +// String require = element.getRequire();
153.222 +// String fqn = element.getFqn();
153.223 + String fqn = element.getIn() != null ? element.getIn() + "." + element.getName() : element.getName();
153.224 + if (element.getName().equals(fqn)) {
153.225 + fqn = null;
153.226 + String url = element.getFilenameUrl();
153.227 + if (url != null) {
153.228 + return url.substring(url.lastIndexOf('/') + 1);
153.229 + }
153.230 + }
153.231 +
153.232 + return fqn;
153.233 + }
153.234 +
153.235 + @Override
153.236 + public ElementHandle getElement() {
153.237 + return element;
153.238 + }
153.239 +
153.240 + @Override
153.241 + public int getOffset() {
153.242 + throw new UnsupportedOperationException("Not supported yet.");
153.243 + }
153.244 +
153.245 + @Override
153.246 + public String getSimpleName() {
153.247 + return element.getName();
153.248 + }
153.249 +
153.250 + @Override
153.251 + public String getOuterName() {
153.252 + return null;
153.253 + }
153.254 + }
153.255 +}
154.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
154.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndexer.java Wed Sep 02 20:31:18 2015 +0200
154.3 @@ -0,0 +1,1399 @@
154.4 +/*
154.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
154.6 + *
154.7 + * Copyright 1997-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 + * Contributor(s):
154.31 + *
154.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
154.33 + */
154.34 +package org.netbeans.modules.python.source;
154.35 +
154.36 +import java.io.File;
154.37 +import java.io.IOException;
154.38 +import java.net.MalformedURLException;
154.39 +import java.net.URL;
154.40 +import java.util.ArrayList;
154.41 +import java.util.Collections;
154.42 +import java.util.HashMap;
154.43 +import java.util.List;
154.44 +import java.util.Map;
154.45 +import java.util.logging.Level;
154.46 +import java.util.logging.Logger;
154.47 +import java.util.regex.Matcher;
154.48 +import java.util.regex.Pattern;
154.49 +import javax.swing.text.BadLocationException;
154.50 +import org.netbeans.editor.BaseDocument;
154.51 +import org.netbeans.modules.csl.spi.GsfUtilities;
154.52 +import org.netbeans.modules.csl.spi.ParserResult;
154.53 +import org.netbeans.modules.parsing.api.Snapshot;
154.54 +import org.netbeans.modules.parsing.spi.Parser;
154.55 +import org.netbeans.modules.parsing.spi.indexing.Context;
154.56 +import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer;
154.57 +import org.netbeans.modules.parsing.spi.indexing.Indexable;
154.58 +import org.netbeans.modules.parsing.spi.indexing.support.IndexDocument;
154.59 +import org.netbeans.modules.parsing.spi.indexing.support.IndexingSupport;
154.60 +import org.netbeans.modules.python.api.PythonPlatform;
154.61 +import org.netbeans.modules.python.api.PythonPlatformManager;
154.62 +import org.netbeans.modules.python.source.elements.IndexedElement;
154.63 +import org.netbeans.modules.python.source.scopes.ScopeConstants;
154.64 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
154.65 +import org.netbeans.modules.python.source.scopes.SymbolTable;
154.66 +import org.netbeans.modules.python.source.scopes.SymInfo;
154.67 +import org.netbeans.modules.python.source.queries.DeprecationQuery;
154.68 +import org.openide.filesystems.FileObject;
154.69 +import org.openide.filesystems.FileUtil;
154.70 +import org.openide.filesystems.URLMapper;
154.71 +import org.openide.util.Exceptions;
154.72 +import org.python.antlr.PythonTree;
154.73 +import org.python.antlr.ast.ClassDef;
154.74 +import org.python.antlr.ast.FunctionDef;
154.75 +import org.python.antlr.ast.Module;
154.76 +import org.python.antlr.ast.Name;
154.77 +import org.python.antlr.base.expr;
154.78 +
154.79 +/**
154.80 + *
154.81 + * @todo Store information about all symbols exported by a module.
154.82 + * I can use that to provide "unused import" help.
154.83 + * @todo Clean this stuff up: store data, functions, etc.
154.84 + * @todo Improve detection of builtins. Perhaps run from within Python,
154.85 + * something like this:
154.86 +>>> dir(__builtins__)
154.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']
154.88 + *
154.89 + * My code for scanning for functions has to be smarter:
154.90 +.. function:: ljust(s, width)
154.91 +rjust(s, width)
154.92 +center(s, width)
154.93 + * Here I need to pick up all 3 signatures!
154.94 + * @author Tor Norbye
154.95 + */
154.96 +public class PythonIndexer extends EmbeddingIndexer {
154.97 + public static final String NAME = "PythonIndexer";
154.98 + public static final int VERSION = 1;
154.99 + public static boolean PREINDEXING = Boolean.getBoolean("gsf.preindexing"); // NOI18N
154.100 + public static final String FIELD_MEMBER = "member"; //NOI18N
154.101 + public static final String FIELD_MODULE_NAME = "module"; //NOI18N
154.102 + public static final String FIELD_MODULE_ATTR_NAME = "modattrs"; //NOI18N
154.103 + public static final String FIELD_CLASS_ATTR_NAME = "clzattrs"; //NOI18N
154.104 + public static final String FIELD_EXTENDS_NAME = "extends"; //NOI18N
154.105 + public static final String FIELD_ITEM = "item"; //NOI18N
154.106 + public static final String FIELD_IN = "in"; //NOI18N
154.107 + public static final String FIELD_CLASS_NAME = "class"; //NOI18N
154.108 + public static final String FIELD_CASE_INSENSITIVE_CLASS_NAME = "class-ig"; //NOI18N
154.109 + private FileObject prevParent;
154.110 + private boolean prevResult;
154.111 +
154.112 + public static boolean isIndexable(Indexable indexable, Snapshot snapshot) {
154.113 + FileObject fo = snapshot.getSource().getFileObject();
154.114 + String extension = fo.getExt();
154.115 + if ("py".equals(extension)) { // NOI18N
154.116 + return true;
154.117 + }
154.118 +
154.119 + if ("rst".equals(extension)) { // NOI18N
154.120 + // Index restructured text if it looks like it contains Python library
154.121 + // definitions
154.122 + return true;
154.123 + }
154.124 +
154.125 + if ("egg".equals(extension)) { // NOI18N
154.126 + return true;
154.127 + }
154.128 +
154.129 + return false;
154.130 + }
154.131 +
154.132 +
154.133 + public boolean isIndexable(Snapshot file) {
154.134 + FileObject fo = file.getSource().getFileObject();
154.135 + String extension = fo.getExt();
154.136 + if ("py".equals(extension)) { // NOI18N
154.137 +
154.138 + // Skip "test" folders under lib... Lots of weird files there
154.139 + // and we don't want to pollute the index with them
154.140 + FileObject parent = fo.getParent();
154.141 +
154.142 + if (parent != null && parent.getName().equals("test")) { // NOI18N
154.143 + // Make sure it's really a lib folder, we want to include the
154.144 + // user's files
154.145 +
154.146 + // Avoid double-indexing files that have multiple versions - e.g. foo.js and foo-min.js
154.147 + // or foo.uncompressed
154.148 + FileObject parentFo = fo.getParent();
154.149 + if (prevParent == parentFo) {
154.150 + return prevResult;
154.151 + }
154.152 + prevResult = true;
154.153 + prevParent = parentFo;
154.154 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
154.155 + Platforms:
154.156 + for (String name : manager.getPlatformList()) {
154.157 + PythonPlatform platform = manager.getPlatform(name);
154.158 + if (platform != null) {
154.159 + for (FileObject root : platform.getLibraryRoots()) {
154.160 + if (FileUtil.isParentOf(root, parentFo)) {
154.161 + prevResult = false;
154.162 + break Platforms;
154.163 + }
154.164 + }
154.165 + }
154.166 + }
154.167 + }
154.168 +
154.169 + return true;
154.170 + }
154.171 +
154.172 + if ("rst".equals(extension)) { // NOI18N
154.173 + // Index restructured text if it looks like it contains Python library
154.174 + // definitions
154.175 + return true;
154.176 + }
154.177 +
154.178 + if ("egg".equals(extension)) { // NOI18N
154.179 + return true;
154.180 + }
154.181 +
154.182 + return false;
154.183 + }
154.184 +
154.185 + @Override
154.186 + protected void index(Indexable indexable, Parser.Result result, Context context) {
154.187 + PythonParserResult parseResult = (PythonParserResult)result;
154.188 + if (parseResult == null) {
154.189 + return;
154.190 + }
154.191 +
154.192 + IndexingSupport support;
154.193 + try {
154.194 + support = IndexingSupport.getInstance(context);
154.195 + } catch (IOException ioe) {
154.196 + LOG.log(Level.WARNING, null, ioe);
154.197 + return;
154.198 + }
154.199 +
154.200 + support.removeDocuments(indexable);
154.201 +
154.202 + FileObject fileObject = result.getSnapshot().getSource().getFileObject();
154.203 + String extension = fileObject.getNameExt();
154.204 +
154.205 + if (extension.endsWith(".rst")) { // NOI18N
154.206 + scanRst(fileObject, indexable, support, null);
154.207 + } else if (extension.endsWith(".egg")) { // NOI18N
154.208 + scanEgg(fileObject, indexable, parseResult, support);
154.209 + } else {
154.210 + // Normal python file
154.211 + new IndexTask(parseResult, support).scan();
154.212 + }
154.213 + }
154.214 + private static final Logger LOG = Logger.getLogger(PythonIndexer.class.getName());
154.215 +
154.216 + public boolean acceptQueryPath(String url) {
154.217 + return !url.contains("jsstubs"); // NOI18N
154.218 + }
154.219 +
154.220 + public String getPersistentUrl(File file) {
154.221 + String url;
154.222 + try {
154.223 + url = file.toURI().toURL().toExternalForm();
154.224 +
154.225 + // Make relative URLs for urls in the libraries
154.226 + return PythonIndex.getPreindexUrl(url);
154.227 + } catch (MalformedURLException ex) {
154.228 + Exceptions.printStackTrace(ex);
154.229 + return file.getPath();
154.230 + }
154.231 + }
154.232 +
154.233 + public String getIndexVersion() {
154.234 + return "0.123"; // NOI18N
154.235 + }
154.236 +
154.237 + public String getIndexerName() {
154.238 + return "python"; // NOI18N
154.239 + }
154.240 +
154.241 + public FileObject getPreindexedDb() {
154.242 + return null;
154.243 + }
154.244 +
154.245 + private static void appendFlags(StringBuilder sb, char c, SymInfo sym, int flags) {
154.246 + sb.append(';');
154.247 + sb.append(c);
154.248 + sb.append(';');
154.249 +
154.250 + if (sym.isPrivate()) {
154.251 + flags |= IndexedElement.PRIVATE;
154.252 + }
154.253 + if (c == 'c') {
154.254 + flags |= IndexedElement.CONSTRUCTOR;
154.255 + }
154.256 +
154.257 + sb.append(IndexedElement.encode(flags));
154.258 + sb.append(';');
154.259 + }
154.260 + private static final int DEFAULT_DOC_SIZE = 40; // TODO Measure
154.261 +
154.262 + private static class IndexTask {
154.263 + private PythonParserResult result;
154.264 + private FileObject file;
154.265 + private IndexingSupport support;
154.266 + private List<IndexDocument> documents = new ArrayList<>();
154.267 + private String url;
154.268 + private String module;
154.269 + private SymbolTable symbolTable;
154.270 + private String overrideUrl;
154.271 +
154.272 + private IndexTask(PythonParserResult result, IndexingSupport support) {
154.273 + this.result = result;
154.274 + this.file = result.getSnapshot().getSource().getFileObject();
154.275 + this.support = support;
154.276 +
154.277 + module = PythonUtils.getModuleName(file);
154.278 + //PythonTree root = PythonAstUtils.getRoot(result);
154.279 + //if (root instanceof Module) {
154.280 + // Str moduleDoc = PythonAstUtils.getDocumentationNode(root);
154.281 + // if (moduleDoc != null) {
154.282 + // moduleAttributes = "d(" + moduleDoc.getCharStartIndex() + ")";
154.283 + // }
154.284 + //}
154.285 + }
154.286 +
154.287 + private IndexTask(PythonParserResult result, IndexingSupport support, String overrideUrl) {
154.288 + this(result, support);
154.289 + this.overrideUrl = overrideUrl;
154.290 + }
154.291 +
154.292 + public List<IndexDocument> scan() {
154.293 + url = file.toURL().toExternalForm();
154.294 + // Make relative URLs for urls in the libraries
154.295 + url = PythonIndex.getPreindexUrl(url);
154.296 +
154.297 + IndexDocument doc = createDocument();
154.298 + doc.addPair(FIELD_MODULE_NAME, module, true, true);
154.299 +
154.300 + String moduleAttrs = null;
154.301 + if (url.startsWith(PythonIndex.CLUSTER_URL) || url.startsWith(PythonIndex.PYTHONHOME_URL)) {
154.302 + moduleAttrs = "S"; // NOI18N
154.303 + } else if (PREINDEXING) {
154.304 + String prj = System.getProperty("gsf.preindexing.projectpath");
154.305 + if (prj != null && !url.contains(prj)) {
154.306 + System.err.println("WARNING -- not marking url " + url + " from " + file + " as a system library!");
154.307 + }
154.308 + }
154.309 + if (DeprecationQuery.isDeprecatedModule(module)) {
154.310 + if (moduleAttrs == null) {
154.311 + moduleAttrs = "D"; // NOI18N
154.312 + } else {
154.313 + moduleAttrs += "D"; // NOI18N
154.314 + }
154.315 + }
154.316 + if (moduleAttrs != null) {
154.317 + doc.addPair(FIELD_MODULE_ATTR_NAME, moduleAttrs, false, true);
154.318 + }
154.319 +
154.320 + PythonTree root = PythonAstUtils.getRoot(result);
154.321 + if (root == null) {
154.322 + return documents;
154.323 + }
154.324 + if (!(root instanceof Module)) {
154.325 + // Unexpected... http://netbeans.org/bugzilla/show_bug.cgi?id=165756
154.326 + // Maybe some kind of top level error node?
154.327 + System.err.println("WARNING - top level AST node type was " + root + " of type " + root.getClass().getName());
154.328 + return documents;
154.329 + }
154.330 + symbolTable = result.getSymbolTable();
154.331 + ScopeInfo scopeInfo = symbolTable.getScopeInfo(root);
154.332 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
154.333 + String name = entry.getKey();
154.334 + SymInfo sym = entry.getValue();
154.335 +
154.336 + if (sym.isClass()) {
154.337 + StringBuilder sig = new StringBuilder();
154.338 + sig.append(name);
154.339 + appendFlags(sig, 'C', sym, 0);
154.340 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
154.341 +
154.342 + if (sym.node instanceof ClassDef) {
154.343 + assert sym.node instanceof ClassDef : sym.node;
154.344 + indexClass(name, sym, (ClassDef)sym.node);
154.345 + } else {
154.346 + // Could be a symbol defined both as a class and a function
154.347 + // (conditionally) such as _Environ in minicompat.py,
154.348 + // and another trigger in socket.py.
154.349 + }
154.350 + } else if (sym.isFunction()) {
154.351 + if (sym.node instanceof Name) {
154.352 + assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
154.353 + }
154.354 + assert sym.node instanceof FunctionDef : sym.node;
154.355 + FunctionDef def = (FunctionDef)sym.node;
154.356 + String sig = computeFunctionSig(name, def, sym);
154.357 + doc.addPair(FIELD_ITEM, sig, true, true);
154.358 + } else if (sym.isImported()) {
154.359 + if (!"*".equals(name)) { // NOI18N
154.360 + StringBuilder sig = new StringBuilder();
154.361 + sig.append(name);
154.362 + appendFlags(sig, 'I', sym, 0);
154.363 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
154.364 + }
154.365 + } else if (sym.isGeneratorExp()) {
154.366 + StringBuilder sig = new StringBuilder();
154.367 + sig.append(name);
154.368 + appendFlags(sig, 'G', sym, 0);
154.369 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
154.370 + } else if (sym.isData()) {
154.371 + StringBuilder sig = new StringBuilder();
154.372 + sig.append(name);
154.373 + appendFlags(sig, 'D', sym, 0);
154.374 + doc.addPair(FIELD_ITEM, sig.toString(), true, true);
154.375 + } else {
154.376 + // XXX what the heck is this??
154.377 + }
154.378 + }
154.379 +
154.380 + return documents;
154.381 + }
154.382 +
154.383 + private void indexClass(String className, SymInfo classSym, ClassDef clz) {
154.384 + IndexDocument classDocument = createDocument();
154.385 + classDocument.addPair(FIELD_IN, module, true, true);
154.386 +
154.387 + // Superclass
154.388 + List<expr> bases = clz.getInternalBases();
154.389 + if (bases != null) {
154.390 + for (expr base : bases) {
154.391 + String extendsName = PythonAstUtils.getExprName(base);
154.392 + if (extendsName != null) {
154.393 + classDocument.addPair(FIELD_EXTENDS_NAME, extendsName, true, true);
154.394 + }
154.395 + }
154.396 + }
154.397 +
154.398 + classDocument.addPair(FIELD_CLASS_NAME, className, true, true);
154.399 +
154.400 + if (classSym.isPrivate()) {
154.401 + // TODO - store Documented, Deprecated, DocOnly, etc.
154.402 + classDocument.addPair(FIELD_CLASS_ATTR_NAME, IndexedElement.encode(IndexedElement.PRIVATE), false, true);
154.403 + }
154.404 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, className.toLowerCase(), true, true);
154.405 +
154.406 + //Str doc = PythonAstUtils.getDocumentationNode(clz);
154.407 + //if (doc != null) {
154.408 + // StringBuilder sb = new StringBuilder();
154.409 + // sb.append("d("); // NOI18N
154.410 + // sb.append(doc.getCharStartIndex());
154.411 + // sb.append(")"); // NOI18N
154.412 + // classDocument.addPair(FIELD_CLASS_ATTRS, sb.toString(), false);
154.413 + //}
154.414 +
154.415 + ScopeInfo scopeInfo = symbolTable.getScopeInfo(clz);
154.416 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
154.417 + String name = entry.getKey();
154.418 + SymInfo sym = entry.getValue();
154.419 +
154.420 +// int flags = sym.flags;
154.421 +// assert !sym.isClass() : "found a class " + name + " of type " + sym.dumpFlags(scopeInfo) + " within class " + className + " in module " + module;
154.422 +// if (!(sym.isFunction() || sym.isMember() || sym.isData())) {
154.423 +// }
154.424 +// assert sym.isFunction() || sym.isMember() || sym.isData() : name + ";" + sym.toString();
154.425 +
154.426 + if (sym.isClass()) {
154.427 + // Triggers in httplib _socket_close inside FakeSocket
154.428 + StringBuilder sig = new StringBuilder();
154.429 + sig.append(name);
154.430 + appendFlags(sig, 'C', sym, 0);
154.431 + classDocument.addPair(FIELD_ITEM, sig.toString(), true, true);
154.432 +
154.433 + } else if (sym.isFunction() && sym.node instanceof FunctionDef) {
154.434 + if (sym.node instanceof Name) {
154.435 + assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
154.436 + }
154.437 + FunctionDef def = (FunctionDef)sym.node;
154.438 + String sig = computeFunctionSig(name, def, sym);
154.439 + classDocument.addPair(FIELD_MEMBER, sig, true, true);
154.440 + } else if (sym.isData()) {
154.441 + StringBuilder sig = new StringBuilder();
154.442 + sig.append(name);
154.443 + appendFlags(sig, 'D', sym, 0);
154.444 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
154.445 + } else if (sym.isMember()) {
154.446 + StringBuilder sig = new StringBuilder();
154.447 + sig.append(name);
154.448 + appendFlags(sig, 'A', sym, 0);
154.449 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
154.450 + } else if (!sym.isBound()) {
154.451 + continue;
154.452 + } else {
154.453 + // XXX what the heck is this??
154.454 + assert false : className + "::" + name + " : " + sym.dumpFlags(scopeInfo);
154.455 + }
154.456 + }
154.457 +
154.458 + if (scopeInfo.attributes.size() > 0) {
154.459 + for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
154.460 + String name = entry.getKey();
154.461 + SymInfo sym = entry.getValue();
154.462 +
154.463 + if (sym.isClass()) {
154.464 + // Triggers in httplib _socket_close inside FakeSocket
154.465 + StringBuilder sig = new StringBuilder();
154.466 + sig.append(name);
154.467 + appendFlags(sig, 'C', sym, 0);
154.468 + classDocument.addPair(FIELD_ITEM, sig.toString(), true, true);
154.469 +
154.470 + } else if (sym.isFunction() && sym.node instanceof FunctionDef) {
154.471 + if (sym.node instanceof Name) {
154.472 + assert false : "Unexpected non-function node, " + ((Name)sym.node).getInternalId() + " - from symbol " + name + " in " + file + " with sym=" + sym;
154.473 + }
154.474 + FunctionDef def = (FunctionDef)sym.node;
154.475 + String sig = computeFunctionSig(name, def, sym);
154.476 + classDocument.addPair(FIELD_MEMBER, sig, true, true);
154.477 + } else if (sym.isData()) {
154.478 + StringBuilder sig = new StringBuilder();
154.479 + sig.append(name);
154.480 + appendFlags(sig, 'D', sym, 0);
154.481 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
154.482 + } else if (sym.isMember()) {
154.483 + StringBuilder sig = new StringBuilder();
154.484 + sig.append(name);
154.485 + appendFlags(sig, 'A', sym, 0);
154.486 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true, true);
154.487 + } else if (!sym.isBound()) {
154.488 + continue;
154.489 + } else {
154.490 + // XXX what the heck is this??
154.491 + assert false : className + "::" + name + " : " + sym.dumpFlags(scopeInfo);
154.492 + }
154.493 + }
154.494 + }
154.495 + }
154.496 +
154.497 +
154.498 +// TODO - what about nested functions?
154.499 + private IndexDocument createDocument() {
154.500 + IndexDocument doc = support.createDocument(file);
154.501 + documents.add(doc);
154.502 +
154.503 + return doc;
154.504 + }
154.505 + }
154.506 +
154.507 + public static String computeClassSig(ClassDef def, SymInfo sym) {
154.508 + StringBuilder sig = new StringBuilder();
154.509 + sig.append(def.getInternalName());
154.510 + appendFlags(sig, 'C', sym, 0);
154.511 +
154.512 + return sig.toString();
154.513 + }
154.514 +
154.515 + public static String computeFunctionSig(String name, FunctionDef def, SymInfo sym) {
154.516 + StringBuilder sb = new StringBuilder();
154.517 + sb.append(name);
154.518 + char type;
154.519 + int flags = 0;
154.520 + if ("__init__".equals(name)) { // NOI18N
154.521 + type = 'c';
154.522 + } else {
154.523 + type = 'F';
154.524 +
154.525 + List<expr> decorators = def.getInternalDecorator_list();
154.526 + if (decorators != null && decorators.size() > 0) {
154.527 + for (expr decorator : decorators) {
154.528 + String decoratorName = PythonAstUtils.getExprName(decorator);
154.529 + if ("property".equals(decoratorName)) { // NOI18N
154.530 + type = 'A';
154.531 + } else if ("classmethod".equals(decoratorName)) { // NOI18N
154.532 + // Classmethods seem to be used mostly for constructors/inherited factories
154.533 + type = 'c';
154.534 + flags |= IndexedElement.CONSTRUCTOR | IndexedElement.STATIC;
154.535 + } else if ("staticmethod".equals(decoratorName)) { // NOI18N
154.536 + flags |= IndexedElement.STATIC;
154.537 + }
154.538 + }
154.539 + }
154.540 + }
154.541 + appendFlags(sb, type, sym, flags);
154.542 +
154.543 + List<String> params = PythonAstUtils.getParameters(def);
154.544 + boolean first = true;
154.545 + for (String param : params) {
154.546 + if (first) {
154.547 + first = false;
154.548 + } else {
154.549 + sb.append(',');
154.550 + }
154.551 + sb.append(param);
154.552 + }
154.553 + sb.append(';');
154.554 + String sig = sb.toString();
154.555 + return sig;
154.556 + }
154.557 +
154.558 + private String cleanupSignature(String signature) {
154.559 + // Clean up signatures - remove [optional] areas, deal
154.560 + // with arg=Default.Value parameters,
154.561 + // or "literal" or (lit,er,al) default values.
154.562 + // See unit tests for details.
154.563 + boolean lastWasComma = false;
154.564 + StringBuilder sb = new StringBuilder();
154.565 + Loop:
154.566 + for (int i = 0, n = signature.length(); i < n; i++) {
154.567 + char c = signature.charAt(i);
154.568 + switch (c) {
154.569 + case ' ':
154.570 + case '[':
154.571 + case ']':
154.572 + case '\'':
154.573 + case '"':
154.574 + case '.':
154.575 + continue Loop;
154.576 + case '=': {
154.577 + int level = 0;
154.578 + for (i++; i < n; i++) {
154.579 + c = signature.charAt(i);
154.580 + if (c == '(') {
154.581 + level++;
154.582 + } else if (c == ')') {
154.583 + if (level == 0) {
154.584 + break;
154.585 + }
154.586 + level--;
154.587 + }
154.588 + if (c == ',' && level == 0) {
154.589 + break;
154.590 + }
154.591 + }
154.592 + i--; // compensate for loop-increment
154.593 + continue Loop;
154.594 + }
154.595 + case ')':
154.596 + if (lastWasComma) {
154.597 + sb.setLength(sb.length() - 1);
154.598 + lastWasComma = false;
154.599 + }
154.600 + break;
154.601 + case ',':
154.602 + if (lastWasComma) {
154.603 + continue Loop;
154.604 + }
154.605 + lastWasComma = true;
154.606 + break;
154.607 + default:
154.608 + lastWasComma = false;
154.609 + }
154.610 + sb.append(c);
154.611 + }
154.612 +
154.613 + return sb.toString();
154.614 + }
154.615 +
154.616 + /**
154.617 + * Determine if the definition beginning on lines[lineno] is deprecated.
154.618 + */
154.619 + private boolean isDeprecated(String[] lines, int lineno) {
154.620 + int firstIndent = RstFormatter.getIndentation(lines[lineno], 0);
154.621 + for (int i = lineno + 1; i < lines.length; i++) {
154.622 + String line = lines[i];
154.623 + int indent = RstFormatter.getIndentation(line, 0);
154.624 + if (indent == -1) { // empty line
154.625 + continue;
154.626 + }
154.627 + if (line.contains(":deprecated:") || line.contains(".. deprecated::")) { // NOI18N
154.628 + return true;
154.629 + }
154.630 + // Note - we checked for ::deprecated BEFORE bailing on the next
154.631 + // same-indent line, because in some cases, these appear on the same
154.632 + // level as the deprecated element (for exampe, modules)
154.633 + if (indent <= firstIndent) {
154.634 + return false;
154.635 + }
154.636 +
154.637 + // For classes we can have embedded definitions of functions/data/methods --
154.638 + // a deprecated note for these should not be considered a deprecation of
154.639 + // the whole class! See the unit test for bz2.zip for example.
154.640 + if (line.startsWith(".. attribute::", indent) || // NOI18N
154.641 + line.startsWith(".. data::", indent) || // NOI18N
154.642 + line.startsWith(".. function::", indent) || // NOI18N
154.643 + line.startsWith(".. method::", indent)) { // NOI18N
154.644 + return false;
154.645 + }
154.646 + }
154.647 +
154.648 + return false;
154.649 + }
154.650 +
154.651 + private static class CachedIndexDocument {
154.652 + private List<CachedIndexDocumentEntry> entries = new ArrayList<>(DEFAULT_DOC_SIZE);
154.653 +
154.654 + private void addPair(String key, String value, boolean index) {
154.655 + entries.add(new CachedIndexDocumentEntry(key, value, index));
154.656 + }
154.657 + }
154.658 +
154.659 + private static class CachedIndexDocumentEntry {
154.660 + private String key;
154.661 + private String value;
154.662 + private boolean index;
154.663 +
154.664 + public CachedIndexDocumentEntry(String key, String value, boolean index) {
154.665 + this.key = key;
154.666 + this.value = value;
154.667 + this.index = index;
154.668 + }
154.669 + }
154.670 +
154.671 + private List<IndexDocument> scanRst(FileObject fo, Indexable indexable, IndexingSupport support, String overrideUrl) {
154.672 + List<CachedIndexDocument> documents = new ArrayList<>();
154.673 +
154.674 + List<IndexDocument> docs = new ArrayList<>();
154.675 +
154.676 + if (fo != null) {
154.677 + String module = fo.getNameExt();
154.678 + assert module.endsWith(".rst"); // NOI18N
154.679 + module = module.substring(0, module.length() - 4);
154.680 +
154.681 + // Skip files that are already in the standard Python libraries (as .py files).
154.682 + // For these, normal scanning applies
154.683 + // (I should consider checking that they are consistent with the official
154.684 + // documentation, at least during preindexing)
154.685 + if (PREINDEXING) {
154.686 + // XXX This doesn't work right for anything but the builtin Jython interpreter....
154.687 + // OTOH that's the only thing we're preindexing at this point
154.688 + FileObject lib = getLibDir();
154.689 + if (lib != null) {
154.690 + String path = module.replace('.', '/');
154.691 + FileObject py = lib.getFileObject(path); // Look for package dir
154.692 + if (py == null) {
154.693 + py = lib.getFileObject(path + ".py"); // NOI18N
154.694 + }
154.695 + if (py != null) {
154.696 + System.err.println("DELETE " + FileUtil.getFileDisplayName(fo) + " because there is a corresponding " + FileUtil.getFileDisplayName(py)); // NOI18N
154.697 + // No - it's in a zip archive now
154.698 + //try {
154.699 + // // Delete it!
154.700 + // fo.delete();
154.701 + //} catch (IOException ex) {
154.702 + // Exceptions.printStackTrace(ex);
154.703 + //}
154.704 + return Collections.emptyList();
154.705 + }
154.706 + }
154.707 + }
154.708 +
154.709 + String name = fo.getName();
154.710 +
154.711 + // Skip some really obsolete libraries -- IRIX only etc
154.712 + if (name.equals("gl") || name.equals("cd") || // NOI18N
154.713 + name.equals("al") || name.equals("fm") ||
154.714 + name.equals("fl") || name.equals("imgfile") || // NOI18N
154.715 + name.equals("jpeg") || // NOI18N
154.716 + name.equals("sunau") || name.equals("sunaudio")) { // NOI!8N
154.717 + return Collections.emptyList();
154.718 + }
154.719 +
154.720 + Pattern PATTERN = Pattern.compile("\\s*\\.\\.\\s+(.*)::\\s*(.+)\\s*"); // NOI18N
154.721 +
154.722 + BaseDocument doc = GsfUtilities.getDocument(fo, true);
154.723 + if (doc != null) {
154.724 + Map<String, CachedIndexDocument> classDocs = new HashMap<>();
154.725 + CachedIndexDocument document = null;
154.726 + try {
154.727 + String text = doc.getText(0, doc.getLength());
154.728 + String[] lines = text.split("\n");
154.729 + String currentClass = null;
154.730 +
154.731 + for (int lineno = 0, maxLines = lines.length; lineno < maxLines; lineno++) {
154.732 + String line = lines[lineno];
154.733 + if (!line.startsWith(".. ") && !line.contains(" .. ")) { // NOI18N
154.734 + continue;
154.735 + }
154.736 +
154.737 + Matcher m = PATTERN.matcher(line);
154.738 + if (m.matches()) {
154.739 + String key = m.group(1);
154.740 +
154.741 + if (key.equals("attribute") || // NOI18N
154.742 + key.equals("currentmodule") || // NOI18N
154.743 + key.equals("class") || // NOI18N
154.744 + key.equals("exception") || // NOI18N
154.745 + key.equals("function") || // NOI18N
154.746 + key.equals("method") || // NOI18N
154.747 + key.equals("data") || // NOI18N
154.748 + key.equals("module")) { // NOI18N
154.749 +
154.750 +
154.751 + if (key.equals("module") || key.equals("currentmodule")) { // NOI18N
154.752 + // TODO - determine package name
154.753 + module = m.group(2);
154.754 + document = new CachedIndexDocument();
154.755 + documents.add(document);
154.756 + document.addPair(FIELD_MODULE_NAME, module, true);
154.757 + String moduleAttrs = "S";
154.758 + if (isDeprecated(lines, lineno)) {
154.759 + moduleAttrs = "SD";
154.760 + }
154.761 + document.addPair(FIELD_MODULE_ATTR_NAME, moduleAttrs, false); // NOI18N
154.762 + } else {
154.763 + // Methods described in an rst without an actual module definition...
154.764 + if (document == null) {
154.765 + document = new CachedIndexDocument();
154.766 + documents.add(document);
154.767 + document.addPair(FIELD_MODULE_NAME, module, true);
154.768 + document.addPair(FIELD_MODULE_ATTR_NAME, "S", false); // NOI18N
154.769 + }
154.770 + if (key.equals("method") || key.equals("attribute")) { // NOI18N) { // NOI18N
154.771 + String signature = m.group(2);
154.772 +
154.773 + if ("string.template".equals(signature)) { // NOI18N
154.774 + // Wrong - ignore this one (ends up on the String class)
154.775 + continue;
154.776 + }
154.777 + if (signature.startsWith("somenamedtuple.")) {
154.778 + // Ditto
154.779 + continue;
154.780 + }
154.781 + // Error in mailbox.rst - Python 2.6
154.782 + if (".et_folder(folder)".equals(signature)) {
154.783 + signature = "get_folder(folder)";
154.784 + }
154.785 +
154.786 + int dot = signature.indexOf('.');
154.787 + if (dot != -1) {
154.788 + int paren = signature.indexOf('(');
154.789 + if (paren == -1 || paren > dot) {
154.790 + assert signature.matches("\\w+\\.\\w+.*") : signature;
154.791 + String dottedName = signature.substring(0, dot);
154.792 + CachedIndexDocument dottedDoc = classDocs.get(dottedName);
154.793 + if (dottedDoc != null) {
154.794 + currentClass = dottedName;
154.795 + } else /*if (currentClass == null)*/ {
154.796 + currentClass = dottedName;
154.797 + // New class without class:: declaration first.
154.798 + CachedIndexDocument classDocument = new CachedIndexDocument();
154.799 + documents.add(classDocument);
154.800 + classDocs.put(currentClass, classDocument);
154.801 + classDocument.addPair(FIELD_IN, module, true);
154.802 +
154.803 + classDocument.addPair(FIELD_CLASS_NAME, currentClass, true);
154.804 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, currentClass.toLowerCase(), true);
154.805 + }
154.806 + signature = signature.substring(dot + 1);
154.807 + }
154.808 + }
154.809 +
154.810 +
154.811 + CachedIndexDocument classDocument = classDocs.get(currentClass);
154.812 + assert classDocs != null;
154.813 +
154.814 + if (key.equals("method")) {
154.815 + signature = cleanupSignature(signature);
154.816 + if (signature.indexOf('(') == -1) {
154.817 + signature = signature + "()";
154.818 + }
154.819 +
154.820 + assert signature.indexOf('(') != -1 && signature.indexOf(')') != -1 &&
154.821 + signature.indexOf(')') > signature.indexOf('(') : signature;
154.822 + int lparen = signature.indexOf('(');
154.823 + int rparen = signature.indexOf(')', lparen + 1);
154.824 + if (lparen != -1 && rparen != -1) {
154.825 + String methodName = signature.substring(0, lparen);
154.826 + String args = signature.substring(lparen + 1, rparen);
154.827 + char type;
154.828 + if (methodName.equals("__init__")) { // NOI18N
154.829 + type = 'c';
154.830 + } else {
154.831 + type = 'F';
154.832 + }
154.833 + StringBuilder sig = new StringBuilder();
154.834 + sig.append(methodName);
154.835 +
154.836 + int symFlags = 0;
154.837 + if (NameStyle.isPrivateName(methodName)) {
154.838 + symFlags |= ScopeConstants.PRIVATE;
154.839 + }
154.840 + // TODO - look up deprecated etc.
154.841 + SymInfo fakeSym = new SymInfo(symFlags);
154.842 +
154.843 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
154.844 + if (isDeprecated(lines, lineno)) {
154.845 + flags |= IndexedElement.DEPRECATED;
154.846 + }
154.847 +
154.848 + appendFlags(sig, type, fakeSym, flags);
154.849 + sig.append(args);
154.850 + sig.append(';');
154.851 +
154.852 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
154.853 + }
154.854 + } else {
154.855 + assert key.equals("attribute");
154.856 +
154.857 + StringBuilder sig = new StringBuilder();
154.858 + sig.append(signature);
154.859 + int symFlags = 0;
154.860 + if (NameStyle.isPrivateName(signature)) {
154.861 + symFlags |= ScopeConstants.PRIVATE;
154.862 + }
154.863 + // TODO - look up deprecated etc.
154.864 + SymInfo fakeSym = new SymInfo(symFlags);
154.865 +
154.866 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
154.867 + if (isDeprecated(lines, lineno)) {
154.868 + flags |= IndexedElement.DEPRECATED;
154.869 + }
154.870 +
154.871 +
154.872 + appendFlags(sig, 'A', fakeSym, flags);
154.873 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
154.874 + }
154.875 + } else if (key.equals("class") || key.equals("exception")) { // NOI18N
154.876 + assert module != null;
154.877 + String cls = m.group(2);
154.878 +
154.879 + int paren = cls.indexOf('(');
154.880 + String constructor = null;
154.881 + if (paren != -1) {
154.882 + // Some documents specify a constructor here
154.883 + constructor = cleanupSignature(cls);
154.884 + cls = cls.substring(0, paren);
154.885 + }
154.886 + currentClass = cls;
154.887 +
154.888 + CachedIndexDocument classDocument = new CachedIndexDocument();
154.889 + classDocs.put(currentClass, classDocument);
154.890 + documents.add(classDocument);
154.891 + classDocument.addPair(FIELD_IN, module, true);
154.892 +
154.893 + if (key.equals("exception") && !"Exception".equals(cls)) { // NOI18N
154.894 + classDocument.addPair(FIELD_EXTENDS_NAME, "Exception", true); // NOI18N
154.895 + }
154.896 +
154.897 + classDocument.addPair(FIELD_CLASS_NAME, cls, true);
154.898 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY | IndexedElement.CONSTRUCTOR;
154.899 + if (isDeprecated(lines, lineno)) {
154.900 + flags |= IndexedElement.DEPRECATED;
154.901 + }
154.902 + if (flags != 0) {
154.903 + // TODO - store Documented, Deprecated, DocOnly, etc.
154.904 + classDocument.addPair(FIELD_CLASS_ATTR_NAME, IndexedElement.encode(flags), false);
154.905 + }
154.906 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, cls.toLowerCase(), true);
154.907 +
154.908 + // TODO - determine extends
154.909 + //document.addPair(FIELD_EXTENDS_NAME, superClass, true);
154.910 +
154.911 + if (constructor != null) {
154.912 + assert constructor.indexOf('(') != -1 && constructor.indexOf(')') != -1 &&
154.913 + constructor.indexOf(')') > constructor.indexOf('(') : constructor;
154.914 +
154.915 + String signature = constructor;
154.916 + int lparen = signature.indexOf('(');
154.917 + int rparen = signature.indexOf(')', lparen + 1);
154.918 + if (lparen != -1 && rparen != -1) {
154.919 + //String methodName = signature.substring(0, lparen);
154.920 + String methodName = "__init__"; // The constructor is always __init__ !
154.921 + String args = signature.substring(lparen + 1, rparen);
154.922 + StringBuilder sig = new StringBuilder();
154.923 + sig.append(methodName);
154.924 + int symFlags = 0;
154.925 + if (NameStyle.isPrivateName(methodName)) {
154.926 + symFlags |= ScopeConstants.PRIVATE;
154.927 + }
154.928 + // TODO - look up deprecated etc.
154.929 + SymInfo fakeSym = new SymInfo(symFlags);
154.930 +
154.931 + flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY | IndexedElement.CONSTRUCTOR;
154.932 + if (isDeprecated(lines, lineno)) {
154.933 + flags |= IndexedElement.DEPRECATED;
154.934 + }
154.935 +
154.936 + appendFlags(sig, 'c', fakeSym, flags);
154.937 + sig.append(args);
154.938 + sig.append(';');
154.939 +
154.940 + classDocument.addPair(FIELD_MEMBER, sig.toString(), true);
154.941 + }
154.942 +
154.943 + }
154.944 + } else if (key.equals("function") || (key.equals("data") && m.group(2).contains("("))) { // NOI18N
154.945 + // constants.rst for example registers a data item for "quit" which is really a function
154.946 +
154.947 + String signature = m.group(2);
154.948 + indexRstFunction(signature, lines, lineno, document);
154.949 +
154.950 + // See if we have any additional lines with signatures
154.951 + for (int lookahead = lineno + 1; lookahead < maxLines; lookahead++) {
154.952 + String l = lines[lookahead];
154.953 + String trimmed = l.trim();
154.954 + if (trimmed.length() == 0 || trimmed.startsWith(":")) { // NOI18N
154.955 + break;
154.956 + }
154.957 + lineno++;
154.958 +
154.959 + indexRstFunction(trimmed, lines, lookahead, document);
154.960 + }
154.961 +
154.962 + } else if (key.equals("data")) { // NOI18N
154.963 + String data = m.group(2);
154.964 +
154.965 + StringBuilder sig = new StringBuilder();
154.966 + sig.append(data);
154.967 + int symFlags = 0;
154.968 + if (NameStyle.isPrivateName(data)) {
154.969 + symFlags |= ScopeConstants.PRIVATE;
154.970 + }
154.971 + // TODO - look up deprecated etc.
154.972 + SymInfo fakeSym = new SymInfo(symFlags);
154.973 +
154.974 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
154.975 + if (isDeprecated(lines, lineno)) {
154.976 + flags |= IndexedElement.DEPRECATED;
154.977 + }
154.978 +
154.979 + appendFlags(sig, 'D', fakeSym, flags);
154.980 +
154.981 + document.addPair(FIELD_ITEM, sig.toString(), true);
154.982 + } else {
154.983 + // TODO Handle deprecated attribute!
154.984 +
154.985 + // currentmodule::
154.986 + // deprecated::
154.987 + // doctest::
154.988 + // envvar::
154.989 + // epigraph::
154.990 + // highlight::
154.991 + // highlightlang::
154.992 + // index::
154.993 + // literalinclude::
154.994 + // moduleauthor::
154.995 + // note::
154.996 + // opcode::
154.997 + // productionlist::
154.998 + // rubric::
154.999 + // sectionauthor::
154.1000 + // seealso::
154.1001 + // testcode::
154.1002 + // testsetup::
154.1003 + // toctree::
154.1004 + // versionadded::
154.1005 + // versionchanged::
154.1006 + // warning::
154.1007 + }
154.1008 + }
154.1009 + }
154.1010 + } else if (line.startsWith(".. _bltin-file-objects:") || line.startsWith(".. _string-methods:")) { // NOI18N
154.1011 + if (currentClass != null) {
154.1012 + currentClass = null;
154.1013 + }
154.1014 + }
154.1015 + }
154.1016 +
154.1017 + for (String clz : classDocs.keySet()) {
154.1018 + StringBuilder sig = new StringBuilder();
154.1019 + sig.append(clz);
154.1020 + int symFlags = 0;
154.1021 + if (NameStyle.isPrivateName(clz)) {
154.1022 + symFlags |= ScopeConstants.PRIVATE;
154.1023 + }
154.1024 + // TODO - look up deprecated etc.
154.1025 + SymInfo fakeSym = new SymInfo(symFlags);
154.1026 + appendFlags(sig, 'C', fakeSym, IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY);
154.1027 +
154.1028 + document.addPair(FIELD_ITEM, sig.toString(), true);
154.1029 + }
154.1030 +
154.1031 + } catch (BadLocationException ex) {
154.1032 + Exceptions.printStackTrace(ex);
154.1033 + }
154.1034 +
154.1035 + // Post processing: Add missing attributes not found in the .rst files
154.1036 + // but introspected using dir() in a python console
154.1037 + if (document != null) {
154.1038 + if ("operator".equals(module)) { // Fill in missing operators!
154.1039 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1040 + new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
154.1041 + document, classDocs, "int", documents, module, false, true);
154.1042 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1043 + new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
154.1044 + document, classDocs, "long", documents, module, false, true);
154.1045 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1046 + new String[] { "__abs__", "__add__", "__div__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__pos__", "__pow__", "__sub__", "__truediv__" },
154.1047 + document, classDocs, "float", documents, module, false, true);
154.1048 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1049 + new String[] { "__abs__", "__add__", "__div__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__pos__", "__pow__", "__sub__", "__truediv__" },
154.1050 + document, classDocs, "complex", documents, module, false, true);
154.1051 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1052 + new String[] { "__abs__", "__add__", "__and__", "__div__", "__floordiv__", "__index__", "__invert__", "__lshift__", "__mod__", "__mul__", "__neg__", "__or__", "__pos__", "__pow__", "__rshift__", "__sub__", "__truediv__", "__xor__" },
154.1053 + document, classDocs, "bool", documents, module, false, true);
154.1054 +
154.1055 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1056 + new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "index" },
154.1057 + document, classDocs, "str", documents, module, false, true);
154.1058 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1059 + new String[] { "__add__", "__contains__", "__delitem__", "__delslice__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__iadd__", "__imul__", "__le__", "__lt__", "__mul__", "__ne__", "__setitem__", "__setslice__", "index" },
154.1060 + document, classDocs, "list", documents, module, false, true);
154.1061 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1062 + new String[] { "__contains__", "__delitem__", "__eq__", "__ge__", "__getitem__", "__gt__", "__le__", "__lt__", "__ne__", "__setitem__" },
154.1063 + document, classDocs, "dict", documents, module, false, true);
154.1064 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1065 + new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mul__", "__ne__", "index" },
154.1066 + document, classDocs, "tuple", documents, module, false, true);
154.1067 + addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1068 + new String[] { "__add__", "__contains__", "__eq__", "__ge__", "__getitem__", "__getslice__", "__gt__", "__le__", "__lt__", "__mod__", "__mul__", "__ne__", "index" },
154.1069 + document, classDocs, "unicode", documents, module, false, true);
154.1070 +// } else if ("stdtypes".equals(module)) {
154.1071 +// // Found no definitions for these puppies
154.1072 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1074 +// document, classDocs, "int", documents, module, true, false);
154.1075 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1077 +// document, classDocs, "long", documents, module, true, false);
154.1078 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1080 +// document, classDocs, "float", documents, module, true, false);
154.1081 +//
154.1082 +//
154.1083 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1085 +// document, classDocs, "complex", documents, module, true, false);
154.1086 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1088 +// document, classDocs, "bool", documents, module, true, false);
154.1089 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1091 +// document, classDocs, "str", documents, module, true, false);
154.1092 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1094 +// document, classDocs, "list", documents, module, true, false);
154.1095 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1096 +// new String[] { "__class__", "__cmp__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__hash__", "__iter__", "__len__", "__new__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__" },
154.1097 +// document, classDocs, "dict", documents, module, true, false);
154.1098 +//
154.1099 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.1100 +// new String[] { "__class__", "__delattr__", "__doc__", "__format__", "__getattribute__", "__getnewargs__", "__hash__", "__init__", "__iter__", "__len__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__rmul__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "count" },
154.1101 +// document, classDocs, "tuple", documents, module, true, false);
154.1102 +// addMissing(PythonIndexer.FIELD_ITEM, PythonIndexer.FIELD_MEMBER,
154.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" },
154.1104 +// document, classDocs, "unicode", documents, module, true, false);
154.1105 +//
154.1106 + }
154.1107 + }
154.1108 +
154.1109 + // And convert to a proper GSF search document. I didn't do this directly
154.1110 + // because I want to modify the documents after adding documents and pairs.
154.1111 + for (CachedIndexDocument cid : documents) {
154.1112 + List<CachedIndexDocumentEntry> entries = cid.entries;
154.1113 + IndexDocument indexedDoc = support.createDocument(indexable);
154.1114 +// IndexDocument indexedDoc = support.createDocument(entries.size(), overrideUrl);
154.1115 + docs.add(indexedDoc);
154.1116 + for (CachedIndexDocumentEntry entry : entries) {
154.1117 + indexedDoc.addPair(entry.key, entry.value, true, true); // XXX indexable and stored ???
154.1118 + }
154.1119 + }
154.1120 + }
154.1121 + }
154.1122 +
154.1123 + return docs;
154.1124 + }
154.1125 +
154.1126 + /** Add the given list of names, found in the given document with a given key, and add it
154.1127 + * to the specified class (possibly found in the classDocs list - if not, add one to the
154.1128 + * documents list)
154.1129 + */
154.1130 + private void addMissing(String key, String newKey, String[] names, CachedIndexDocument doc,
154.1131 + Map<String, CachedIndexDocument> classDocs, String clz, List<CachedIndexDocument> documents, String module,
154.1132 + boolean addUnknown, boolean search) {
154.1133 +
154.1134 + CachedIndexDocument classDocument = classDocs.get(clz);
154.1135 + if (classDocument == null) {
154.1136 + // New class without class:: declaration first.
154.1137 + classDocument = new CachedIndexDocument();
154.1138 + documents.add(classDocument);
154.1139 + classDocs.put(clz, classDocument);
154.1140 + classDocument.addPair(FIELD_IN, module, true);
154.1141 +
154.1142 + classDocument.addPair(FIELD_CLASS_NAME, clz, true);
154.1143 + classDocument.addPair(FIELD_CASE_INSENSITIVE_CLASS_NAME, clz.toLowerCase(), true);
154.1144 + }
154.1145 +
154.1146 + assert classDocument != doc;
154.1147 +
154.1148 + List<String> namesFound = new ArrayList<>();
154.1149 + List<String> namesMissing = new ArrayList<>();
154.1150 + boolean noneFound = true;
154.1151 +
154.1152 + // Look for each of the given functions
154.1153 + Search:
154.1154 + for (String name : names) {
154.1155 + boolean found = false;
154.1156 + if (search) {
154.1157 + int nameLength = name.length();
154.1158 +
154.1159 + // DEBUGGING: Look to make sure I don't already have it in the class doc!
154.1160 + for (CachedIndexDocumentEntry entry : classDocument.entries) {
154.1161 + if (newKey.equals(entry.key)) {
154.1162 + if (entry.value.startsWith(name) &&
154.1163 + (entry.value.length() <= nameLength || entry.value.charAt(nameLength) == ';')) {
154.1164 + // Uh oh - what do I do here?
154.1165 + System.err.println("WARNING: I already have a definition for name " + name + " in class " + clz);
154.1166 + continue Search;
154.1167 + }
154.1168 + }
154.1169 + }
154.1170 +
154.1171 + for (CachedIndexDocumentEntry entry : doc.entries) {
154.1172 + if (key.equals(entry.key)) {
154.1173 + if (entry.value.startsWith(name) &&
154.1174 + (entry.value.length() <= nameLength || entry.value.charAt(nameLength) == ';')) {
154.1175 + // Found it!
154.1176 + classDocument.addPair(newKey, entry.value, entry.index);
154.1177 + found = true;
154.1178 + namesFound.add(name);
154.1179 + break;
154.1180 + }
154.1181 + }
154.1182 + }
154.1183 + }
154.1184 +
154.1185 + if (!found) {
154.1186 + if (addUnknown) {
154.1187 + // TODO - see if I can find a way to extract the signature too!
154.1188 + String args = "";
154.1189 + String signature = name + "()"; //
154.1190 +
154.1191 + assert signature.indexOf('(') != -1 && signature.indexOf(')') != -1 &&
154.1192 + signature.indexOf(')') > signature.indexOf('(') : signature;
154.1193 + char type;
154.1194 + if (name.equals("__init__")) { // NOI18N
154.1195 + type = 'c';
154.1196 + } else {
154.1197 + type = 'F';
154.1198 + }
154.1199 + StringBuilder sig = new StringBuilder();
154.1200 + sig.append(name);
154.1201 +
154.1202 + int symFlags = 0;
154.1203 + if (NameStyle.isPrivateName(name)) {
154.1204 + symFlags |= ScopeConstants.PRIVATE;
154.1205 + }
154.1206 + // TODO - look up deprecated etc.
154.1207 + SymInfo fakeSym = new SymInfo(symFlags);
154.1208 +
154.1209 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
154.1210 + appendFlags(sig, type, fakeSym, flags);
154.1211 + sig.append(args);
154.1212 + sig.append(';');
154.1213 +
154.1214 + classDocument.addPair(newKey, sig.toString(), true);
154.1215 + } else {
154.1216 + namesMissing.add(name);
154.1217 + }
154.1218 + } else {
154.1219 + noneFound = false;
154.1220 + }
154.1221 + }
154.1222 +
154.1223 + if (PREINDEXING) {
154.1224 + if (namesFound.size() > 0) {
154.1225 + StringBuilder sb = new StringBuilder();
154.1226 + sb.append("FOUND for ");
154.1227 + sb.append(clz);
154.1228 + sb.append(" in ");
154.1229 + sb.append(module);
154.1230 + sb.append(": ");
154.1231 + appendList(sb, namesFound);
154.1232 + System.err.println(sb.toString());
154.1233 + }
154.1234 +
154.1235 + if (noneFound && search) {
154.1236 + System.err.println("ERROR: NONE of the passed in names for " + clz + " were found!");
154.1237 + }
154.1238 +
154.1239 + if (namesMissing.size() > 0) {
154.1240 + StringBuilder sb = new StringBuilder();
154.1241 + sb.append("WARNING: Missing these names from ");
154.1242 + sb.append(module);
154.1243 + sb.append(" for use by class ");
154.1244 + sb.append(clz);
154.1245 + sb.append(" : ");
154.1246 + appendList(sb, namesMissing);
154.1247 + System.err.println(sb.toString());
154.1248 + }
154.1249 + }
154.1250 + }
154.1251 +
154.1252 + private static void appendList(StringBuilder sb, List<String> list) {
154.1253 + sb.append("{ ");
154.1254 + boolean first = true;
154.1255 + for (String m : list) {
154.1256 + if (first) {
154.1257 + first = false;
154.1258 + } else {
154.1259 + sb.append(", ");
154.1260 + }
154.1261 + sb.append('"');
154.1262 + sb.append(m);
154.1263 + sb.append('"');
154.1264 + }
154.1265 + sb.append(" }");
154.1266 + }
154.1267 +
154.1268 + private void indexRstFunction(String signature, String[] lines, int lineno, CachedIndexDocument document) {
154.1269 + int dot = signature.indexOf('.');
154.1270 + if (dot != -1) {
154.1271 + int paren = signature.indexOf('(');
154.1272 + if (paren == -1 || paren > dot) {
154.1273 + assert signature.matches("\\w+\\.\\w+.*") : signature; // NOI18N
154.1274 + signature = signature.substring(dot + 1);
154.1275 + }
154.1276 + }
154.1277 + signature = cleanupSignature(signature);
154.1278 + if (signature.indexOf('(') == -1) {
154.1279 + signature = signature + "()"; // NOI18N
154.1280 + } else if (signature.indexOf(')') == -1) {
154.1281 + //signature = signature + ")";
154.1282 + assert signature.indexOf(')') != -1;
154.1283 + }
154.1284 + int lparen = signature.indexOf('(');
154.1285 + int rparen = signature.indexOf(')', lparen + 1);
154.1286 + if (lparen != -1 && rparen != -1) {
154.1287 + String methodName = signature.substring(0, lparen);
154.1288 + String args = signature.substring(lparen + 1, rparen);
154.1289 + StringBuilder sig = new StringBuilder();
154.1290 + sig.append(methodName);
154.1291 + int symFlags = 0;
154.1292 + if (NameStyle.isPrivateName(methodName)) {
154.1293 + symFlags |= ScopeConstants.PRIVATE;
154.1294 + }
154.1295 + // TODO - look up deprecated etc.
154.1296 + SymInfo fakeSym = new SymInfo(symFlags);
154.1297 + int flags = IndexedElement.DOCUMENTED | IndexedElement.DOC_ONLY;
154.1298 + if (isDeprecated(lines, lineno)) {
154.1299 + flags |= IndexedElement.DEPRECATED;
154.1300 + }
154.1301 + appendFlags(sig, 'F', fakeSym, flags);
154.1302 + sig.append(args);
154.1303 + sig.append(';');
154.1304 +
154.1305 + document.addPair(FIELD_ITEM, sig.toString(), true);
154.1306 + }
154.1307 + }
154.1308 +
154.1309 + private List<IndexDocument> scanEgg(FileObject fo, Indexable indexable, ParserResult result, IndexingSupport support) {
154.1310 + List<IndexDocument> documents = new ArrayList<>();
154.1311 +
154.1312 + if (fo == null) {
154.1313 + return documents;
154.1314 + }
154.1315 +
154.1316 + try {
154.1317 + String s = fo.toURL().toExternalForm() + "!"; // NOI18N
154.1318 + URL u = new URL("jar:" + s); // NOI18N
154.1319 + FileObject root = URLMapper.findFileObject(u);
154.1320 + String rootUrl = PythonIndex.getPreindexUrl(u.toExternalForm());
154.1321 + indexScriptDocRecursively(support, documents, root, rootUrl);
154.1322 + } catch (MalformedURLException ex) {
154.1323 + Exceptions.printStackTrace(ex);
154.1324 + }
154.1325 +
154.1326 + return documents;
154.1327 + }
154.1328 +
154.1329 + /**
154.1330 + * Method which recursively indexes directory trees, such as the yui/ folder
154.1331 + * for example
154.1332 + */
154.1333 + private void indexScriptDocRecursively(IndexingSupport support, List<IndexDocument> documents, final FileObject fo, String url) {
154.1334 + if (fo.isFolder()) {
154.1335 + for (FileObject c : fo.getChildren()) {
154.1336 + indexScriptDocRecursively(support, documents, c, url + "/" + c.getNameExt()); // NOI18N
154.1337 + }
154.1338 + return;
154.1339 + }
154.1340 +
154.1341 + String ext = fo.getExt();
154.1342 +
154.1343 +// if ("py".equals(ext)) { // NOI18N
154.1344 +// DefaultParseListener listener = new DefaultParseListener();
154.1345 +// List<ParserFile> files = Collections.<ParserFile>singletonList(new DefaultParserFile(fo, null, false));
154.1346 +// SourceFileReader reader = new SourceFileReader() {
154.1347 +// public CharSequence read(ParserFile file) throws IOException {
154.1348 +// BaseDocument doc = GsfUtilities.getDocument(fo, true);
154.1349 +// if (doc != null) {
154.1350 +// try {
154.1351 +// return doc.getText(0, doc.getLength());
154.1352 +// } catch (BadLocationException ex) {
154.1353 +// Exceptions.printStackTrace(ex);
154.1354 +// }
154.1355 +// }
154.1356 +//
154.1357 +// return "";
154.1358 +// }
154.1359 +//
154.1360 +// public int getCaretOffset(ParserFile file) {
154.1361 +// return -1;
154.1362 +// }
154.1363 +// };
154.1364 +// Job job = new Job(files, listener, reader, null);
154.1365 +// new PythonParser().parseFiles(job);
154.1366 +// ParserResult parserResult = listener.getParserResult();
154.1367 +// if (parserResult != null && parserResult.isValid()) {
154.1368 +// documents.addAll(new IndexTask((PythonParserResult)parserResult, support, url).scan());
154.1369 +// }
154.1370 +// } else if ("rst".equals(ext)) { // NOI18N
154.1371 +// documents.addAll(scanRst(fo, support, url));
154.1372 +// }
154.1373 + }
154.1374 +
154.1375 + private FileObject getLibDir() {
154.1376 + // TODO - fetch from projects!!!!
154.1377 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
154.1378 + PythonPlatform platform = manager.getPlatform(manager.getDefaultPlatform());
154.1379 + if (platform != null) {
154.1380 + String cmd = platform.getInterpreterCommand();
154.1381 + File file = new File(cmd);
154.1382 + if (file.exists()) {
154.1383 + file = file.getAbsoluteFile();
154.1384 + File home = file.getParentFile().getParentFile();
154.1385 + if (home != null) {
154.1386 + // Look for Lib - Jython style
154.1387 + File lib = new File(home, "Lib"); // NOI18N
154.1388 + boolean exists = lib.exists();
154.1389 + if (!exists) { // Unix style
154.1390 + lib = new File(home, "lib" + File.separator + "python"); // NOI18N
154.1391 + exists = lib.exists();
154.1392 + }
154.1393 + if (exists) {
154.1394 + return FileUtil.toFileObject(lib);
154.1395 + }
154.1396 + }
154.1397 + }
154.1398 + }
154.1399 +
154.1400 + return null;
154.1401 + }
154.1402 +}
155.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
155.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonIndexerFactory.java Wed Sep 02 20:31:18 2015 +0200
155.3 @@ -0,0 +1,47 @@
155.4 +/*
155.5 + * To change this license header, choose License Headers in Project Properties.
155.6 + * To change this template file, choose Tools | Templates
155.7 + * and open the template in the editor.
155.8 + */
155.9 +package org.netbeans.modules.python.source;
155.10 +
155.11 +import org.netbeans.modules.parsing.api.Snapshot;
155.12 +import org.netbeans.modules.parsing.spi.indexing.Context;
155.13 +import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer;
155.14 +import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexerFactory;
155.15 +import org.netbeans.modules.parsing.spi.indexing.Indexable;
155.16 +
155.17 +/**
155.18 + *
155.19 + * @author Ralph Benjamin Ruijs
155.20 + */
155.21 +public class PythonIndexerFactory extends EmbeddingIndexerFactory {
155.22 +
155.23 + @Override
155.24 + public EmbeddingIndexer createIndexer(Indexable indexable, Snapshot snapshot) {
155.25 + if(PythonIndexer.isIndexable(indexable, snapshot)) {
155.26 + return new PythonIndexer();
155.27 + }
155.28 + return null;
155.29 + }
155.30 +
155.31 + @Override
155.32 + public void filesDeleted(Iterable<? extends Indexable> indexables, Context context) {
155.33 +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
155.34 + }
155.35 +
155.36 + @Override
155.37 + public void filesDirty(Iterable<? extends Indexable> arg0, Context arg1) {
155.38 +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
155.39 + }
155.40 +
155.41 + @Override
155.42 + public String getIndexerName() {
155.43 + return PythonIndexer.NAME;
155.44 + }
155.45 +
155.46 + @Override
155.47 + public int getIndexVersion() {
155.48 + return PythonIndexer.VERSION;
155.49 + }
155.50 +}
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
156.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonParser.java Wed Sep 02 20:31:18 2015 +0200
156.3 @@ -0,0 +1,760 @@
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.io.InputStream;
156.37 +import java.io.InputStreamReader;
156.38 +import java.util.ArrayList;
156.39 +import java.util.List;
156.40 +import java.util.logging.Level;
156.41 +import java.util.logging.Logger;
156.42 +import javax.swing.event.ChangeListener;
156.43 +import javax.swing.text.BadLocationException;
156.44 +import org.netbeans.modules.csl.api.Severity;
156.45 +import org.netbeans.modules.csl.spi.DefaultError;
156.46 +import org.netbeans.modules.csl.api.Error;
156.47 +import org.netbeans.modules.csl.api.OffsetRange;
156.48 +import org.netbeans.modules.csl.spi.GsfUtilities;
156.49 +import org.netbeans.modules.parsing.api.Snapshot;
156.50 +import org.netbeans.modules.parsing.api.Task;
156.51 +import org.netbeans.modules.parsing.spi.Parser;
156.52 +import org.netbeans.modules.parsing.spi.SourceModificationEvent;
156.53 +import org.netbeans.modules.python.api.PythonFileEncodingQuery;
156.54 +import org.openide.filesystems.FileObject;
156.55 +import org.python.antlr.runtime.ANTLRStringStream;
156.56 +import org.python.antlr.runtime.BaseRecognizer;
156.57 +import org.python.antlr.runtime.BitSet;
156.58 +import org.python.antlr.runtime.CommonToken;
156.59 +import org.python.antlr.runtime.CommonTokenStream;
156.60 +import org.python.antlr.runtime.IntStream;
156.61 +import org.python.antlr.runtime.Lexer;
156.62 +import org.python.antlr.runtime.MismatchedTokenException;
156.63 +import org.python.antlr.runtime.RecognitionException;
156.64 +
156.65 +import org.openide.filesystems.FileUtil;
156.66 +import org.openide.util.Exceptions;
156.67 +import org.python.antlr.ListErrorHandler;
156.68 +import org.python.antlr.ParseException;
156.69 +import org.python.antlr.PythonLexer;
156.70 +import org.python.antlr.PythonTokenSource;
156.71 +import org.python.antlr.PythonTree;
156.72 +import org.python.antlr.PythonTreeAdaptor;
156.73 +import org.python.antlr.base.expr;
156.74 +import org.python.antlr.base.mod;
156.75 +import org.python.antlr.base.slice;
156.76 +import org.python.antlr.base.stmt;
156.77 +import org.python.antlr.runtime.ANTLRReaderStream;
156.78 +import org.python.antlr.runtime.CharStream;
156.79 +
156.80 +/**
156.81 + * Parser for Python. Wraps Jython.
156.82 + *
156.83 + * @author Frank Wierzbicki
156.84 + * @author Tor Norbye
156.85 + */
156.86 +public class PythonParser extends Parser {
156.87 + /** For unit tests such that they can make sure we didn't have a parser abort */
156.88 + static Throwable runtimeException;
156.89 +
156.90 + static {
156.91 + org.python.core.PySystemState.initialize();
156.92 + }
156.93 +
156.94 + private Result lastResult;
156.95 + private final PythonFileEncodingQuery fileEncodingQuery = new PythonFileEncodingQuery();
156.96 + private String headerCached = null;
156.97 + private String encodingCache = null;
156.98 +
156.99 + public mod file_input(CharStream charStream, String fileName) throws RecognitionException {
156.100 + ListErrorHandler eh = new ListErrorHandler();
156.101 + mod tree = null;
156.102 + PythonLexer lexer = new PythonLexer(charStream);
156.103 + lexer.setErrorHandler(eh);
156.104 + CommonTokenStream tokens = new CommonTokenStream(lexer);
156.105 + tokens.discardOffChannelTokens(true);
156.106 + PythonTokenSource indentedSource = new PythonTokenSource(tokens, fileName);
156.107 + tokens = new CommonTokenStream(indentedSource);
156.108 + org.python.antlr.PythonParser parser = new org.python.antlr.PythonParser(tokens);
156.109 + parser.setTreeAdaptor(new PythonTreeAdaptor());
156.110 + parser.setErrorHandler(eh);
156.111 + org.python.antlr.PythonParser.file_input_return r = parser.file_input();
156.112 + tree = (mod)r.getTree();
156.113 + return tree;
156.114 + }
156.115 +
156.116 + @Override
156.117 + public void addChangeListener(ChangeListener changeListener) {}
156.118 +
156.119 + @Override
156.120 + public void removeChangeListener(ChangeListener changeListener) {}
156.121 +
156.122 + public PythonTree parse(InputStream istream, String fileName) throws Exception {
156.123 + InputStreamReader reader = new InputStreamReader(istream, "ISO-8859-1");
156.124 + return file_input(new ANTLRReaderStream(reader), fileName);
156.125 + }
156.126 +
156.127 + @Override
156.128 + public final Result getResult(Task task) throws org.netbeans.modules.parsing.spi.ParseException {
156.129 + return lastResult;
156.130 + }
156.131 +
156.132 + private static final Logger LOG = Logger.getLogger(PythonParser.class.getName());
156.133 +
156.134 + @Override
156.135 + public void parse(Snapshot snapshot, Task task, SourceModificationEvent event) throws org.netbeans.modules.parsing.spi.ParseException {
156.136 + Context context = new Context();
156.137 + context.snapshot = snapshot;
156.138 + context.event = event;
156.139 + context.task = task;
156.140 + context.caretOffset = GsfUtilities.getLastKnownCaretOffset(snapshot, event);
156.141 + context.source = snapshot.getText().toString();
156.142 + context.file = snapshot.getSource().getFileObject();
156.143 + if(context.file == null) {
156.144 + return; // TODO: parse the source, not the file
156.145 + }
156.146 + /* Let's not sanitize ;-) Would be great if we could have a more robust parser
156.147 + if (context.caretOffset != -1) {
156.148 + context.sanitized = Sanitize.EDITED_DOT;
156.149 + }
156.150 + */
156.151 + lastResult = parse(context, context.sanitized);
156.152 + }
156.153 + public PythonParserResult parse(final Context context, Sanitize sanitizing) {
156.154 + boolean sanitizedSource = false;
156.155 + String sourceCode = context.source;
156.156 + if (!((sanitizing == Sanitize.NONE) || (sanitizing == Sanitize.NEVER))) {
156.157 + boolean ok = sanitizeSource(context, sanitizing);
156.158 +
156.159 + if (ok) {
156.160 + assert context.sanitizedSource != null;
156.161 + sanitizedSource = true;
156.162 + sourceCode = context.sanitizedSource;
156.163 + } else {
156.164 + // Try next trick
156.165 + return sanitize(context, sanitizing);
156.166 + }
156.167 + }
156.168 + final String source = sourceCode;
156.169 +
156.170 + if (sanitizing == Sanitize.NONE) {
156.171 + context.errorOffset = -1;
156.172 + }
156.173 +
156.174 + final List<Error> errors = new ArrayList<>();
156.175 + final FileObject file = context.file;
156.176 + try {
156.177 + String fileName = file.getNameExt();
156.178 + // TODO - sniff file headers etc. Frank's comment:
156.179 + // Longer term for Python compatibility, having NetBeans sniff the top two lines
156.180 + // for an encoding would be the right thing to do from a pure Python
156.181 + // compatibility standard (see http://www.python.org/dev/peps/pep-0263/) I
156.182 + // have pep-0263 code in Jython that I could probably extract for this
156.183 + // purpose down the road.
156.184 + //String charset = "ISO8859_1"; // NOI18N
156.185 + //String charset = "UTF-8"; // NOI18N
156.186 + //String charset = "iso8859_1"; // NOI18N
156.187 + // TODO: improve this check.
156.188 + int cache_len = sourceCode.length() >= 64 ? 64 : sourceCode.length();
156.189 + if (headerCached == null || cache_len != headerCached.length() || !headerCached.equals(sourceCode.substring(0, cache_len))) {
156.190 + headerCached = sourceCode.substring(0, cache_len);
156.191 + encodingCache = fileEncodingQuery.getPythonFileEncoding(sourceCode.split("\n", 2));
156.192 + }
156.193 + String charset = encodingCache;
156.194 +
156.195 + final boolean ignoreErrors = sanitizedSource;
156.196 + ListErrorHandler errorHandler = new ListErrorHandler() {
156.197 + @Override
156.198 + public void error(String message, PythonTree t) {
156.199 + errors.add(new DefaultError(null, message, null, file, t.getCharStartIndex(), t.getCharStopIndex(), Severity.ERROR));
156.200 + super.error(message, t);
156.201 + }
156.202 +
156.203 + @Override
156.204 + public expr errorExpr(PythonTree t) {
156.205 + return super.errorExpr(t);
156.206 + }
156.207 +
156.208 + @Override
156.209 + public mod errorMod(PythonTree t) {
156.210 + return super.errorMod(t);
156.211 + }
156.212 +
156.213 + @Override
156.214 + public slice errorSlice(PythonTree t) {
156.215 + return super.errorSlice(t);
156.216 + }
156.217 +
156.218 + @Override
156.219 + public stmt errorStmt(PythonTree t) {
156.220 + return super.errorStmt(t);
156.221 + }
156.222 +
156.223 + @Override
156.224 + public boolean mismatch(BaseRecognizer br, IntStream input, int ttype, BitSet follow) {
156.225 + return super.mismatch(br, input, ttype, follow);
156.226 + }
156.227 +
156.228 + @Override
156.229 + public Object recoverFromMismatchedToken(BaseRecognizer br, IntStream input, int ttype, BitSet follow) {
156.230 + MismatchedTokenException mt = new MismatchedTokenException(ttype, input);
156.231 + String message = br.getErrorMessage(mt, br.getTokenNames());
156.232 + if (mt.line >= 1) {
156.233 + int lineOffset = findLineOffset(context.source, mt.line-1);
156.234 + if (mt.charPositionInLine > 0) {
156.235 + lineOffset += mt.charPositionInLine;
156.236 + }
156.237 + int start = lineOffset;//t.getCharStartIndex();
156.238 + int stop = lineOffset;//t.getCharStopIndex();
156.239 + errors.add(new DefaultError(null, message, null, file, start, stop, Severity.ERROR));
156.240 + }
156.241 + return super.recoverFromMismatchedToken(br, input, ttype, follow);
156.242 + }
156.243 +
156.244 + @Override
156.245 + public void recover(Lexer lex, RecognitionException re) {
156.246 + super.recover(lex, re);
156.247 + }
156.248 +
156.249 + @Override
156.250 + public void recover(BaseRecognizer br, IntStream input, RecognitionException re) {
156.251 + super.recover(br, input, re);
156.252 + }
156.253 +
156.254 + @Override
156.255 + public void reportError(BaseRecognizer br, RecognitionException re) {
156.256 + if (!ignoreErrors) {
156.257 + String message = br.getErrorMessage(re, br.getTokenNames());
156.258 + if (message == null || message.length() == 0) {
156.259 + message = re.getMessage();
156.260 + }
156.261 + if (message == null) {
156.262 + //message = re.getUnexpectedType();
156.263 + message = re.toString();
156.264 + }
156.265 + int start = re.index;
156.266 +
156.267 + // Try to find the line offset. re.index doesn't do the trick.
156.268 + start = PythonUtils.getOffsetByLineCol(source, re.line - 1, 0); // -1: 0-based
156.269 + int end = start;
156.270 + if (re.charPositionInLine > 0) {
156.271 + try {
156.272 + end = GsfUtilities.getRowLastNonWhite(source, start) + 1;
156.273 + start += re.charPositionInLine;
156.274 + if (end < start) {
156.275 + end = start;
156.276 + }
156.277 + } catch (BadLocationException ex) {
156.278 + Exceptions.printStackTrace(ex);
156.279 + end = start;
156.280 + }
156.281 + if (end == 0) {
156.282 + end = start;
156.283 + }
156.284 + }
156.285 +
156.286 + // Some errors have better offsets if we look at the token stream
156.287 + if (re instanceof MismatchedTokenException) {
156.288 + MismatchedTokenException m = (MismatchedTokenException)re;
156.289 + if (m.token != null) {
156.290 + if (m.token instanceof org.python.antlr.runtime.CommonToken) {
156.291 + CommonToken token = (org.python.antlr.runtime.CommonToken)m.token;
156.292 + start = token.getStartIndex();
156.293 + end = token.getStopIndex();
156.294 + }
156.295 + }
156.296 + }
156.297 +
156.298 + if (start > source.length()) {
156.299 + start = source.length();
156.300 + end = start;
156.301 + }
156.302 +
156.303 + errors.add(new DefaultError(null, message, null, file, start, end, Severity.ERROR));
156.304 +
156.305 + // In order to avoid a StackOverflowError, the BaseRecognizer must be recreated.
156.306 + // We must keep the names of the tokens to avoid a NullPointerException.
156.307 + // See bz252630
156.308 + final String[] tokenNames = br.getTokenNames();
156.309 + br = new BaseRecognizer() {
156.310 +
156.311 + @Override
156.312 + public String getSourceName() {
156.313 + return file.getName();
156.314 + }
156.315 +
156.316 + @Override
156.317 + public String[] getTokenNames() {
156.318 + return tokenNames;
156.319 + }
156.320 + };
156.321 +
156.322 + super.reportError(br, re);
156.323 + }
156.324 + }
156.325 + };
156.326 +
156.327 + PythonLexer lexer = new PythonLexer(new ANTLRStringStream(sourceCode));
156.328 + lexer.setErrorHandler(errorHandler);
156.329 + CommonTokenStream tokens = new CommonTokenStream(lexer);
156.330 + tokens.discardOffChannelTokens(true);
156.331 + PythonTokenSource indentedSource = new PythonTokenSource(tokens, fileName);
156.332 + CommonTokenStream indentedTokens = new CommonTokenStream(indentedSource);
156.333 + // Import line ending with a dot raise a NullPointerException in
156.334 + // org.python.antlr.GrammarActions.makeDottedText called from parser.file_input
156.335 + // sanitizeImportTokens will remove the dot token from the list of tokens in
156.336 + // indentedTokens to avoid the bug and add an error at this file.
156.337 + // See https://netbeans.org/bugzilla/show_bug.cgi?id=252356
156.338 + sanitizeImportTokens(indentedTokens, errors, file);
156.339 + org.python.antlr.PythonParser parser;
156.340 + if (charset != null) {
156.341 + parser = new org.python.antlr.PythonParser(indentedTokens, charset);
156.342 + } else {
156.343 + parser = new org.python.antlr.PythonParser(indentedTokens);
156.344 + }
156.345 + parser.setTreeAdaptor(new PythonTreeAdaptor());
156.346 + parser.setErrorHandler(errorHandler);
156.347 + org.python.antlr.PythonParser.file_input_return r = parser.file_input();
156.348 + PythonTree t = (PythonTree)r.getTree();
156.349 + PythonParserResult result = new PythonParserResult(t, context.snapshot);
156.350 + result.setErrors(errors);
156.351 +
156.352 + result.setSanitized(context.sanitized, context.sanitizedRange, context.sanitizedContents);
156.353 + result.setSource(sourceCode);
156.354 +
156.355 + return result;
156.356 + } catch (ParseException pe) {
156.357 + if (sanitizing == Sanitize.NONE) {
156.358 + PythonParserResult sanitizedResult = sanitize(context, sanitizing);
156.359 + if (sanitizedResult.isValid()) {
156.360 + return sanitizedResult;
156.361 + } else {
156.362 + int offset = pe.index;
156.363 + assert offset >= 0;
156.364 + String desc = pe.getLocalizedMessage();
156.365 + if (desc == null) {
156.366 + desc = pe.getMessage();
156.367 + }
156.368 + DefaultError error = new DefaultError(null /*key*/, desc, null, file, offset, offset, Severity.ERROR);
156.369 + PythonParserResult parserResult = new PythonParserResult(null, context.snapshot);
156.370 + parserResult.addError(error);
156.371 + for (Error e : errors) {
156.372 + parserResult.addError(e);
156.373 + }
156.374 +
156.375 + return parserResult;
156.376 + }
156.377 + } else {
156.378 + return sanitize(context, sanitizing);
156.379 + }
156.380 + } catch (NullPointerException e) {
156.381 + String fileName = "";
156.382 + if (file != null) {
156.383 + fileName = FileUtil.getFileDisplayName(file);
156.384 + }
156.385 + e = Exceptions.attachMessage(e, "Was parsing " + fileName);
156.386 + Exceptions.printStackTrace(e);
156.387 + return new PythonParserResult(null, context.snapshot);
156.388 + } catch (Throwable t) {
156.389 + runtimeException = t;
156.390 + StackTraceElement[] stackTrace = t.getStackTrace();
156.391 + if (stackTrace != null && stackTrace.length > 0 && stackTrace[0].getClassName().startsWith("org.python.antlr")) {//.runtime.tree.RewriteRuleElementStream")) {
156.392 + // This is issue 150921
156.393 + // Don't bug user about it -- we already know
156.394 + Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Encountered issue #150921", t);
156.395 + } else {
156.396 + t = Exceptions.attachMessage(t, "Was parsing " + FileUtil.getFileDisplayName(file));
156.397 + Exceptions.printStackTrace(t);
156.398 + }
156.399 + return new PythonParserResult(null, context.snapshot);
156.400 + }
156.401 + }
156.402 +
156.403 + private void sanitizeImportTokens(CommonTokenStream indentedTokens, List errors, FileObject file) {
156.404 + List tokens = indentedTokens.getTokens();
156.405 + List<CommonToken> tokensToRemove = new ArrayList<>();
156.406 + int i = 0;
156.407 + while (i < tokens.size()) {
156.408 + CommonToken importToken = (CommonToken)tokens.get(i);
156.409 + if ("import".equals(importToken.getText()) || "from".equals(importToken.getText())) {
156.410 + // sanitizeDotTokens return the index of the token that starts the next line
156.411 + i = sanitizeDotTokens(tokens, tokensToRemove, importToken, i + 1, errors, file);
156.412 + } else {
156.413 + i++;
156.414 + }
156.415 + }
156.416 +
156.417 + for (CommonToken token : tokensToRemove) {
156.418 + tokens.remove(token);
156.419 + }
156.420 + }
156.421 +
156.422 + private int sanitizeDotTokens(List tokens, List tokensToRemove, CommonToken importToken,
156.423 + int startIndex, List errors, FileObject file) {
156.424 + for (int j = startIndex; j < tokens.size() - 1; j++) {
156.425 + CommonToken dotToken = (CommonToken)tokens.get(j);
156.426 + CommonToken nextToken = (CommonToken)tokens.get(j + 1);
156.427 + if (".".equals(dotToken.getText())) {
156.428 + if (nextToken.getText().startsWith("\n")) {
156.429 + tokensToRemove.add(dotToken);
156.430 + String rawTokenText;
156.431 + if (nextToken.getText().startsWith("\n")) {
156.432 + rawTokenText = "\\n";
156.433 + } else {
156.434 + rawTokenText = " ";
156.435 + }
156.436 + errors.add(
156.437 + new DefaultError(null, "Mismatch input '.' expecting NAME\nMissing NAME at '" + rawTokenText + "'",
156.438 + null, file, importToken.getStartIndex(), dotToken.getStopIndex(), Severity.ERROR));
156.439 + }
156.440 + } else if ("\n".equals(nextToken.getText())) { // End of line, must continue looping from external loop
156.441 + return j + 1;
156.442 + }
156.443 + }
156.444 +
156.445 + return startIndex;
156.446 + }
156.447 +
156.448 + private static String asString(CharSequence sequence) {
156.449 + if (sequence instanceof String) {
156.450 + return (String)sequence;
156.451 + } else {
156.452 + return sequence.toString();
156.453 + }
156.454 + }
156.455 +
156.456 +
156.457 + @SuppressWarnings("fallthrough")
156.458 + private PythonParserResult sanitize(final Context context, final Sanitize sanitizing) {
156.459 +
156.460 + switch (sanitizing) {
156.461 + case NEVER:
156.462 + return new PythonParserResult(null, context.snapshot);
156.463 +
156.464 + case NONE:
156.465 + if (context.caretOffset != -1) {
156.466 + return parse(context, Sanitize.EDITED_DOT);
156.467 + }
156.468 +
156.469 + case EDITED_DOT:
156.470 + // We've tried removing whitespace around the edit location
156.471 + // Fall through to try parsing with removing stuff around error location
156.472 + // (Don't bother doing this if errorOffset==caretOffset since that would try the same
156.473 + // source as EDITED_DOT which has no better chance of succeeding...)
156.474 + if (context.errorOffset != -1 && context.errorOffset != context.caretOffset) {
156.475 + return parse(context, Sanitize.ERROR_DOT);
156.476 + }
156.477 +
156.478 + // Fall through to try the next trick
156.479 + case ERROR_DOT:
156.480 +
156.481 + // We've tried removing dots - now try removing the whole line at the error position
156.482 + if (context.errorOffset != -1) {
156.483 + return parse(context, Sanitize.ERROR_LINE);
156.484 + }
156.485 +
156.486 + // Fall through to try the next trick
156.487 + case ERROR_LINE:
156.488 +
156.489 + // Messing with the error line didn't work - we could try "around" the error line
156.490 + // but I'm not attempting that now.
156.491 + // Finally try removing the whole line around the user editing position
156.492 + // (which could be far from where the error is showing up - but if you're typing
156.493 + // say a new "def" statement in a class, this will show up as an error on a mismatched
156.494 + // "end" statement rather than here
156.495 + if (context.caretOffset != -1) {
156.496 + return parse(context, Sanitize.EDITED_LINE);
156.497 + }
156.498 +
156.499 + // Fall through for default handling
156.500 + case EDITED_LINE:
156.501 + default:
156.502 + // We're out of tricks - just return the failed parse result
156.503 + return new PythonParserResult(null, context.snapshot);
156.504 + }
156.505 + }
156.506 +
156.507 + /**
156.508 + * Try cleaning up the source buffer around the current offset to increase
156.509 + * likelihood of parse success. Initially this method had a lot of
156.510 + * logic to determine whether a parse was likely to fail (e.g. invoking
156.511 + * the isEndMissing method from bracket completion etc.).
156.512 + * However, I am now trying a parse with the real source first, and then
156.513 + * only if that fails do I try parsing with sanitized source. Therefore,
156.514 + * this method has to be less conservative in ripping out code since it
156.515 + * will only be used when the regular source is failing.
156.516 + *
156.517 + * @todo Automatically close current statement by inserting ";"
156.518 + * @todo Handle sanitizing "new ^" from parse errors
156.519 + * @todo Replace "end" insertion fix with "}" insertion
156.520 + */
156.521 + private boolean sanitizeSource(Context context, Sanitize sanitizing) {
156.522 + int offset = context.caretOffset;
156.523 +
156.524 + // Let caretOffset represent the offset of the portion of the buffer we'll be operating on
156.525 + if ((sanitizing == Sanitize.ERROR_DOT) || (sanitizing == Sanitize.ERROR_LINE)) {
156.526 + offset = context.errorOffset;
156.527 + }
156.528 +
156.529 + // Don't attempt cleaning up the source if we don't have the buffer position we need
156.530 + if (offset == -1) {
156.531 + return false;
156.532 + }
156.533 +
156.534 + // The user might be editing around the given caretOffset.
156.535 + // See if it looks modified
156.536 + // Insert an end statement? Insert a } marker?
156.537 + String doc = context.source;
156.538 + if (offset > doc.length()) {
156.539 + return false;
156.540 + }
156.541 +
156.542 + try {
156.543 + // Sometimes the offset shows up on the next line
156.544 + if (GsfUtilities.isRowEmpty(doc, offset) || GsfUtilities.isRowWhite(doc, offset)) {
156.545 + offset = GsfUtilities.getRowStart(doc, offset) - 1;
156.546 + if (offset < 0) {
156.547 + offset = 0;
156.548 + }
156.549 + }
156.550 +
156.551 + if (!(GsfUtilities.isRowEmpty(doc, offset) || GsfUtilities.isRowWhite(doc, offset))) {
156.552 + if ((sanitizing == Sanitize.EDITED_LINE) || (sanitizing == Sanitize.ERROR_LINE)) {
156.553 + // See if I should try to remove the current line, since it has text on it.
156.554 + int lineEnd = GsfUtilities.getRowLastNonWhite(doc, offset);
156.555 +
156.556 + if (lineEnd != -1) {
156.557 + lineEnd++; // lineEnd is exclusive, not inclusive
156.558 + StringBuilder sb = new StringBuilder(doc.length());
156.559 + int lineStart = GsfUtilities.getRowStart(doc, offset);
156.560 + if (lineEnd >= lineStart + 2) {
156.561 + sb.append(doc.substring(0, lineStart));
156.562 + sb.append("//");
156.563 + int rest = lineStart + 2;
156.564 + if (rest < doc.length()) {
156.565 + sb.append(doc.substring(rest, doc.length()));
156.566 + }
156.567 + } else {
156.568 + // A line with just one character - can't replace with a comment
156.569 + // Just replace the char with a space
156.570 + sb.append(doc.substring(0, lineStart));
156.571 + sb.append(" ");
156.572 + int rest = lineStart + 1;
156.573 + if (rest < doc.length()) {
156.574 + sb.append(doc.substring(rest, doc.length()));
156.575 + }
156.576 +
156.577 + }
156.578 +
156.579 + assert sb.length() == doc.length();
156.580 +
156.581 + context.sanitizedRange = new OffsetRange(lineStart, lineEnd);
156.582 + context.sanitizedSource = sb.toString();
156.583 + context.sanitizedContents = doc.substring(lineStart, lineEnd);
156.584 + return true;
156.585 + }
156.586 + } else {
156.587 + assert sanitizing == Sanitize.ERROR_DOT || sanitizing == Sanitize.EDITED_DOT;
156.588 + // Try nuking dots/colons from this line
156.589 + // See if I should try to remove the current line, since it has text on it.
156.590 + int lineStart = GsfUtilities.getRowStart(doc, offset);
156.591 + int lineEnd = offset - 1;
156.592 + while (lineEnd >= lineStart && lineEnd < doc.length()) {
156.593 + if (!Character.isWhitespace(doc.charAt(lineEnd))) {
156.594 + break;
156.595 + }
156.596 + lineEnd--;
156.597 + }
156.598 + if (lineEnd > lineStart) {
156.599 + StringBuilder sb = new StringBuilder(doc.length());
156.600 + String line = doc.substring(lineStart, lineEnd + 1);
156.601 + int removeChars = 0;
156.602 + int removeEnd = lineEnd + 1;
156.603 + boolean isLineEnd = GsfUtilities.getRowLastNonWhite(context.source, lineEnd) <= lineEnd;
156.604 +
156.605 + if (line.endsWith(".")) { // NOI18N
156.606 + removeChars = 1;
156.607 + } else if (line.endsWith("(")) { // NOI18N
156.608 + if (isLineEnd) {
156.609 + removeChars = 1;
156.610 + }
156.611 + } else if (line.endsWith(",")) { // NOI18N removeChars = 1;
156.612 + if (!isLineEnd) {
156.613 + removeChars = 1;
156.614 + }
156.615 + } else if (line.endsWith(", ")) { // NOI18N
156.616 + if (!isLineEnd) {
156.617 + removeChars = 2;
156.618 + }
156.619 + } else if (line.endsWith(",)")) { // NOI18N
156.620 + // Handle lone comma in parameter list - e.g.
156.621 + // type "foo(a," -> you end up with "foo(a,|)" which doesn't parse - but
156.622 + // the line ends with ")", not "," !
156.623 + // Just remove the comma
156.624 + removeChars = 1;
156.625 + removeEnd--;
156.626 + } else if (line.endsWith(", )")) { // NOI18N
156.627 + // Just remove the comma
156.628 + removeChars = 1;
156.629 + removeEnd -= 2;
156.630 + } else if (line.endsWith(" def") && isLineEnd) { // NOI18N
156.631 + removeChars = 3;
156.632 + } else {
156.633 +// // Make sure the line doesn't end with one of the JavaScript keywords
156.634 +// // (new, do, etc) - we can't handle that!
156.635 +// for (String keyword : PythonUtils.PYTHON_KEYWORDS) { // reserved words are okay
156.636 +// if (line.endsWith(keyword)) {
156.637 +// if ("print".equals(keyword)) { // NOI18N
156.638 +// // Only remove the keyword if it's the end of the line. Otherwise,
156.639 +// // it could have just been typed in front of something (e.g. inserted a print) and we don't
156.640 +// // want to confuse the parser with "va foo" instead of "var foo"
156.641 +// if (!isLineEnd) {
156.642 +// continue;
156.643 +// }
156.644 +// }
156.645 +// removeChars = 1;
156.646 +// break;
156.647 +// }
156.648 +// }
156.649 + }
156.650 +
156.651 + if (removeChars == 0) {
156.652 + return false;
156.653 + }
156.654 +
156.655 + int removeStart = removeEnd - removeChars;
156.656 +
156.657 + sb.append(doc.substring(0, removeStart));
156.658 +
156.659 + for (int i = 0; i < removeChars; i++) {
156.660 + sb.append(' ');
156.661 + }
156.662 +
156.663 + if (removeEnd < doc.length()) {
156.664 + sb.append(doc.substring(removeEnd, doc.length()));
156.665 + }
156.666 + assert sb.length() == doc.length();
156.667 +
156.668 + context.sanitizedRange = new OffsetRange(removeStart, removeEnd);
156.669 + context.sanitizedSource = sb.toString();
156.670 + context.sanitizedContents = doc.substring(removeStart, removeEnd);
156.671 + return true;
156.672 + }
156.673 + }
156.674 + }
156.675 + } catch (BadLocationException ble) {
156.676 + Exceptions.printStackTrace(ble);
156.677 + }
156.678 +
156.679 + return false;
156.680 + }
156.681 +
156.682 + private static int findLineOffset(String source, int line) {
156.683 + int offset = -1;
156.684 + for (int i = 0; i < line; i++) {
156.685 + offset = source.indexOf("\n", offset+1);
156.686 + if (offset == -1) {
156.687 + return source.length();
156.688 + }
156.689 + }
156.690 +
156.691 + return Math.min(source.length(), offset+1);
156.692 + }
156.693 +
156.694 + /** Attempts to sanitize the input buffer */
156.695 + public static enum Sanitize {
156.696 + /** Only parse the current file accurately, don't try heuristics */
156.697 + NEVER,
156.698 + /** Perform no sanitization */
156.699 + NONE,
156.700 + /** Try to remove the trailing . or :: at the caret line */
156.701 + EDITED_DOT,
156.702 + /** Try to remove the trailing . or :: at the error position, or the prior
156.703 + * line, or the caret line */
156.704 + ERROR_DOT,
156.705 + /** Try to cut out the error line */
156.706 + ERROR_LINE,
156.707 + /** Try to cut out the current edited line, if known */
156.708 + EDITED_LINE,
156.709 + }
156.710 +
156.711 + /** Sanitize context */
156.712 + public static class Context {
156.713 + private FileObject file;
156.714 +// private ParseListener listener;
156.715 + private int errorOffset;
156.716 + private String source;
156.717 + private String sanitizedSource;
156.718 + private OffsetRange sanitizedRange = OffsetRange.NONE;
156.719 + private String sanitizedContents;
156.720 + private int caretOffset;
156.721 + private Sanitize sanitized = Sanitize.NONE;
156.722 +// private TranslatedSource translatedSource;
156.723 +// private Parser.Job job;
156.724 + private Snapshot snapshot;
156.725 + private Task task;
156.726 + private SourceModificationEvent event;
156.727 +//
156.728 +// public Context(ParserFile parserFile, ParseListener listener, String source, int caretOffset, TranslatedSource translatedSource, Parser.Job job) {
156.729 +// this.file = parserFile;
156.730 +// this.listener = listener;
156.731 +// this.source = source;
156.732 +// this.caretOffset = caretOffset;
156.733 +// this.translatedSource = translatedSource;
156.734 +// this.job = job;
156.735 +//
156.736 +//
156.737 +// if (caretOffset != -1) {
156.738 +// sanitized = Sanitize.EDITED_DOT;
156.739 +// }
156.740 +// }
156.741 +//
156.742 +// @Override
156.743 +// public String toString() {
156.744 +// return "PythonParser.Context(" + file.toString() + ")"; // NOI18N
156.745 +// }
156.746 +//
156.747 +// public OffsetRange getSanitizedRange() {
156.748 +// return sanitizedRange;
156.749 +// }
156.750 +//
156.751 +// public Sanitize getSanitized() {
156.752 +// return sanitized;
156.753 +// }
156.754 +//
156.755 +// public String getSanitizedSource() {
156.756 +// return sanitizedSource;
156.757 +// }
156.758 +//
156.759 +// public int getErrorOffset() {
156.760 +// return errorOffset;
156.761 +// }
156.762 + }
156.763 +}
157.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
157.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonParserResult.java Wed Sep 02 20:31:18 2015 +0200
157.3 @@ -0,0 +1,152 @@
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.util.LinkedList;
157.37 +import java.util.List;
157.38 +import org.netbeans.api.annotations.common.NonNull;
157.39 +import org.netbeans.modules.csl.api.Error;
157.40 +import org.netbeans.modules.csl.api.OffsetRange;
157.41 +import org.netbeans.modules.csl.spi.ParserResult;
157.42 +import org.netbeans.modules.parsing.api.Snapshot;
157.43 +import org.netbeans.modules.python.source.PythonParser.Sanitize;
157.44 +import org.netbeans.modules.python.source.scopes.SymbolTable;
157.45 +import org.python.antlr.PythonTree;
157.46 +
157.47 +/**
157.48 + * A ParserResult for Python. The AST Jython's AST.
157.49 + *
157.50 + * @todo Cache AstPath for caret position here!
157.51 + * @author Tor Norbye
157.52 + */
157.53 +public class PythonParserResult extends ParserResult {
157.54 + private PythonTree root;
157.55 + private List<Error> errors;
157.56 + private OffsetRange sanitizedRange = OffsetRange.NONE;
157.57 + private String source;
157.58 + private String sanitizedContents;
157.59 + private PythonParser.Sanitize sanitized;
157.60 + private PythonStructureScanner.AnalysisResult analysisResult;
157.61 + private SymbolTable symbolTable;
157.62 + private int codeTemplateOffset = -1;
157.63 +
157.64 + public PythonParserResult(PythonTree tree, @NonNull Snapshot snapshot) {
157.65 + super(snapshot);
157.66 + this.root = tree;
157.67 + this.errors = new LinkedList<>();
157.68 + }
157.69 +
157.70 + public PythonTree getRoot() {
157.71 + return root;
157.72 + }
157.73 +
157.74 + @Override
157.75 + public List<? extends Error> getDiagnostics() {
157.76 + return errors;
157.77 + }
157.78 +
157.79 + @Override
157.80 + protected void invalidate() {
157.81 + }
157.82 +
157.83 + public void setErrors(List<? extends Error> errors) {
157.84 + this.errors.clear();
157.85 + this.errors.addAll(errors);
157.86 + }
157.87 +
157.88 + /**
157.89 + * Set the range of source that was sanitized, if any.
157.90 + */
157.91 + void setSanitized(PythonParser.Sanitize sanitized, OffsetRange sanitizedRange, String sanitizedContents) {
157.92 + this.sanitized = sanitized;
157.93 + this.sanitizedRange = sanitizedRange;
157.94 + this.sanitizedContents = sanitizedContents;
157.95 + if (sanitizedContents == null || sanitizedRange == OffsetRange.NONE) {
157.96 + this.sanitized = Sanitize.NONE;
157.97 + }
157.98 + }
157.99 +
157.100 + public PythonParser.Sanitize getSanitized() {
157.101 + return sanitized;
157.102 + }
157.103 +
157.104 + /**
157.105 + * Return whether the source code for the parse result was "cleaned"
157.106 + * or "sanitized" (modified to reduce chance of parser errors) or not.
157.107 + * This method returns OffsetRange.NONE if the source was not sanitized,
157.108 + * otherwise returns the actual sanitized range.
157.109 + */
157.110 + public OffsetRange getSanitizedRange() {
157.111 + return sanitizedRange;
157.112 + }
157.113 +
157.114 + public SymbolTable getSymbolTable() {
157.115 + if (symbolTable == null) {
157.116 + symbolTable = new SymbolTable(root, getSnapshot().getSource().getFileObject());
157.117 + }
157.118 +
157.119 + return symbolTable;
157.120 + }
157.121 +
157.122 + public String getSanitizedContents() {
157.123 + return sanitizedContents;
157.124 + }
157.125 +
157.126 + public String getSource() {
157.127 + return source;
157.128 + }
157.129 +
157.130 + public void setSource(String source) {
157.131 + this.source = source;
157.132 + }
157.133 +
157.134 + /**
157.135 + * @return the codeTemplateOffset
157.136 + */
157.137 + public int getCodeTemplateOffset() {
157.138 + return codeTemplateOffset;
157.139 + }
157.140 +
157.141 + /**
157.142 + * @param codeTemplateOffset the codeTemplateOffset to set
157.143 + */
157.144 + public void setCodeTemplateOffset(int codeTemplateOffset) {
157.145 + this.codeTemplateOffset = codeTemplateOffset;
157.146 + }
157.147 +
157.148 + public void addError(Error e) {
157.149 + errors.add(e);
157.150 + }
157.151 +
157.152 + public boolean isValid() {
157.153 + return errors.isEmpty();
157.154 + }
157.155 +}
158.1 --- a/python.source/src/org/netbeans/modules/python/source/PythonProjectSourceLevelQuery.java Mon Aug 31 12:40:19 2015 +0200
158.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
158.3 @@ -1,29 +0,0 @@
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.python.source.queries.SourceLevelQueryImplementation;
158.12 -import org.netbeans.api.project.FileOwnerQuery;
158.13 -import org.netbeans.api.project.Project;
158.14 -import org.openide.filesystems.FileObject;
158.15 -import org.openide.util.lookup.ServiceProvider;
158.16 -
158.17 -@ServiceProvider(service = SourceLevelQueryImplementation.class, position = 400)
158.18 -public class PythonProjectSourceLevelQuery implements SourceLevelQueryImplementation {
158.19 -
158.20 - @Override
158.21 - public Result getSourceLevel(FileObject pythonFile) {
158.22 - final Project project = FileOwnerQuery.getOwner(pythonFile);
158.23 - if (project != null) {
158.24 - SourceLevelQueryImplementation impl = project.getLookup().lookup(SourceLevelQueryImplementation.class);
158.25 - if (impl != null) {
158.26 - return impl.getSourceLevel(pythonFile);
158.27 - }
158.28 - }
158.29 - return null;
158.30 - }
158.31 -
158.32 -}
159.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
159.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonStructureItem.java Wed Sep 02 20:31:18 2015 +0200
159.3 @@ -0,0 +1,195 @@
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.util.ArrayList;
159.37 +import java.util.Collections;
159.38 +import java.util.List;
159.39 +import javax.swing.ImageIcon;
159.40 +import org.netbeans.modules.csl.api.ElementHandle;
159.41 +import org.netbeans.modules.csl.api.ElementKind;
159.42 +import org.netbeans.modules.csl.api.HtmlFormatter;
159.43 +import org.netbeans.modules.csl.api.Modifier;
159.44 +import org.netbeans.modules.csl.api.StructureItem;
159.45 +import org.netbeans.modules.python.source.elements.AstElement;
159.46 +import org.netbeans.modules.python.source.scopes.SymbolTable;
159.47 +import org.openide.util.ImageUtilities;
159.48 +import org.python.antlr.PythonTree;
159.49 +import org.python.antlr.ast.ClassDef;
159.50 +import org.python.antlr.ast.FunctionDef;
159.51 +
159.52 +public final class PythonStructureItem extends AstElement implements StructureItem {
159.53 + private List<PythonStructureItem> children;
159.54 + private PythonStructureItem parent;
159.55 +
159.56 + public PythonStructureItem(SymbolTable scopes, ClassDef def) {
159.57 + this(scopes, def, def.getInternalName(), ElementKind.CLASS);
159.58 + }
159.59 +
159.60 + public PythonStructureItem(SymbolTable scopes, FunctionDef def) {
159.61 + this(scopes, def, def.getInternalName(), ElementKind.METHOD);
159.62 + if ("__init__".equals(name)) { // NOI18N
159.63 + kind = ElementKind.CONSTRUCTOR;
159.64 + }
159.65 + }
159.66 +
159.67 + public PythonStructureItem(SymbolTable scopes, PythonTree node, String name, ElementKind kind) {
159.68 + super(scopes, node, name, kind);
159.69 + this.node = node;
159.70 + this.name = name;
159.71 + this.kind = kind;
159.72 + }
159.73 +
159.74 + void add(PythonStructureItem child) {
159.75 + if (children == null) {
159.76 + children = new ArrayList<>();
159.77 + }
159.78 + children.add(child);
159.79 + child.parent = this;
159.80 + }
159.81 +
159.82 + @Override
159.83 + public String getSortText() {
159.84 + return name;
159.85 + }
159.86 +
159.87 + @Override
159.88 + public String getHtml(HtmlFormatter formatter) {
159.89 + formatter.appendText(name);
159.90 + if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
159.91 + FunctionDef def = (FunctionDef)node;
159.92 + List<String> params = PythonAstUtils.getParameters(def);
159.93 + if (params.size() > 0) {
159.94 + boolean isFirst = true;
159.95 + formatter.appendHtml("(");
159.96 + formatter.parameters(true);
159.97 + for (String param : params) {
159.98 + if (isFirst) {
159.99 + isFirst = false;
159.100 + } else {
159.101 + formatter.appendText(",");
159.102 + }
159.103 + formatter.appendText(param);
159.104 + }
159.105 + formatter.parameters(false);
159.106 + formatter.appendHtml(")");
159.107 + }
159.108 + }
159.109 + return formatter.getText();
159.110 + }
159.111 +
159.112 + @Override
159.113 + public ElementHandle getElementHandle() {
159.114 + return null;
159.115 + }
159.116 +
159.117 + @Override
159.118 + public boolean isLeaf() {
159.119 + return children == null;
159.120 + }
159.121 +
159.122 + @Override
159.123 + public List<? extends StructureItem> getNestedItems() {
159.124 + return children == null ? Collections.<StructureItem>emptyList() : children;
159.125 + }
159.126 +
159.127 + @Override
159.128 + public long getPosition() {
159.129 + return node.getCharStartIndex();
159.130 + }
159.131 +
159.132 + @Override
159.133 + public long getEndPosition() {
159.134 + return node.getCharStopIndex();
159.135 + }
159.136 +
159.137 + @Override
159.138 + public ImageIcon getCustomIcon() {
159.139 + if (kind == ElementKind.CLASS && getModifiers().contains(Modifier.PRIVATE)) {
159.140 + // GSF doesn't automatically handle icons on private classes, so I have to
159.141 + // work around that here
159.142 + return ImageUtilities.loadImageIcon("org/netbeans/modules/python/editor/resources/private-class.png", false); //NOI18N
159.143 + }
159.144 +
159.145 + return null;
159.146 + }
159.147 +
159.148 + @Override
159.149 + public Object getSignature() {
159.150 + if ((kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) && parent != null &&
159.151 + parent.kind == ElementKind.CLASS) {
159.152 + return parent.name + "." + name;
159.153 + }
159.154 + return super.getSignature();
159.155 + }
159.156 +
159.157 + @Override
159.158 + public boolean equals(Object obj) {
159.159 + if (obj == null) {
159.160 + return false;
159.161 + }
159.162 + if (getClass() != obj.getClass()) {
159.163 + return false;
159.164 + }
159.165 + final PythonStructureItem other = (PythonStructureItem)obj;
159.166 + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
159.167 + return false;
159.168 + }
159.169 + if (this.kind != other.kind) {
159.170 + return false;
159.171 + }
159.172 + if (this.getModifiers() != other.getModifiers() && (this.modifiers == null || !this.modifiers.equals(other.modifiers))) {
159.173 + return false;
159.174 + }
159.175 +
159.176 + if ((kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) && node != null && other.node != null) {
159.177 + FunctionDef def = (FunctionDef)node;
159.178 + List<String> params = PythonAstUtils.getParameters(def);
159.179 + List<String> otherParams = PythonAstUtils.getParameters((FunctionDef)other.node);
159.180 + if (!params.equals((otherParams))) {
159.181 + return false;
159.182 + }
159.183 + }
159.184 +
159.185 +// if (this.getNestedItems().size() != other.getNestedItems().size()) {
159.186 +// return false;
159.187 +// }
159.188 +//
159.189 + return true;
159.190 + }
159.191 +
159.192 + @Override
159.193 + public int hashCode() {
159.194 + int hash = 7;
159.195 + hash = 97 * hash + (this.name != null ? this.name.hashCode() : 0);
159.196 + return hash;
159.197 + }
159.198 +}
160.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
160.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonStructureScanner.java Wed Sep 02 20:31:18 2015 +0200
160.3 @@ -0,0 +1,274 @@
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.ArrayList;
160.37 +import java.util.Collections;
160.38 +import java.util.HashMap;
160.39 +import java.util.List;
160.40 +import java.util.Map;
160.41 +import javax.swing.text.BadLocationException;
160.42 +import org.netbeans.modules.python.source.lexer.PythonLexerUtils;
160.43 +import org.netbeans.editor.BaseDocument;
160.44 +import org.netbeans.editor.Utilities;
160.45 +import org.netbeans.modules.csl.api.ElementKind;
160.46 +import org.netbeans.modules.csl.api.OffsetRange;
160.47 +import org.netbeans.modules.csl.api.StructureItem;
160.48 +import org.netbeans.modules.csl.api.StructureScanner;
160.49 +import org.netbeans.modules.csl.api.StructureScanner.Configuration;
160.50 +import org.netbeans.modules.csl.spi.GsfUtilities;
160.51 +import org.netbeans.modules.csl.spi.ParserResult;
160.52 +import org.netbeans.modules.python.source.scopes.ScopeInfo;
160.53 +import org.netbeans.modules.python.source.scopes.SymInfo;
160.54 +import org.netbeans.modules.python.source.scopes.SymbolTable;
160.55 +import org.openide.util.Exceptions;
160.56 +import org.python.antlr.PythonTree;
160.57 +import org.python.antlr.Visitor;
160.58 +import org.python.antlr.ast.ClassDef;
160.59 +import org.python.antlr.ast.FunctionDef;
160.60 +import org.python.antlr.ast.Str;
160.61 +
160.62 +/**
160.63 + * This class analyzes the structure of a Python parse tree
160.64 + * and infers structure (navigation items, folds, etc.)
160.65 + *
160.66 + * @author Tor Norbye
160.67 + */
160.68 +public class PythonStructureScanner implements StructureScanner {
160.69 +
160.70 + public static AnalysisResult analyze(PythonParserResult info) {
160.71 + AnalysisResult analysisResult = new AnalysisResult();
160.72 +
160.73 + PythonTree root = PythonAstUtils.getRoot(info);
160.74 + if (root != null) {
160.75 + SymbolTable scopes = PythonAstUtils.getParseResult(info).getSymbolTable();
160.76 + StructureVisitor visitor = new StructureVisitor(scopes);
160.77 + try {
160.78 + visitor.visit(root);
160.79 + analysisResult.setElements(visitor.getRoots());
160.80 + } catch (Exception ex) {
160.81 + Exceptions.printStackTrace(ex);
160.82 + }
160.83 + }
160.84 +
160.85 + return analysisResult;
160.86 + }
160.87 +
160.88 + @Override
160.89 + public List<? extends StructureItem> scan(ParserResult info) {
160.90 + PythonParserResult parseResult = PythonAstUtils.getParseResult(info);
160.91 + if (parseResult == null) {
160.92 + return Collections.emptyList();
160.93 + }
160.94 +
160.95 + return getStructure(parseResult).getElements();
160.96 + }
160.97 +
160.98 + public PythonStructureScanner.AnalysisResult getStructure(PythonParserResult result) {
160.99 + // TODO Cache ! (Used to be in PythonParserResult
160.100 + AnalysisResult analysisResult = PythonStructureScanner.analyze(result);
160.101 + return analysisResult;
160.102 + }
160.103 +
160.104 + @Override
160.105 + public Map<String, List<OffsetRange>> folds(ParserResult info) {
160.106 + PythonParserResult result = PythonAstUtils.getParseResult(info);
160.107 + PythonTree root = PythonAstUtils.getRoot(result);
160.108 + if (root == null) {
160.109 + return Collections.emptyMap();
160.110 + }
160.111 +
160.112 + //TranslatedSource source = result.getTranslatedSource();
160.113 + //
160.114 + //AnalysisResult ar = result.getStructure();
160.115 + //
160.116 + //List<?extends AstElement> elements = ar.getElements();
160.117 + //List<StructureItem> itemList = new ArrayList<StructureItem>(elements.size());
160.118 +
160.119 + BaseDocument doc = GsfUtilities.getDocument(result.getSnapshot().getSource().getFileObject(), false);
160.120 + if (doc != null) {
160.121 + try {
160.122 + doc.readLock(); // For Utilities.getRowEnd() access
160.123 + FoldVisitor visitor = new FoldVisitor((PythonParserResult) info, doc);
160.124 + visitor.visit(root);
160.125 + List<OffsetRange> codeBlocks = visitor.getCodeBlocks();
160.126 +
160.127 + Map<String, List<OffsetRange>> folds = new HashMap<>();
160.128 + folds.put("codeblocks", codeBlocks); // NOI18N
160.129 +
160.130 + return folds;
160.131 + } catch (Exception ex) {
160.132 + Exceptions.printStackTrace(ex);
160.133 + } finally {
160.134 + doc.readUnlock();
160.135 + }
160.136 + }
160.137 + return Collections.emptyMap();
160.138 + }
160.139 +
160.140 + @Override
160.141 + public Configuration getConfiguration() {
160.142 + return new Configuration(true, true, -1);
160.143 + }
160.144 +
160.145 + private static class FoldVisitor extends Visitor {
160.146 + private List<OffsetRange> codeBlocks = new ArrayList<>();
160.147 + private PythonParserResult info;
160.148 + private BaseDocument doc;
160.149 +
160.150 + private FoldVisitor(PythonParserResult info, BaseDocument doc) {
160.151 + this.info = info;
160.152 + this.doc = doc;
160.153 + }
160.154 +
160.155 + private void addFoldRange(PythonTree node) {
160.156 + OffsetRange astRange = PythonAstUtils.getRange(node);
160.157 +
160.158 + OffsetRange lexRange = PythonLexerUtils.getLexerOffsets(info, astRange);
160.159 + if (lexRange != OffsetRange.NONE) {
160.160 + try {
160.161 + int startRowEnd = Utilities.getRowEnd(doc, lexRange.getStart());
160.162 + if (startRowEnd < lexRange.getEnd()) {
160.163 + codeBlocks.add(new OffsetRange(startRowEnd, lexRange.getEnd()));
160.164 + }
160.165 + } catch (BadLocationException ex) {
160.166 + Exceptions.printStackTrace(ex);
160.167 + }
160.168 + }
160.169 + }
160.170 +
160.171 + @Override
160.172 + public Object visitClassDef(ClassDef node) throws Exception {
160.173 + addFoldRange(node);
160.174 +
160.175 + return super.visitClassDef(node);
160.176 + }
160.177 +
160.178 + @Override
160.179 + public Object visitFunctionDef(FunctionDef node) throws Exception {
160.180 + addFoldRange(node);
160.181 +
160.182 + return super.visitFunctionDef(node);
160.183 + }
160.184 +
160.185 + @Override
160.186 + public Object visitStr(Str node) throws Exception {
160.187 + addFoldRange(node);
160.188 + return super.visitStr(node);
160.189 + }
160.190 +
160.191 + public List<OffsetRange> getCodeBlocks() {
160.192 + return codeBlocks;
160.193 + }
160.194 + }
160.195 +
160.196 + private static class StructureVisitor extends Visitor {
160.197 + List<PythonStructureItem> roots = new ArrayList<>();
160.198 + List<PythonStructureItem> stack = new ArrayList<>();
160.199 + SymbolTable scopes;
160.200 +
160.201 + StructureVisitor(SymbolTable scopes) {
160.202 + this.scopes = scopes;
160.203 + }
160.204 +
160.205 + private List<PythonStructureItem> getRoots() {
160.206 + return roots;
160.207 + }
160.208 +
160.209 + @Override
160.210 + public Object visitClassDef(ClassDef def) throws Exception {
160.211 + PythonStructureItem item = new PythonStructureItem(scopes, def);
160.212 + add(item);
160.213 +
160.214 + ScopeInfo scope = scopes.getScopeInfo(def);
160.215 + if (scope != null && scope.attributes.size() > 0) {
160.216 + for (Map.Entry<String, SymInfo> entry : scope.attributes.entrySet()) {
160.217 + // TODO - sort these puppies? Right now their natural order will be
160.218 + // random (hashkey dependent) instead of by source position or by name
160.219 + SymInfo sym = entry.getValue();
160.220 + if (sym.node != null) {
160.221 + String name = entry.getKey();
160.222 + PythonStructureItem attribute = new PythonStructureItem(scopes, sym.node, name, ElementKind.ATTRIBUTE);
160.223 + item.add(attribute);
160.224 + }
160.225 + }
160.226 + }
160.227 +
160.228 + stack.add(item);
160.229 + Object result = super.visitClassDef(def);
160.230 + stack.remove(stack.size() - 1);
160.231 +
160.232 + return result;
160.233 + }
160.234 +
160.235 + @Override
160.236 + public Object visitFunctionDef(FunctionDef def) throws Exception {
160.237 + PythonStructureItem item = new PythonStructureItem(scopes, def);
160.238 +
160.239 + add(item);
160.240 + stack.add(item);
160.241 + Object result = super.visitFunctionDef(def);
160.242 + stack.remove(stack.size() - 1);
160.243 +
160.244 + return result;
160.245 + }
160.246 +
160.247 + private void add(PythonStructureItem child) {
160.248 + PythonStructureItem parent = stack.size() > 0 ? stack.get(stack.size() - 1) : null;
160.249 + if (parent == null) {
160.250 + roots.add(child);
160.251 + } else {
160.252 + parent.add(child);
160.253 + }
160.254 + }
160.255 + }
160.256 +
160.257 + public static class AnalysisResult {
160.258 + //private List<?extends AstElement> elements;
160.259 + private List<PythonStructureItem> elements;
160.260 +
160.261 + private AnalysisResult() {
160.262 + }
160.263 +
160.264 + //private void setElements(List<?extends AstElement> elements) {
160.265 + private void setElements(List<PythonStructureItem> elements) {
160.266 + this.elements = elements;
160.267 + }
160.268 +
160.269 + //public List<?extends AstElement> getElements() {
160.270 + public List<PythonStructureItem> getElements() {
160.271 + if (elements == null) {
160.272 + return Collections.emptyList();
160.273 + }
160.274 + return elements;
160.275 + }
160.276 + }
160.277 +}
161.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
161.2 +++ b/python.source/src/org/netbeans/modules/python/source/PythonUtils.java Wed Sep 02 20:31:18 2015 +0200
161.3 @@ -0,0 +1,506 @@
161.4 +/*
161.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
161.6 + *
161.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
161.8 + *
161.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
161.10 + * Other names may be trademarks of their respective owners.
161.11 + *
161.12 + * The contents of this file are subject to the terms of either the GNU
161.13 + * General Public License Version 2 only ("GPL") or the Common
161.14 + * Development and Distribution License("CDDL") (collectively, the
161.15 + * "License"). You may not use this file except in compliance with the
161.16 + * License. You can obtain a copy of the License at
161.17 + * http://www.netbeans.org/cddl-gplv2.html
161.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
161.19 + * specific language governing permissions and limitations under the
161.20 + * License. When distributing the software, include this License Header
161.21 + * Notice in each file and include the License file at
161.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
161.23 + * particular file as subject to the "Classpath" exception as provided
161.24 + * by Oracle in the GPL Version 2 section of the License file that
161.25 + * accompanied this code. If applicable, add the following below the
161.26 + * License Header, with the fields enclosed by brackets [] replaced by
161.27 + * your own identifying information:
161.28 + * "Portions Copyrighted [year] [name of copyright owner]"
161.29 + *
161.30 + * Contributor(s):
161.31 + *
161.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
161.33 + */
161.34 +package org.netbeans.modules.python.source;
161.35 +
161.36 +import java.util.Comparator;
161.37 +import java.util.List;
161.38 +import javax.swing.text.Document;
161.39 +import org.netbeans.api.annotations.common.NonNull;
161.40 +import org.netbeans.api.project.FileOwnerQuery;
161.41 +import org.netbeans.api.project.Project;
161.42 +import org.netbeans.api.project.ProjectUtils;
161.43 +import org.netbeans.api.project.SourceGroup;
161.44 +import org.netbeans.api.project.Sources;
161.45 +import org.netbeans.modules.python.api.PythonMIMEResolver;
161.46 +import org.netbeans.modules.python.api.PythonPlatform;
161.47 +import org.netbeans.modules.python.api.PythonPlatformManager;
161.48 +import org.openide.filesystems.FileObject;
161.49 +import org.openide.filesystems.FileUtil;
161.50 +import org.openide.util.NbBundle;
161.51 +import org.python.antlr.PythonTree;
161.52 +import org.python.antlr.ast.Attribute;
161.53 +import org.python.antlr.ast.Name;
161.54 +
161.55 +/**
161.56 + *
161.57 + * @author Tor Norbye
161.58 + */
161.59 +public class PythonUtils {
161.60 + public static boolean canContainPython(FileObject f) {
161.61 + String mimeType = f.getMIMEType();
161.62 + return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(mimeType);
161.63 + // TODO: "text/x-yaml".equals(mimeType) || // NOI18N
161.64 + // RubyInstallation.RHTML_MIME_TYPE.equals(mimeType);
161.65 + }
161.66 +
161.67 + public static boolean isPythonFile(FileObject f) {
161.68 + return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(f.getMIMEType());
161.69 + }
161.70 +
161.71 + public static boolean isRstFile(FileObject f) {
161.72 + return "rst".equals(f.getExt()); // NOI18N
161.73 + }
161.74 +
161.75 + public static boolean isPythonDocument(Document doc) {
161.76 + String mimeType = (String)doc.getProperty("mimeType"); // NOI18N
161.77 +
161.78 + return PythonMIMEResolver.PYTHON_MIME_TYPE.equals(mimeType);
161.79 + }
161.80 + public static final String DOT__INIT__ = ".__init__"; // NOI18N
161.81 +
161.82 + // From PythonProjectType
161.83 + public static final String SOURCES_TYPE_PYTHON = "python"; // NOI18N
161.84 +
161.85 + // Cache
161.86 + private static FileObject prevParent;
161.87 + private static String prevRootUrl;
161.88 +
161.89 + /**
161.90 + * Produce the module name (including packages) for a given python source file.
161.91 + *
161.92 + * @param fo The source file (can be null, if file is not))
161.93 + * @param file The parser file (can be null, if fo is not).
161.94 + * @param fileName The filename (basename only)
161.95 + * @param projectRelativeName If non null, the path from the project root down to this file
161.96 + * @return A string for the full package module name
161.97 + */
161.98 + public static String getModuleName(@NonNull FileObject fo) {
161.99 +
161.100 + // TODO - use PythonPlatform's library roots!
161.101 +
161.102 + String module = fo.getName();
161.103 +
161.104 + // First see if we're on the load path for the platform, and if so,
161.105 + // use that as the base
161.106 + // TODO - look up platform for the current search context instead of all platforms!!
161.107 + if (fo.getParent() != prevParent) {
161.108 + prevRootUrl = null;
161.109 + prevParent = fo.getParent();
161.110 + }
161.111 +
161.112 + String url = fo.toURL().toExternalForm();
161.113 + if (prevRootUrl == null) {
161.114 + boolean found = false;
161.115 + PythonPlatformManager manager = PythonPlatformManager.getInstance();
161.116 +
161.117 + PlatformSearch:
161.118 + for (String name : manager.getPlatformList()) {
161.119 + PythonPlatform platform = manager.getPlatform(name);
161.120 + if (platform != null) {
161.121 + List<FileObject> unique = platform.getUniqueLibraryRoots();
161.122 + for (FileObject root : unique) {
161.123 + if (FileUtil.isParentOf(root, fo)) {
161.124 + for (FileObject r : platform.getLibraryRoots()) {
161.125 + if (FileUtil.isParentOf(r, fo)) {
161.126 + // See if the folder itself contains
161.127 + // an __init__.py file - if it does,
161.128 + // then include the directory itself
161.129 + // in the package name.
161.130 + if (r.getFileObject("__init__.py") != null) { // NOI18N
161.131 + r = r.getParent();
161.132 + }
161.133 +
161.134 + prevRootUrl = r.toURL().toExternalForm();
161.135 + found = true;
161.136 + break PlatformSearch;
161.137 + }
161.138 + }
161.139 + break PlatformSearch;
161.140 + }
161.141 + }
161.142 + }
161.143 + }
161.144 +
161.145 + if (!found) {
161.146 + Project project = FileOwnerQuery.getOwner(fo);
161.147 + if (project != null) {
161.148 + Sources source = ProjectUtils.getSources(project);
161.149 + // Look up the source path
161.150 + SourceGroup[] sourceGroups = source.getSourceGroups(SOURCES_TYPE_PYTHON);
161.151 + for (SourceGroup group : sourceGroups) {
161.152 + FileObject folder = group.getRootFolder();
161.153 + if (FileUtil.isParentOf(folder, fo)) {
161.154 + // See if the folder itself contains
161.155 + // an __init__.py file - if it does,
161.156 + // then include the directory itself
161.157 + // in the package name.
161.158 + if (folder.getFileObject("__init__.py") != null) { // NOI18N
161.159 + folder = folder.getParent();
161.160 + }
161.161 +
161.162 + prevRootUrl = folder.toURL().toExternalForm();
161.163 + break;
161.164 + }
161.165 + }
161.166 + }
161.167 + }
161.168 + }
161.169 +
161.170 + if (prevRootUrl != null) {
161.171 + module = url.substring(prevRootUrl.length());
161.172 + if (module.startsWith("/")) {
161.173 + module = module.substring(1);
161.174 + }
161.175 + }
161.176 +
161.177 + // Strip off .y extension
161.178 + if (module.endsWith(".py")) { // NOI18N
161.179 + module = module.substring(0, module.length() - 3);
161.180 + }
161.181 +
161.182 + if (module.indexOf('/') != -1) {
161.183 + module = module.replace('/', '.');
161.184 + }
161.185 +
161.186 + if (module.endsWith(DOT__INIT__)) {
161.187 + module = module.substring(0, module.length() - DOT__INIT__.length());
161.188 + }
161.189 +
161.190 + return module;
161.191 + }
161.192 +
161.193 + // Keywords - according to http://docs.python.org/ref/keywords.html
161.194 + static final String[] PYTHON_KEYWORDS = new String[]{
161.195 + "and", // NOI18N
161.196 + "as", // NOI18N
161.197 + "assert", // NOI18N
161.198 + "break", // NOI18N
161.199 + "class", // NOI18N
161.200 + "continue", // NOI18N
161.201 + "def", // NOI18N
161.202 + "del", // NOI18N
161.203 + "elif", // NOI18N
161.204 + "else", // NOI18N
161.205 + "except", // NOI18N
161.206 + "exec", // NOI18N
161.207 + "finally", // NOI18N
161.208 + "for", // NOI18N
161.209 + "from", // NOI18N
161.210 + "global", // NOI18N
161.211 + "if", // NOI18N
161.212 + "import", // NOI18N
161.213 + "in", // NOI18N
161.214 + "is", // NOI18N
161.215 + "lambda", // NOI18N
161.216 + "not", // NOI18N
161.217 + "or", // NOI18N
161.218 + "pass", // NOI18N
161.219 + "print", // NOI18N
161.220 + "raise", // NOI18N
161.221 + "return", // NOI18N
161.222 + "try", // NOI18N
161.223 + "while", // NOI18N
161.224 + "with", // NOI18N
161.225 + "yield", // NOI18N
161.226 + };
161.227 +
161.228 + public static boolean isPythonKeyword(String name) {
161.229 + for (String s : PYTHON_KEYWORDS) {
161.230 + if (s.equals(name)) {
161.231 + return true;
161.232 + }
161.233 + }
161.234 +
161.235 + return false;
161.236 + }
161.237 +
161.238 + /**
161.239 + * Return true iff the name is a class name
161.240 + * @param name The name
161.241 + * @param emptyDefault Whether empty or _ names should be considered a class name or not
161.242 + * @return True iff the name looks like a class name
161.243 + */
161.244 + public static boolean isClassName(String name, boolean emptyDefault) {
161.245 + if (name == null || name.length() == 0) {
161.246 + return emptyDefault;
161.247 + }
161.248 + if (name.startsWith("_") && name.length() > 1) {
161.249 + return Character.isUpperCase(name.charAt(1));
161.250 + }
161.251 +
161.252 + return Character.isUpperCase(name.charAt(0));
161.253 + }
161.254 +
161.255 + /**
161.256 + * Return true iff the name is a method name
161.257 + * @param name The name
161.258 + * @param emptyDefault Whether empty or _ names should be considered a class name or not
161.259 + * @return True iff the name looks like a method name
161.260 + */
161.261 + public static boolean isMethodName(String name, boolean emptyDefault) {
161.262 + if (name == null || name.length() == 0) {
161.263 + return emptyDefault;
161.264 + }
161.265 + if (name.startsWith("__") && name.length() > 2) {
161.266 + return Character.isLowerCase(name.charAt(2));
161.267 + }
161.268 + if (name.startsWith("_") && name.length() > 1) {
161.269 + return Character.isLowerCase(name.charAt(1));
161.270 + }
161.271 +
161.272 + return Character.isLowerCase(name.charAt(0));
161.273 + }
161.274 +
161.275 + public static boolean isValidPythonClassName(String name) {
161.276 + if (isPythonKeyword(name)) {
161.277 + return false;
161.278 + }
161.279 +
161.280 + if (name.trim().length() == 0) {
161.281 + return false;
161.282 + }
161.283 +
161.284 + if (!Character.isUpperCase(name.charAt(0))) {
161.285 + return false;
161.286 + }
161.287 +
161.288 + for (int i = 1; i < name.length(); i++) {
161.289 + char c = name.charAt(i);
161.290 + if (!Character.isJavaIdentifierPart(c)) {
161.291 + return false;
161.292 + }
161.293 +
161.294 + }
161.295 +
161.296 + return true;
161.297 + }
161.298 +
161.299 + /** Is this name a valid operator name? */
161.300 + public static boolean isOperator(String name) {
161.301 + // TODO - update to Python
161.302 + if (name.length() == 0) {
161.303 + return false;
161.304 + }
161.305 +
161.306 + switch (name.charAt(0)) {
161.307 + case '+':
161.308 + return name.equals("+") || name.equals("+@");
161.309 + case '-':
161.310 + return name.equals("-") || name.equals("-@");
161.311 + case '*':
161.312 + return name.equals("*") || name.equals("**");
161.313 + case '<':
161.314 + return name.equals("<") || name.equals("<<") || name.equals("<=") || name.equals("<=>");
161.315 + case '>':
161.316 + return name.equals(">") || name.equals(">>") || name.equals(">=");
161.317 + case '=':
161.318 + return name.equals("=") || name.equals("==") || name.equals("===") || name.equals("=~");
161.319 + case '!':
161.320 + return name.equals("!=") || name.equals("!~");
161.321 + case '&':
161.322 + return name.equals("&") || name.equals("&&");
161.323 + case '|':
161.324 + return name.equals("|") || name.equals("||");
161.325 + case '[':
161.326 + return name.equals("[]") || name.equals("[]=");
161.327 + case '%':
161.328 + return name.equals("%");
161.329 + case '/':
161.330 + return name.equals("/");
161.331 + case '~':
161.332 + return name.equals("~");
161.333 + case '^':
161.334 + return name.equals("^");
161.335 + case '`':
161.336 + return name.equals("`");
161.337 + default:
161.338 + return false;
161.339 + }
161.340 + }
161.341 +
161.342 + public static boolean isValidPythonMethodName(String name) {
161.343 + if (isPythonKeyword(name)) {
161.344 + return false;
161.345 + }
161.346 +
161.347 + if (name.trim().length() == 0) {
161.348 + return false;
161.349 + }
161.350 +
161.351 + // TODO - allow operators
161.352 + if (isOperator(name)) {
161.353 + return true;
161.354 + }
161.355 +
161.356 + if (Character.isUpperCase(name.charAt(0)) || Character.isWhitespace(name.charAt(0))) {
161.357 + return false;
161.358 + }
161.359 +
161.360 + for (int i = 0; i < name.length(); i++) {
161.361 + char c = name.charAt(i);
161.362 + if (!(Character.isLetterOrDigit(c) || c == '_')) {
161.363 + return false;
161.364 + }
161.365 +
161.366 + }
161.367 +
161.368 + return true;
161.369 + }
161.370 +
161.371 + public static boolean isValidPythonIdentifier(String name) {
161.372 + if (isPythonKeyword(name)) {
161.373 + return false;
161.374 + }
161.375 +
161.376 + if (name.trim().length() == 0) {
161.377 + return false;
161.378 + }
161.379 +
161.380 + for (int i = 0; i < name.length(); i++) {
161.381 + // Identifier char isn't really accurate - I can have a function named "[]" etc.
161.382 + // so just look for -obvious- mistakes
161.383 + if (Character.isWhitespace(name.charAt(i))) {
161.384 + return false;
161.385 + }
161.386 +
161.387 + // TODO - make this more accurate, like the method validifier
161.388 + }
161.389 +
161.390 + return true;
161.391 + }
161.392 +
161.393 + /**
161.394 + * Ruby identifiers should consist of [a-zA-Z0-9_]
161.395 + * http://www.headius.com/rubyspec/index.php/Variables
161.396 + * <p>
161.397 + * This method also accepts the field/global chars
161.398 + * since it's unlikely
161.399 + */
161.400 + public static boolean isSafeIdentifierName(String name, int fromIndex) {
161.401 + int i = fromIndex;
161.402 + for (; i < name.length(); i++) {
161.403 + char c = name.charAt(i);
161.404 + if (!(c == '$' || c == '@' || c == ':')) {
161.405 + break;
161.406 + }
161.407 + }
161.408 + for (; i < name.length(); i++) {
161.409 + char c = name.charAt(i);
161.410 + if (!((c >= 'a' && c <= 'z') || (c == '_') ||
161.411 + (c >= 'A' && c <= 'Z') ||
161.412 + (c >= '0' && c <= '9') ||
161.413 + (c == '?') || (c == '=') || (c == '!'))) { // Method suffixes; only allowed on the last line
161.414 +
161.415 + if (isOperator(name)) {
161.416 + return true;
161.417 + }
161.418 +
161.419 + return false;
161.420 + }
161.421 + }
161.422 +
161.423 + return true;
161.424 + }
161.425 +
161.426 + /**
161.427 + * Return null if the given identifier name is valid, otherwise a localized
161.428 + * error message explaining the problem.
161.429 + */
161.430 + public static String getIdentifierWarning(String name, int fromIndex) {
161.431 + if (isSafeIdentifierName(name, fromIndex)) {
161.432 + return null;
161.433 + } else {
161.434 + return NbBundle.getMessage(PythonUtils.class, "UnsafeIdentifierName");
161.435 + }
161.436 + }
161.437 +
161.438 + /** @todo Move into GsfUtilities after 6.5 */
161.439 + public static int getOffsetByLineCol(String source, int line, int col) {
161.440 + int offset = 0;
161.441 + for (int i = 0; i < line; i++) {
161.442 + offset = source.indexOf('\n', offset);
161.443 + if (offset == -1) {
161.444 + offset = source.length();
161.445 + break;
161.446 + }
161.447 + offset++;
161.448 + }
161.449 + if (col > 0) { // -1: invalid
161.450 + offset += col;
161.451 + }
161.452 +
161.453 + return offset;
161.454 + }
161.455 + public static Comparator NAME_NODE_COMPARATOR = new Comparator<Name>() {
161.456 + @Override
161.457 + public int compare(Name n1, Name n2) {
161.458 + return n1.getInternalId().compareTo(n2.getInternalId());
161.459 + }
161.460 + };
161.461 + public static Comparator ATTRIBUTE_NAME_NODE_COMPARATOR = new Comparator<Object>() {
161.462 + @SuppressWarnings("unchecked")
161.463 + @Override
161.464 + public int compare(Object n1, Object n2) {
161.465 + String s1 = "";
161.466 + String s2 = "";
161.467 +
161.468 + if (n1 instanceof Name) {
161.469 + s1 = ((Name)n1).getInternalId();
161.470 + } else if (n1 instanceof Attribute) {
161.471 + Attribute a = (Attribute)n1;
161.472 + String v = PythonAstUtils.getName(a.getInternalValue());
161.473 + if (v != null) {
161.474 + s1 = a.getInternalAttr() + "." + v;
161.475 + } else {
161.476 + s1 = a.getInternalAttr();
161.477 + }
161.478 + }
161.479 +
161.480 + if (n2 instanceof Name) {
161.481 + s2 = ((Name)n2).getInternalId();
161.482 + } else if (n2 instanceof Attribute) {
161.483 + Attribute a = (Attribute)n2;
161.484 + String v = PythonAstUtils.getName(a.getInternalValue());
161.485 + if (v != null) {
161.486 + s2 = a.getInternalAttr() + "." + v;
161.487 + } else {
161.488 + s2 = a.getInternalAttr();
161.489 + }
161.490 + }
161.491 +
161.492 + return s1.compareTo(s2);
161.493 + }
161.494 + };
161.495 + public static Comparator NODE_POS_COMPARATOR = new Comparator<PythonTree>() {
161.496 + @Override
161.497 + public int compare(PythonTree p1, PythonTree p2) {
161.498 + int ret = p1.getCharStartIndex() - p2.getCharStartIndex();
161.499 + if (ret != 0) {
161.500 + return ret;
161.501 + }
161.502 + ret = p2.getCharStopIndex() - p1.getCharStopIndex();
161.503 + if (ret != 0) {
161.504 + return ret;
161.505 + }
161.506 + return p2.getAntlrType() - p1.getAntlrType();
161.507 + }
161.508 + };
161.509 +}
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
162.2 +++ b/python.source/src/org/netbeans/modules/python/source/RstFormatter.java Wed Sep 02 20:31:18 2015 +0200
162.3 @@ -0,0 +1,1342 @@
162.4 +/*
162.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
162.6 + *
162.7 + * Copyright 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 + * If you wish your version of this file to be governed by only the CDDL
162.31 + * or only the GPL Version 2, indicate your decision by adding
162.32 + * "[Contributor] elects to include this software in this distribution
162.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
162.34 + * single choice of license, a recipient has the option to distribute
162.35 + * your version of this file under either the CDDL, the GPL Version 2 or
162.36 + * to extend the choice of license to its licensees as provided above.
162.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
162.38 + * Version 2 license, then the option applies only if the new code is
162.39 + * made subject to such option by the copyright holder.
162.40 + *
162.41 + * Contributor(s):
162.42 + *
162.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
162.44 + */
162.45 +package org.netbeans.modules.python.source;
162.46 +
162.47 +import java.awt.Color;
162.48 +import java.io.CharConversionException;
162.49 +import java.util.ArrayList;
162.50 +import java.util.Collections;
162.51 +import java.util.List;
162.52 +import javax.swing.text.AttributeSet;
162.53 +import javax.swing.text.BadLocationException;
162.54 +import javax.swing.text.StyleConstants;
162.55 +import org.netbeans.api.editor.mimelookup.MimeLookup;
162.56 +import org.netbeans.api.editor.mimelookup.MimePath;
162.57 +import org.netbeans.api.editor.settings.FontColorSettings;
162.58 +import org.netbeans.api.lexer.Language;
162.59 +import org.netbeans.api.lexer.Token;
162.60 +import org.netbeans.api.lexer.TokenHierarchy;
162.61 +import org.netbeans.api.lexer.TokenSequence;
162.62 +import org.netbeans.editor.BaseDocument;
162.63 +import org.netbeans.modules.csl.api.ElementHandle;
162.64 +import org.netbeans.modules.csl.api.ElementKind;
162.65 +import org.netbeans.modules.csl.spi.GsfUtilities;
162.66 +import org.netbeans.modules.csl.spi.ParserResult;
162.67 +import org.netbeans.modules.python.api.PythonMIMEResolver;
162.68 +import org.netbeans.modules.python.source.elements.Element;
162.69 +import org.netbeans.modules.python.source.elements.IndexedElement;
162.70 +import org.netbeans.modules.python.source.elements.IndexedMethod;
162.71 +import org.netbeans.modules.python.source.lexer.PythonTokenId;
162.72 +import org.openide.filesystems.FileObject;
162.73 +import org.openide.util.Exceptions;
162.74 +import org.openide.util.Lookup;
162.75 +import org.openide.xml.XMLUtil;
162.76 +import org.python.antlr.PythonTree;
162.77 +
162.78 +/**
162.79 + * Support for reStructured text. Parse .rst files and rst content in
162.80 + * Python doc strings and format it as HTML. Also provide functions
162.81 + * to locate a code element in RST files.
162.82 + * @see http://www.python.org/dev/peps/pep-0287/
162.83 + * @see http://docutils.sourceforge.net/docs/user/rst/quickstart.html
162.84 + *
162.85 + * @todo Render verbatim blocks
162.86 + * @todo Syntax highlight verbatim blocks?
162.87 + * @todo Render *bold* and `identifier` stuff
162.88 + * @todo For class definitions which nest the method documentation,
162.89 + * try to remove all items, or perhaps just make it shorter
162.90 + * @todo Render note:: into something cleaner etc.
162.91 + *
162.92 + * @author Tor Norbye
162.93 + */
162.94 +public class RstFormatter {
162.95 + private static final String BRBR = "\n<br><br>\n"; // NOI18N
162.96 + private StringBuilder sb = new StringBuilder();
162.97 + private boolean lastWasEmpty = false;
162.98 + private int beginPos;
162.99 + private boolean inVerbatim;
162.100 + private boolean inIndex;
162.101 + private boolean inTable;
162.102 + private boolean inDiv;
162.103 + private int lastIndent;
162.104 + private boolean maybeVerbatim;
162.105 + private boolean inDocTest;
162.106 + private List<String> code;
162.107 +
162.108 + public RstFormatter() {
162.109 + }
162.110 +
162.111 + private void flush() {
162.112 + if (inTable) {
162.113 + sb.append("</pre>\n"); // NOI18N
162.114 + inTable = false;
162.115 + inVerbatim = false;
162.116 + } else if (inVerbatim) {
162.117 + // Process code and format as Python
162.118 + String html = getPythonHtml(code, true);
162.119 + if (html != null) {
162.120 + // <pre> tag is added as part of the rubyhtml (since it
162.121 + // needs to pick up the background color from the syntax
162.122 + // coloring settings)
162.123 + sb.append(html);
162.124 + } else {
162.125 + sb.append("<pre style=\"margin: 5px 5px; background: #ffffdd; border-size: 1px; padding: 5px\">"); // NOI18N
162.126 + sb.append("\n"); // NOI18N
162.127 + // Some kind of error; normal append
162.128 + for (String s : code) {
162.129 + appendEscaped(s);
162.130 + sb.append("<br>"); // NOI18N
162.131 + }
162.132 + sb.append("</pre>\n"); // NOI18N
162.133 + }
162.134 + inVerbatim = false;
162.135 + code = null;
162.136 + } else if (inDiv) {
162.137 + sb.append("</div>\n"); // NOI18N
162.138 + inDiv = false;
162.139 + }
162.140 + }
162.141 +
162.142 + private void appendEscaped(char c) {
162.143 + if ('<' == c) {
162.144 + sb.append("<"); // NOI18N
162.145 + } else if ('&' == c) {
162.146 + sb.append("&"); // NOI18N
162.147 + } else {
162.148 + sb.append(c);
162.149 + }
162.150 + }
162.151 +
162.152 + private void appendEscaped(CharSequence s) {
162.153 + for (int i = 0, n = s.length(); i < n; i++) {
162.154 + char c = s.charAt(i);
162.155 + if ('<' == c) {
162.156 + sb.append("<"); // NOI18N
162.157 + } else if ('&' == c) {
162.158 + sb.append("&"); // NOI18N
162.159 + } else {
162.160 + sb.append(c);
162.161 + }
162.162 + }
162.163 + }
162.164 +
162.165 + private int appendColonCmd(String line, int i, String marker, boolean url) throws CharConversionException {
162.166 + String MARKER = ":" + marker + ":`"; // NOI18N
162.167 + if (line.startsWith(MARKER, i)) {
162.168 + int end = line.indexOf("`", i + MARKER.length()); // NOI18N
162.169 + if (end != -1) {
162.170 + String token = line.substring(i + MARKER.length(), end);
162.171 + if (url) {
162.172 + sb.append("<a href=\""); // NOI18N
162.173 + if ("pep".equals(marker)) { // NOI18N
162.174 + sb.append("http://www.python.org/dev/peps/pep-"); // NOI18N
162.175 + for (int j = 0; j < 4 - token.length(); j++) {
162.176 + sb.append("0");
162.177 + }
162.178 + sb.append(token);
162.179 + sb.append("/"); // NOI18N
162.180 + sb.append("\">PEP "); // NOI18N
162.181 + sb.append(token);
162.182 + sb.append("</a>");
162.183 + return end;
162.184 + } else {
162.185 + sb.append(marker);
162.186 + sb.append(":"); // NOI18N
162.187 + appendEscaped(token);
162.188 + }
162.189 + sb.append("\">"); // NOI18N
162.190 + } else if (marker.equals("keyword")) { // NOI18N
162.191 + sb.append("<code style=\""); // NOI18N
162.192 +
162.193 + MimePath mimePath = MimePath.parse(PythonMIMEResolver.PYTHON_MIME_TYPE);
162.194 + Lookup lookup = MimeLookup.getLookup(mimePath);
162.195 + FontColorSettings fcs = lookup.lookup(FontColorSettings.class);
162.196 +
162.197 + AttributeSet attribs = fcs.getTokenFontColors("keyword"); // NOI18N
162.198 + Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
162.199 + if (fg != null) {
162.200 + sb.append("color:"); // NOI18N
162.201 + sb.append(getHtmlColor(fg));
162.202 + sb.append(";"); // NOI18N
162.203 + }
162.204 + Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
162.205 + // Only set the background for dark colors
162.206 + if (bg != null && bg.getRed() < 128) {
162.207 + sb.append("background:"); // NOI18N
162.208 + sb.append(getHtmlColor(bg));
162.209 + }
162.210 +
162.211 + sb.append("\">"); // NOI18N
162.212 + } else {
162.213 + sb.append("<code>"); // NOI18N
162.214 + }
162.215 + appendEscaped(token);
162.216 + if (url) {
162.217 + sb.append("</a>"); // NOI18N
162.218 + } else {
162.219 + sb.append("</code>"); // NOI18N
162.220 + }
162.221 + //return end+1; // instead of end+2: get to end of ``, minus loop increment
162.222 + return end; // instead of end+2: get to end of ``, minus loop increment
162.223 + }
162.224 + }
162.225 +
162.226 + return -1;
162.227 + }
162.228 +
162.229 + private void appendRstLine(String line) throws CharConversionException {
162.230 + int n = line.length();
162.231 + char prev = 0;
162.232 + Loop:
162.233 + for (int i = 0; i < n; i++) {
162.234 + char c = line.charAt(i);
162.235 + if (c == '`') {
162.236 + if (i < n - 2 && line.charAt(i + 1) == '`') {
162.237 + // See if it's an ``identifier``
162.238 + int end = line.indexOf("``", i + 2);
162.239 + if (end != -1) {
162.240 + sb.append("<code>"); // NOI18N
162.241 + appendEscaped(line.substring(i + 2, end));
162.242 + sb.append("</code>"); // NOI18N
162.243 + i = end + 1; // instead of end+2: get to end of ``, minus loop increment
162.244 + continue;
162.245 + }
162.246 + } else {
162.247 + // Single identifier
162.248 + for (int j = i + 1; j < n; j++) {
162.249 + char d = line.charAt(j);
162.250 + if (d == '`') {
162.251 + sb.append("<code>"); // NOI18N
162.252 + appendEscaped(line.substring(i + 1, j));
162.253 + sb.append("</code>"); // NOI18N
162.254 + i = j;
162.255 + continue Loop;
162.256 + } else if (!Character.isJavaIdentifierPart(d)) {
162.257 + break;
162.258 + }
162.259 + }
162.260 + }
162.261 + } else if (c == ':') {
162.262 + int nextI = appendColonCmd(line, i, "class", true); // NOI18N
162.263 + if (nextI == -1) {
162.264 + nextI = appendColonCmd(line, i, "exc", true); // NOI18N
162.265 + if (nextI == -1) {
162.266 + nextI = appendColonCmd(line, i, "var", false); // NOI18N
162.267 + if (nextI == -1) {
162.268 + nextI = appendColonCmd(line, i, "meth", true); // NOI18N
162.269 + if (nextI == -1) {
162.270 + nextI = appendColonCmd(line, i, "func", true); // NOI18N
162.271 + if (nextI == -1) {
162.272 + nextI = appendColonCmd(line, i, "data", false); // NOI18N
162.273 + if (nextI == -1) {
162.274 + nextI = appendColonCmd(line, i, "attr", false); // NOI18N
162.275 + if (nextI == -1) {
162.276 + nextI = appendColonCmd(line, i, "envvar", false); // NOI18N
162.277 + if (nextI == -1) {
162.278 + nextI = appendColonCmd(line, i, "mod", true); // NOI18N
162.279 + if (nextI == -1) {
162.280 + nextI = appendColonCmd(line, i, "pep", true); // NOI18N
162.281 + if (nextI == -1) {
162.282 + nextI = appendColonCmd(line, i, "ref", false); // NOI18N
162.283 + if (nextI == -1) {
162.284 + nextI = appendColonCmd(line, i, "mod", true); // NOI18N
162.285 + if (nextI == -1) {
162.286 + nextI = appendColonCmd(line, i, "keyword", false); // NOI18N
162.287 + if (nextI == -1) {
162.288 + if (line.startsWith(":noindex:", i)) { // NOI18N
162.289 + nextI = i + 9;
162.290 + } else if (line.startsWith(":synopsis:", i)) { // NOI18N
162.291 + nextI = i + 10;
162.292 + } else if (line.startsWith(":deprecated:", i)) {
162.293 + sb.append("Deprecated. ");
162.294 + nextI = i + 12;
162.295 + } else if (line.startsWith(":platform:", i)) {
162.296 + sb.append("Platform: ");
162.297 + nextI = i + 10;
162.298 + }
162.299 + }
162.300 + }
162.301 + }
162.302 + }
162.303 + }
162.304 + }
162.305 + }
162.306 + }
162.307 + }
162.308 + }
162.309 + }
162.310 + }
162.311 + }
162.312 + if (nextI != -1) {
162.313 + i = nextI;
162.314 + continue;
162.315 + }
162.316 + } else if (c == '*') {
162.317 + // Bold?
162.318 + if (i < n - 1 && Character.isJavaIdentifierPart(line.charAt(i + 1)) && !Character.isJavaIdentifierPart(prev)) { // TODO Use PythonUtils
162.319 + // Peek ahead to see if we have [not-identifier-char]*[identifierchars]*[not-identifier-chars]
162.320 + for (int j = i + 1; j < n; j++) {
162.321 + char d = line.charAt(j);
162.322 + if (d == '*') {
162.323 + if (j == n - 1 || !Character.isJavaIdentifierPart(line.charAt(j + 1))) {
162.324 + // Yess, make bold
162.325 + sb.append("<b>"); // NOI18N
162.326 + appendEscaped(line.substring(i + 1, j));
162.327 + sb.append("</b>"); // NOI18N
162.328 + i = j;
162.329 + continue Loop;
162.330 + }
162.331 + } else if (!Character.isJavaIdentifierPart(d)) {
162.332 + break;
162.333 + }
162.334 + }
162.335 + }
162.336 + } // TODO: :addedin, :deprecated, etc
162.337 +
162.338 + appendEscaped(c);
162.339 + prev = c;
162.340 + }
162.341 + }
162.342 +
162.343 + public void append(String line) {
162.344 + try {
162.345 + String trim = line.trim();
162.346 + if (trim.length() == 0) {
162.347 + inDocTest = false;
162.348 + if (inIndex) {
162.349 + // Completely swallow all indexing entries
162.350 + return;
162.351 + } else if (inTable) {
162.352 + sb.append("</pre>\n"); // NOI18N
162.353 + inVerbatim = false;
162.354 + inTable = false;
162.355 + } else if (inVerbatim) {
162.356 + sb.append("\n"); // NOI18N
162.357 + } else if (!lastWasEmpty && sb.length() > beginPos) {
162.358 + sb.append(BRBR); // NOI18N
162.359 + }
162.360 + lastWasEmpty = true;
162.361 + } else {
162.362 + if (!lastWasEmpty && trim.startsWith("- ")) { // NOI18N
162.363 + // lists - make sure they're on a new line
162.364 + sb.append("<br>"); // NOI18N
162.365 + }
162.366 +
162.367 + lastWasEmpty = false;
162.368 +
162.369 + if (maybeVerbatim) {
162.370 + int indent = getIndentation(line, 0);
162.371 + if (indent > lastIndent) {
162.372 + // Truncate last whitespace separator before <pre> if any
162.373 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
162.374 + sb.setLength(sb.length() - BRBR.length());
162.375 + }
162.376 + inVerbatim = true;
162.377 + code = new ArrayList<>();
162.378 + code.add(line);
162.379 + maybeVerbatim = false;
162.380 + return;
162.381 + }
162.382 + maybeVerbatim = false;
162.383 + } else if (inVerbatim || inTable) {
162.384 + int indent = getIndentation(line, 0);
162.385 + if (indent <= lastIndent) {
162.386 +//// // Truncate trailing whitespace
162.387 +//// while (sb.length() > 0 && sb.charAt(sb.length()-1) == '\n') {
162.388 +//// sb.setLength(sb.length()-1);
162.389 +//// }
162.390 +//// sb.append("</pre>"); // NOI18N
162.391 +// inVerbatim = false;
162.392 +// inTable = false;
162.393 + flush();
162.394 + lastWasEmpty = true;
162.395 + } else if (inVerbatim) {
162.396 + // We need to buffer up the text such that we can lex it as a unit
162.397 + // (and determine when done with the section if it's code or regular text)
162.398 + code.add(line);
162.399 + return;
162.400 + } else {
162.401 + appendEscaped(line);
162.402 + sb.append("\n"); // NOI18N
162.403 + return;
162.404 + }
162.405 + } else if (inDiv) {
162.406 + int indent = getIndentation(line, 0);
162.407 + if (indent <= lastIndent) {
162.408 + // Truncate last whitespace separator before <pre> if any
162.409 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
162.410 + sb.setLength(sb.length() - BRBR.length());
162.411 + }
162.412 + sb.append("</div>\n"); // NOI18N
162.413 + inDiv = false;
162.414 + lastWasEmpty = true;
162.415 + } else {
162.416 + appendRstLine(line);
162.417 + sb.append("\n"); // NOI18N
162.418 + return;
162.419 + }
162.420 + } else if (inIndex) {
162.421 + int indent = getIndentation(line, 0);
162.422 + if (indent <= lastIndent) {
162.423 + inIndex = false;
162.424 + lastWasEmpty = true;
162.425 + } else {
162.426 + return;
162.427 + }
162.428 +
162.429 + }
162.430 +
162.431 + if (trim.startsWith(".. method:: ")) { // NOI18N
162.432 + String sig = trim.substring(12).trim();
162.433 + sb.append("<a href=\"meth:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
162.434 + return;
162.435 + } else if (trim.startsWith(".. function:: ")) { // NOI18N
162.436 + String sig = trim.substring(14).trim();
162.437 + sb.append("<a href=\"func:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
162.438 + return;
162.439 + } else if (trim.startsWith(".. class:: ")) { // NOI18N
162.440 + String sig = trim.substring(11).trim();
162.441 + sb.append("<a href=\"class:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
162.442 + return;
162.443 + } else if (trim.startsWith(".. attribute:: ")) { // NOI18N
162.444 + String sig = trim.substring(15).trim();
162.445 + sb.append("<a href=\"attr:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
162.446 + return;
162.447 + } else if (trim.startsWith(".. data:: ")) { // NOI18N
162.448 + String sig = trim.substring(10).trim();
162.449 + sb.append("<a href=\"data:" + sig.replace("\"", """) + "\">" + sig + "</a>\n"); // NOI18N
162.450 + return;
162.451 + } else if (trim.startsWith(".. module:: ")) { // NOI18N
162.452 + String sig = trim.substring(12).trim();
162.453 + sb.append("<a href=\"module:" + sig.replace("\"", """) + "\">" + sig + "</a>"); // NOI18N
162.454 + sb.append("<br>\n");
162.455 + return;
162.456 + } else if (trim.startsWith(".. productionlist:")) {
162.457 + lastIndent = getIndentation(line, 0);
162.458 + inVerbatim = true;
162.459 + code = new ArrayList<>();
162.460 + code.add(line);
162.461 + maybeVerbatim = false;
162.462 + return;
162.463 + }
162.464 +
162.465 + if (trim.startsWith(">>>") || inDocTest) { // NOI18N
162.466 + if (!trim.startsWith(">>>")) { // NOI18N
162.467 + sb.append("<code>"); // NOI18N
162.468 + appendEscaped(line); // NOI18N
162.469 + // Wait until there is an empty line before we mark doctest done!
162.470 + // inDocTest = false;
162.471 + sb.append("</code><br>"); // NOI18N
162.472 + } else {
162.473 + sb.append("<code>"); // NOI18N
162.474 + appendEscaped(">>>"); // NOI18N
162.475 + String html = getPythonHtml(Collections.singletonList(trim.substring(3)), false);
162.476 + sb.append(html);
162.477 + sb.append("</code>"); // NOI18N
162.478 + inDocTest = true;
162.479 + }
162.480 + return;
162.481 + }
162.482 + inDocTest = false;
162.483 +
162.484 + if (trim.startsWith(".. note::") || trim.startsWith(".. warning::") || trim.startsWith(".. seealso:")) { // NOI18N
162.485 + // Truncate last whitespace separator before <pre> if any
162.486 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
162.487 + sb.setLength(sb.length() - BRBR.length());
162.488 + }
162.489 + sb.append("<div style=\"margin: 5px 5px; "); // NOI18N
162.490 + if (!trim.contains("seealso")) { // NOI18N
162.491 + sb.append("background: #ffdddd; "); // NOI18N
162.492 + } else {
162.493 + sb.append("background: #ddffdd; "); // NOI18N
162.494 + }
162.495 + sb.append("border-size: 1px; padding: 5px\">"); // NOI18N
162.496 + if (trim.contains("note:")) {
162.497 + sb.append("<b>NOTE</b>: "); // NOI18N
162.498 + } else if (trim.contains("warning")) {
162.499 + sb.append("<b>WARNING</b>: "); // NOI18N
162.500 + } else {
162.501 + sb.append("<b>See Also</b>: "); // NOI18N
162.502 + }
162.503 + sb.append("\n"); // NOI18N
162.504 + inDiv = true;
162.505 + lastIndent = getIndentation(line, 0);
162.506 + maybeVerbatim = false;
162.507 + return;
162.508 + } else if (trim.startsWith(".. versionadded::") || trim.startsWith(".. versionchanged::") || trim.startsWith(".. deprecated::")) { // NOI18N
162.509 + // Truncate last whitespace separator before <pre> if any
162.510 + if (sb.length() > BRBR.length() && sb.substring(sb.length() - BRBR.length()).equals(BRBR)) {
162.511 + sb.setLength(sb.length() - BRBR.length());
162.512 + }
162.513 + sb.append("<div style=\"margin: 5px 5px; background: #dddddd; border-size: 1px; padding: 5px\">"); // NOI18N
162.514 + if (trim.contains("added:")) {
162.515 + sb.append("<b>Version Added</b>: "); // NOI18N
162.516 + } else if (trim.contains("changed")) {
162.517 + sb.append("<b>Version Changed</b>: "); // NOI18N
162.518 + } else {
162.519 + assert trim.contains("deprecated"); // NOI18N
162.520 + sb.append("<b>Deprecated</b>: "); // NOI18N
162.521 + }
162.522 + sb.append(trim.substring(trim.indexOf("::") + 2));
162.523 + sb.append("\n"); // NOI18N
162.524 + inDiv = true;
162.525 + lastIndent = getIndentation(line, 0);
162.526 + maybeVerbatim = false;
162.527 + return;
162.528 + } else if (trim.startsWith(".. index:")) { // NOI18N
162.529 + inIndex = true;
162.530 + lastIndent = getIndentation(line, 0);
162.531 + return;
162.532 + } else if (trim.startsWith(".. _") && trim.endsWith(":")) {
162.533 + // skip lines like .. _pyzipfile-objects:
162.534 + return;
162.535 + } else if (trim.startsWith(".. moduleauthor::") || trim.startsWith(".. sectionauthor::")) { // NOI18N
162.536 + if (trim.startsWith(".. mod")) {
162.537 + sb.append("<br>Module Author:</b>");
162.538 + } else {
162.539 + sb.append("<br>Section Author:</b>");
162.540 + }
162.541 + appendEscaped(trim.substring(trim.indexOf("::") + 2)); //
162.542 + sb.append("\n");
162.543 + return;
162.544 + } else if (trim.endsWith("::")) { // NOI18N
162.545 + maybeVerbatim = true;
162.546 + lastIndent = getIndentation(line, 0);
162.547 + } else if (trim.startsWith("+-----")) { // NOI18N
162.548 + // A table
162.549 + sb.append("<pre>"); // NOI18N
162.550 + appendEscaped(line);
162.551 + sb.append("\n"); // NOI18N
162.552 + inTable = true;
162.553 + lastIndent = getIndentation(line, 0) - 1;
162.554 + return;
162.555 + } else if (line.startsWith("======") || line.startsWith("------") || line.startsWith("******") || line.startsWith("^^^^^^^^")) { // NOI18N
162.556 + // PREVIOUS line could be a title.
162.557 + // Note -- we're comparing on "line" and not "trim" here because in indented contexts,
162.558 + // === sometimes represents parts of tables -- see the turtle.rst file for examples.
162.559 +
162.560 + int n = sb.length();
162.561 + if (n > 0 && sb.charAt(n - 1) == '\n') {
162.562 + n--;
162.563 + }
162.564 + int index = n - 1;
162.565 + for (; index >= 0; index--) {
162.566 + char c = sb.charAt(index);
162.567 + if (c == '\n') {
162.568 + index++;
162.569 + break;
162.570 + }
162.571 + }
162.572 + if (index == -1) {
162.573 + index = 0;
162.574 + }
162.575 + // Index now points to the beginning of the previous line
162.576 + boolean empty = true;
162.577 +// boolean okay = true;
162.578 + int start = index;
162.579 + for (; index < n; index++) {
162.580 + char c = sb.charAt(index);
162.581 + if (c == '\n') {
162.582 + break;
162.583 + }
162.584 + empty = false;
162.585 +// if (c == '<') {
162.586 +// okay = false;
162.587 +// }
162.588 + }
162.589 + if (!empty/* && okay*/) {
162.590 + String tag = "h2"; // NOI18N
162.591 + if (line.startsWith("-") || line.startsWith("^")) { // NOI18N
162.592 + tag = "h3"; // NOI18N
162.593 + }
162.594 + sb.insert(start, "<" + tag + ">"); // NOI18N
162.595 + sb.append("</" + tag + ">\n"); // NOI18N
162.596 + lastWasEmpty = true;
162.597 + return;
162.598 + }
162.599 + }
162.600 +
162.601 + //sb.append(line);
162.602 + appendRstLine(line);
162.603 +
162.604 + sb.append("\n"); // NOI18N
162.605 + }
162.606 + } catch (CharConversionException ex) {
162.607 + Exceptions.printStackTrace(ex);
162.608 + }
162.609 + }
162.610 +
162.611 + public void appendSignature(Element element) {
162.612 + sb.append("<pre>"); // NOI18N
162.613 +
162.614 + if (element instanceof IndexedMethod) {
162.615 + IndexedMethod executable = (IndexedMethod)element;
162.616 + if (element.getIn() != null && !PythonIndex.isBuiltinModule(element.getIn())) {
162.617 + String in = element.getIn();
162.618 + sb.append("<i>"); // NOI18N
162.619 + sb.append(in);
162.620 + sb.append("</i>"); // NOI18N
162.621 + sb.append("<br>"); // NOI18N
162.622 + }
162.623 + // TODO - share this between Navigator implementation and here...
162.624 + sb.append("<b>"); // NOI18N
162.625 + sb.append(element.getName());
162.626 + sb.append("</b>"); // NOI18N
162.627 + String[] parameters = executable.getParams();
162.628 +
162.629 + if ((parameters != null) && (parameters.length > 0)) {
162.630 + sb.append("("); // NOI18N
162.631 +
162.632 + sb.append("<font color=\"#808080\">"); // NOI18N
162.633 +
162.634 + boolean first = true;
162.635 + for (String parameter : parameters) {
162.636 + if (first) {
162.637 + first = false;
162.638 + } else {
162.639 + sb.append(", ");
162.640 + }
162.641 + sb.append(parameter);
162.642 + }
162.643 +
162.644 + sb.append("</font>"); // NOI18N
162.645 +
162.646 + sb.append(")"); // NOI18N
162.647 + }
162.648 + } else if (element instanceof IndexedElement) {
162.649 + //IndexedElement clz = (IndexedElement)element;
162.650 + String name = element.getName();
162.651 +// final String fqn = clz.getFqn();
162.652 +// if (fqn != null && !name.equals(fqn)) {
162.653 +// signature.append("<i>"); // NOI18N
162.654 +// signature.append(fqn); // NOI18N
162.655 +// signature.append("</i>"); // NOI18N
162.656 +// signature.append("<br>"); // NOI18N
162.657 +// }
162.658 + sb.append("<b>"); // NOI18N
162.659 + sb.append(name);
162.660 + sb.append("</b>"); // NOI18N
162.661 + } else {
162.662 + sb.append(element.getName());
162.663 + }
162.664 +
162.665 + sb.append("</pre>\n"); // NOI18N
162.666 + }
162.667 +
162.668 + public void appendHtml(String html) {
162.669 + sb.append(html);
162.670 + }
162.671 +
162.672 + public void markEmpty() {
162.673 + beginPos = sb.length();
162.674 + }
162.675 +
162.676 + public String toHtml() {
162.677 + flush();
162.678 + return sb.toString();
162.679 + }
162.680 +
162.681 + public static String document(String rst) {
162.682 + RstFormatter formatter = new RstFormatter();
162.683 + String[] lines = rst.split("\n"); // NOI18N
162.684 + for (String line : lines) {
162.685 + formatter.append(line);
162.686 + }
162.687 + return formatter.toHtml();
162.688 + }
162.689 +
162.690 + public static String getDocumentation(IndexedElement indexedElement) {
162.691 + RstFormatter formatter = new RstFormatter();
162.692 + FileObject fileObject = indexedElement.getFileObject();
162.693 + if (fileObject == null) {
162.694 + return null;
162.695 + }
162.696 + BaseDocument document = GsfUtilities.getDocument(fileObject, true);
162.697 + if (document == null) {
162.698 + return null;
162.699 + }
162.700 +
162.701 + String[] signatureHolder = new String[1];
162.702 + String rst = formatter.extractRst(indexedElement, document, signatureHolder);
162.703 + if (rst != null && rst.length() > 0) {
162.704 + String signature = signatureHolder[0];
162.705 + if (signature == null) {
162.706 + formatter.appendSignature(indexedElement);
162.707 + formatter.appendHtml("\n<hr>\n"); // NOI18N
162.708 + formatter.markEmpty();
162.709 + } else {
162.710 + formatter.appendHtml("<pre>"); // NOI18N
162.711 + formatter.appendHtml("<b>"); // NOI18N
162.712 + int paren = signature.indexOf('(');
162.713 + if (paren != -1) {
162.714 + formatter.appendHtml(signature.substring(0, paren));
162.715 + formatter.appendHtml("</b>"); // NOI18N
162.716 + formatter.appendHtml("<font color=\"#808080\">"); // NOI18N
162.717 + formatter.appendHtml(signature.substring(paren));
162.718 + formatter.appendHtml("</font>"); // NOI18N
162.719 + } else {
162.720 + formatter.appendHtml(signature);
162.721 + formatter.appendHtml("()"); // NOI18N
162.722 + formatter.appendHtml("</b>"); // NOI18N
162.723 + }
162.724 + formatter.appendHtml("</pre>"); // NOI18N
162.725 + formatter.appendHtml("\n<hr>\n"); // NOI18N
162.726 + formatter.markEmpty();
162.727 + }
162.728 +
162.729 + String[] lines = rst.split("\n"); // NOI18N
162.730 + for (String line : lines) {
162.731 + formatter.append(line);
162.732 + }
162.733 + return formatter.toHtml();
162.734 + }
162.735 +
162.736 + return null;
162.737 + }
162.738 +
162.739 + /**
162.740 + * Find the reStructured text for the documentation for the given element
162.741 + * in the given RST document
162.742 + * @param indexedElement
162.743 + * @param document
162.744 + * @return
162.745 + */
162.746 + private String extractRst(IndexedElement element, BaseDocument doc, String[] signatureHolder) {
162.747 + return extractRst(element.getName(), element.getClz(), element.getKind(), doc, signatureHolder);
162.748 + }
162.749 +
162.750 + String extractRst(String name, String clz, ElementKind kind, BaseDocument doc, String[] signatureHolder) {
162.751 + try {
162.752 + String text = doc.getText(0, doc.getLength());
162.753 + // What about functions?
162.754 + if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
162.755 + int offset = findElementMatch(text, "function::", name, true); // NOI18N
162.756 + if (offset == -1) {
162.757 + offset = findElementMatch(text, "method::", name, false); // NOI18N
162.758 + if (offset == -1 && kind == ElementKind.CONSTRUCTOR) {
162.759 + offset = findElementMatch(text, "class::", name, false); // NOI18N
162.760 + if (offset == -1 && clz != null && clz.length() > 0 && "__init__".equals(name)) { // NOI18N
162.761 + offset = findElementMatch(text, "method::", clz, false); // NOI18N
162.762 + if (offset == -1) {
162.763 + offset = findElementMatch(text, "class::", clz, false); // NOI18N
162.764 + }
162.765 + }
162.766 + }
162.767 + }
162.768 + if (offset != -1) {
162.769 + int end = findElementEnd(text, offset);
162.770 + int nextLine = getNextLineOffset(text, offset);
162.771 + if (nextLine < end) {
162.772 + if (signatureHolder != null) {
162.773 + String signature = text.substring(text.indexOf("::", offset) + 2, nextLine).trim(); // NOI18N
162.774 + signatureHolder[0] = signature;
162.775 + }
162.776 + return text.substring(nextLine, end);
162.777 + }
162.778 + }
162.779 + } else if (kind == ElementKind.CLASS) {
162.780 + int offset = findElementMatch(text, "class::", name, false); // NOI18N
162.781 + if (offset == -1) {
162.782 + offset = findElementMatch(text, "exception::", name, false); // NOI18N
162.783 + }
162.784 + if (offset != -1) {
162.785 + int end = findElementEnd(text, offset);
162.786 + int nextLine = getNextLineOffset(text, offset);
162.787 + if (nextLine < end) {
162.788 + String elementText = text.substring(nextLine, end);
162.789 + return elementText;
162.790 + }
162.791 + }
162.792 + } else if (kind == ElementKind.MODULE) {
162.793 + int offset = findElementMatch(text, "module::", name, false); // NOI18N
162.794 + if (offset == -1) {
162.795 + offset = findElementMatch(text, "currentmodule::", name, false); // NOI18N
162.796 + }
162.797 + if (offset != -1) {
162.798 + int end = findElementEnd(text, offset);
162.799 + int nextLine = getNextLineOffset(text, offset);
162.800 + if (nextLine < end) {
162.801 + String elementText = text.substring(nextLine, end);
162.802 + return elementText;
162.803 + }
162.804 + }
162.805 + } else {
162.806 +// assert kind == ElementKind.ATTRIBUTE :;
162.807 + int offset = findElementMatch(text, "data::", name, true); // NOI18N
162.808 + if (offset == -1) {
162.809 + offset = findElementMatch(text, "attribute::", name, false); // NOI18N
162.810 + }
162.811 + if (offset != -1) {
162.812 + int end = findElementEnd(text, offset);
162.813 + int nextLine = getNextLineOffset(text, offset);
162.814 + if (nextLine < end) {
162.815 + String elementText = text.substring(nextLine, end);
162.816 + return elementText;
162.817 + }
162.818 + }
162.819 + }
162.820 + } catch (BadLocationException ex) {
162.821 + Exceptions.printStackTrace(ex);
162.822 + return "";
162.823 + }
162.824 +
162.825 +// while (true) {
162.826 +// try {
162.827 +// int ret = doc.find(new FinderFactory.StringFwdFinder(".. " + key + "::", true), offset, -1);
162.828 +// if (ret == -1) {
162.829 +// break;
162.830 +// }
162.831 +// } catch (BadLocationException ex) {
162.832 +// Exceptions.printStackTrace(ex);
162.833 +// }
162.834 +// }
162.835 +
162.836 +
162.837 + return "";
162.838 + }
162.839 +
162.840 + public static int getIndentation(String text, int lineBegin) {
162.841 + for (int i = lineBegin; i < text.length(); i++) {
162.842 + char c = text.charAt(i);
162.843 + if (c == '\n') {
162.844 + // Empty lines don't count
162.845 + return -1;
162.846 + }
162.847 + if (!Character.isWhitespace(c)) {
162.848 + // Doesn't quite work for tabs etc. but those aren't
162.849 + // really used in rst files... Fix when I switch to
162.850 + // direct document iteration
162.851 + return i - lineBegin;
162.852 + }
162.853 + }
162.854 +
162.855 + return -1;
162.856 + }
162.857 +
162.858 + public static int getNextLineOffset(String text, int offset) {
162.859 + int index = text.indexOf('\n', offset);
162.860 + if (index == -1) {
162.861 + return -1;
162.862 + } else {
162.863 + return index + 1;
162.864 + }
162.865 + }
162.866 +
162.867 + public static int findElementEnd(String text, int offset) {
162.868 + // Find beginning of line
162.869 + int lineBegin = 0;
162.870 + for (int i = offset; i > 0; i--) {
162.871 + char c = text.charAt(i);
162.872 + if (c == '\n') {
162.873 + lineBegin = i + 1;
162.874 + break;
162.875 + }
162.876 + }
162.877 +
162.878 + // Compute indentation of the ..
162.879 + int firstIndent = getIndentation(text, lineBegin);
162.880 + offset = getNextLineOffset(text, lineBegin);
162.881 + while (true) {
162.882 + offset = getNextLineOffset(text, offset);
162.883 + if (offset == -1) {
162.884 + return text.length();
162.885 + }
162.886 + int indent = getIndentation(text, offset);
162.887 + if (indent == -1) {
162.888 + // Empty line - doesn't count
162.889 + continue;
162.890 + } else if (indent <= firstIndent) {
162.891 + return offset;
162.892 + }
162.893 + }
162.894 + }
162.895 +
162.896 + public static int findElementMatch(String text, String key, String name, boolean checkAdjacentLines) {
162.897 + int nameLength = name.length();
162.898 + int offset = 0;
162.899 + int keyLength = key.length();
162.900 + while (true) {
162.901 + int next = text.indexOf(key, offset);
162.902 + if (next == -1) {
162.903 + break;
162.904 + }
162.905 + offset = next + keyLength;
162.906 +
162.907 + int lineEnd = text.indexOf('\n', offset);
162.908 + if (lineEnd == -1) {
162.909 + lineEnd = text.length(); // on last line with no crlf at the end
162.910 + }
162.911 +
162.912 + // Skip whitespace
162.913 + for (; offset < lineEnd; offset++) {
162.914 + char c = text.charAt(offset);
162.915 + if (c != ' ') {
162.916 + break;
162.917 + }
162.918 + }
162.919 +
162.920 + int nameBegin = offset;
162.921 + int nameEnd = -1;
162.922 +
162.923 + // Pick out the bame
162.924 + for (int i = offset; i < lineEnd; i++) {
162.925 + char c = text.charAt(i);
162.926 + if (c == '(' || c == ' ') {
162.927 + nameEnd = i;
162.928 + break;
162.929 + } else if (c == '.') {
162.930 + nameBegin = i + 1;
162.931 + }
162.932 + }
162.933 + if (nameEnd == -1) {
162.934 + nameEnd = lineEnd;
162.935 + }
162.936 +
162.937 +
162.938 + if (nameEnd - nameBegin == nameLength &&
162.939 + text.regionMatches(nameBegin, name, 0, nameLength)) {
162.940 + // TODO - validate the arguments list?
162.941 + return next;
162.942 + }
162.943 +
162.944 + // Look on subsequent lines too - we sometimes have adjacent lines
162.945 + // with additional signatures
162.946 + if (checkAdjacentLines) {
162.947 + while (true) {
162.948 + int lineBegin = lineEnd+1;
162.949 + if (lineBegin >= text.length()) {
162.950 + break;
162.951 + }
162.952 +
162.953 + lineEnd = text.indexOf('\n', lineBegin);
162.954 + if (lineEnd == -1) {
162.955 + lineEnd = text.length(); // on last line with no crlf at the end
162.956 + }
162.957 +
162.958 + while (lineBegin < lineEnd) {
162.959 + char c = text.charAt(lineBegin);
162.960 + if (!Character.isWhitespace(c)) {
162.961 + break;
162.962 + }
162.963 + lineBegin++;
162.964 + }
162.965 +
162.966 + while (lineEnd > lineBegin) {
162.967 + char c = text.charAt(lineEnd-1);
162.968 + if (!Character.isWhitespace(c)) {
162.969 + break;
162.970 + }
162.971 + lineEnd--;
162.972 + }
162.973 +
162.974 + if (lineEnd <= lineBegin) {
162.975 + break;
162.976 + }
162.977 +
162.978 + nameBegin = lineBegin;
162.979 + nameEnd = -1;
162.980 +
162.981 + // Pick out the name
162.982 + for (int i = lineBegin; i < lineEnd; i++) {
162.983 + char c = text.charAt(i);
162.984 + if (c == '(' || c == ' ') {
162.985 + nameEnd = i;
162.986 + break;
162.987 + } else if (c == '.') {
162.988 + nameBegin = i + 1;
162.989 + }
162.990 + }
162.991 + if (nameEnd == -1) {
162.992 + nameEnd = lineEnd;
162.993 + }
162.994 +
162.995 + if (nameEnd - nameBegin == nameLength &&
162.996 + text.regionMatches(nameBegin, name, 0, nameLength)) {
162.997 + // TODO - validate the arguments list?
162.998 + return next;
162.999 + }
162.1000 + }
162.1001 + }
162.1002 +
162.1003 + }
162.1004 +
162.1005 + return -1;
162.1006 + }
162.1007 +
162.1008 + public static String document(ParserResult info, ElementHandle element) {
162.1009 + if (element instanceof IndexedElement) {
162.1010 + IndexedElement indexedElement = (IndexedElement)element;
162.1011 +
162.1012 + FileObject fo = indexedElement.getFileObject();
162.1013 +
162.1014 + if (fo == null) {
162.1015 + return null;
162.1016 + }
162.1017 +
162.1018 + if (PythonUtils.isRstFile(fo)) {
162.1019 + return getDocumentation(indexedElement);
162.1020 + }
162.1021 +
162.1022 +
162.1023 + PythonTree node = indexedElement.getNode();
162.1024 + if (node != null) {
162.1025 + return document(info, node, indexedElement);
162.1026 + }
162.1027 + }
162.1028 + return null;
162.1029 + }
162.1030 +
162.1031 + public static String document(ParserResult info, PythonTree node, IndexedElement element) {
162.1032 + if (node != null) {
162.1033 + String doc = PythonAstUtils.getDocumentation(node);
162.1034 + if (doc != null) {
162.1035 + // Honor empty lines: paragraphs
162.1036 + RstFormatter formatter = new RstFormatter();
162.1037 + if (element != null) {
162.1038 + formatter.appendSignature(element);
162.1039 + }
162.1040 + if (doc.indexOf('\n') != -1) {
162.1041 + formatter.appendHtml("\n<hr>\n"); // NOI18N
162.1042 + formatter.markEmpty();
162.1043 + String[] lines = doc.split("\n"); // NOI18N
162.1044 + for (String line : lines) {
162.1045 + formatter.append(line);
162.1046 + }
162.1047 + } else if (doc.length() > 0) {
162.1048 + formatter.appendHtml("\n<hr>\n"); // NOI18N
162.1049 + formatter.markEmpty();
162.1050 + formatter.append(doc);
162.1051 + }
162.1052 +
162.1053 + return formatter.toHtml();
162.1054 + }
162.1055 + }
162.1056 +
162.1057 + return null;
162.1058 + }
162.1059 +
162.1060 + public static String getSignature(Element element) {
162.1061 + StringBuilder signature = new StringBuilder();
162.1062 + // TODO:
162.1063 + signature.append("<pre>"); // NOI18N
162.1064 +
162.1065 + if (element instanceof IndexedMethod) {
162.1066 + IndexedMethod executable = (IndexedMethod)element;
162.1067 + if (element.getIn() != null) {
162.1068 + String in = element.getIn();
162.1069 + signature.append("<i>"); // NOI18N
162.1070 + signature.append(in);
162.1071 + signature.append("</i>"); // NOI18N
162.1072 + signature.append("<br>"); // NOI18N
162.1073 + }
162.1074 + // TODO - share this between Navigator implementation and here...
162.1075 + signature.append("<b>"); // NOI18N
162.1076 + signature.append(element.getName());
162.1077 + signature.append("</b>"); // NOI18N
162.1078 + String[] parameters = executable.getParams();
162.1079 +
162.1080 + if ((parameters != null) && (parameters.length > 0)) {
162.1081 + signature.append("("); // NOI18N
162.1082 +
162.1083 + signature.append("<font color=\"#808080\">"); // NOI18N
162.1084 +
162.1085 + boolean first = true;
162.1086 + for (String parameter : parameters) {
162.1087 + if (first) {
162.1088 + first = false;
162.1089 + } else {
162.1090 + signature.append(", "); // NOI18N
162.1091 + }
162.1092 + signature.append(parameter);
162.1093 + }
162.1094 +
162.1095 + signature.append("</font>"); // NOI18N
162.1096 +
162.1097 + signature.append(")"); // NOI18N
162.1098 + }
162.1099 + } else if (element instanceof IndexedElement) {
162.1100 +// IndexedElement clz = (IndexedElement)element;
162.1101 + String name = element.getName();
162.1102 +// final String fqn = clz.getFqn();
162.1103 +// if (fqn != null && !name.equals(fqn)) {
162.1104 +// signature.append("<i>"); // NOI18N
162.1105 +// signature.append(fqn); // NOI18N
162.1106 +// signature.append("</i>"); // NOI18N
162.1107 +// signature.append("<br>"); // NOI18N
162.1108 +// }
162.1109 + signature.append("<b>"); // NOI18N
162.1110 + signature.append(name);
162.1111 + signature.append("</b>"); // NOI18N
162.1112 + } else {
162.1113 + signature.append(element.getName());
162.1114 + }
162.1115 +
162.1116 + signature.append("</pre>\n"); // NOI18N
162.1117 +
162.1118 + return signature.toString();
162.1119 + }
162.1120 +
162.1121 + @SuppressWarnings("unchecked")
162.1122 + private String getPythonHtml(List<String> source, boolean addPre) {
162.1123 + StringBuilder python = new StringBuilder(500);
162.1124 +
162.1125 + for (String s : source) {
162.1126 + python.append(s);
162.1127 + python.append("\n"); // NOI18N
162.1128 + }
162.1129 +
162.1130 + Language<?> language = PythonTokenId.language();
162.1131 + String mimeType = PythonMIMEResolver.PYTHON_MIME_TYPE;
162.1132 + // TODO - handle YAML and other languages I can see in the documentation...
162.1133 + /*if (python.indexOf(" <%") != -1) { // NOI18N
162.1134 + mimeType = "application/x-httpd-eruby"; // RHTML
162.1135 + Collection<LanguageProvider> providers = (Collection<LanguageProvider>) Lookup.getDefault().lookupAll(LanguageProvider.class);
162.1136 + for (LanguageProvider provider : providers) {
162.1137 + language = provider.findLanguage(mimeType);
162.1138 + if (language != null) {
162.1139 + break;
162.1140 + }
162.1141 + }
162.1142 +
162.1143 + if (language == null) {
162.1144 + mimeType = PythonTokenId.PYTHON_MIME_TYPE;
162.1145 + language = PythonTokenId.language();
162.1146 + }
162.1147 + } else*/ if (source.get(0).trim().startsWith("<")) {
162.1148 + // Looks like markup (other than RHTML) - don't colorize it
162.1149 + // since we don't know how
162.1150 + return null;
162.1151 + }
162.1152 +
162.1153 + StringBuilder buffer = new StringBuilder(1500);
162.1154 +
162.1155 + boolean errors = appendSequence(buffer, python.toString(), language, mimeType, addPre);
162.1156 + return errors ? null : buffer.toString();
162.1157 + }
162.1158 +
162.1159 + @SuppressWarnings("unchecked")
162.1160 + private boolean appendSequence(StringBuilder sb, String text,
162.1161 + Language<?> language, String mimeType, boolean addPre) {
162.1162 + // XXX is this getting called twice?
162.1163 + MimePath mimePath = MimePath.parse(mimeType);
162.1164 + Lookup lookup = MimeLookup.getLookup(mimePath);
162.1165 + FontColorSettings fcs = lookup.lookup(FontColorSettings.class);
162.1166 +
162.1167 + if (addPre) {
162.1168 + sb.append("<pre style=\""); // NOI18N
162.1169 +
162.1170 + sb.append("border-color: #dddddd; border-style: solid; border-width: 1px; ");
162.1171 +
162.1172 + AttributeSet attribs = fcs.getTokenFontColors("default"); // NOI18N
162.1173 + Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
162.1174 + if (fg != null) {
162.1175 + sb.append("color:"); // NOI18N
162.1176 + sb.append(getHtmlColor(fg));
162.1177 + sb.append(";"); // NOI18N
162.1178 + }
162.1179 + Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
162.1180 + // Only set the background for dark colors
162.1181 + if (bg != null && bg.getRed() < 128) {
162.1182 + sb.append("background:"); // NOI18N
162.1183 + sb.append(getHtmlColor(bg));
162.1184 + }
162.1185 +
162.1186 + sb.append("\">\n"); // NOI18N
162.1187 + }
162.1188 + TokenHierarchy hi = TokenHierarchy.create(text, language);
162.1189 + TokenSequence ts = hi.tokenSequence();
162.1190 +
162.1191 + int offset = 0;
162.1192 + ts.move(offset);
162.1193 +
162.1194 + if (ts.moveNext()) {
162.1195 + do {
162.1196 + Token t = ts.token();
162.1197 + String tokenText = t.text().toString();
162.1198 +
162.1199 + // TODO - make style classes instead of inlining everything as font!
162.1200 + String category = t.id().name();
162.1201 + String primaryCategory = t.id().primaryCategory();
162.1202 +
162.1203 + if ("error".equals(primaryCategory)) { // NOI18N
162.1204 + // Abort: an error token means the output probably isn't
162.1205 + // code, or it's code or markup but in a different language
162.1206 + // than we're trying to process it as
162.1207 + return true;
162.1208 + }
162.1209 +
162.1210 + AttributeSet attribs = fcs.getTokenFontColors(category);
162.1211 + String escapedText = tokenText;
162.1212 + try {
162.1213 + escapedText = XMLUtil.toElementContent(tokenText);
162.1214 + } catch (CharConversionException cce) {
162.1215 + Exceptions.printStackTrace(cce);
162.1216 + }
162.1217 +
162.1218 + if (attribs == null) {
162.1219 + category = primaryCategory;
162.1220 + attribs = fcs.getTokenFontColors(category);
162.1221 +
162.1222 + }
162.1223 +
162.1224 + TokenSequence embedded = ts.embedded();
162.1225 + if (embedded != null) {
162.1226 + //embedded.languagePath().mimePath();
162.1227 + String embeddedMimeType = MimePath.parse(embedded.languagePath().mimePath()).getPath();
162.1228 + Color bg = null;
162.1229 + Color fg = null;
162.1230 + if (attribs != null) {
162.1231 + bg = (Color)attribs.getAttribute(StyleConstants.Background);
162.1232 + fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
162.1233 + if (fg != null || bg != null) {
162.1234 + sb.append("<span style=\"");
162.1235 + if (bg != null) {
162.1236 + sb.append("background:"); // NOI18N
162.1237 + sb.append(getHtmlColor(bg));
162.1238 + sb.append(";");
162.1239 + }
162.1240 + if (fg != null) {
162.1241 + sb.append("color:"); // NOI18N
162.1242 + sb.append(getHtmlColor(fg));
162.1243 + }
162.1244 + sb.append("\">"); // NOI18N
162.1245 + }
162.1246 + }
162.1247 + appendSequence(sb, tokenText, embedded.language(), embeddedMimeType, false);
162.1248 + if (fg != null || bg != null) {
162.1249 + sb.append("</span>"); // NOI18N
162.1250 + }
162.1251 + continue;
162.1252 + }
162.1253 +
162.1254 + if (attribs == null) {
162.1255 + sb.append(escapedText);
162.1256 +
162.1257 + continue;
162.1258 + }
162.1259 +
162.1260 + if (escapedText.indexOf('\n') != -1) {
162.1261 + escapedText = escapedText.replace("\n", "<br>"); // NOI18N
162.1262 + }
162.1263 +
162.1264 + if (t.id() == PythonTokenId.WHITESPACE) {
162.1265 + sb.append(escapedText);
162.1266 + } else {
162.1267 + sb.append("<span style=\""); // NOI18N
162.1268 +
162.1269 + Color fg = (Color)attribs.getAttribute(StyleConstants.Foreground);
162.1270 +
162.1271 + if (fg != null) {
162.1272 + sb.append("color:"); // NOI18N
162.1273 + sb.append(getHtmlColor(fg));
162.1274 + sb.append(";"); // NOI18N
162.1275 + }
162.1276 +
162.1277 + Color bg = (Color)attribs.getAttribute(StyleConstants.Background);
162.1278 +
162.1279 + if (bg != null) {
162.1280 + sb.append("background:"); // NOI18N
162.1281 + sb.append(getHtmlColor(bg));
162.1282 + sb.append(";"); // NOI18NP
162.1283 + }
162.1284 +
162.1285 + Boolean b = (Boolean)attribs.getAttribute(StyleConstants.Bold);
162.1286 +
162.1287 + if ((b != null) && b) {
162.1288 + sb.append("font-weight:bold;"); // NOI18N
162.1289 + }
162.1290 +
162.1291 + b = (Boolean)attribs.getAttribute(StyleConstants.Italic);
162.1292 +
162.1293 + if ((b != null) && b) {
162.1294 + sb.append("font-style:italic;"); // NOI18N
162.1295 + }
162.1296 +
162.1297 + // TODO - underline, strikethrough, ... and FONTS!
162.1298 + sb.append("\">"); // NOI18N
162.1299 + sb.append(escapedText);
162.1300 + sb.append("</span>"); // NOI18N
162.1301 + }
162.1302 + } while (ts.moveNext());
162.1303 + }
162.1304 +
162.1305 + if (addPre) {
162.1306 + sb.append("</pre>\n");
162.1307 + }
162.1308 +
162.1309 + return false;
162.1310 + }
162.1311 +
162.1312 +
162.1313 + // TODO - move to GsfUtilities?
162.1314 + private static String getHtmlColor(Color c) {
162.1315 + int r = c.getRed();
162.1316 + int g = c.getGreen();
162.1317 + int b = c.getBlue();
162.1318 + StringBuffer result = new StringBuffer();
162.1319 + result.append('#');
162.1320 +
162.1321 + String rs = Integer.toHexString(r);
162.1322 + String gs = Integer.toHexString(g);
162.1323 + String bs = Integer.toHexString(b);
162.1324 +
162.1325 + if (r < 0x10) {
162.1326 + result.append('0');
162.1327 + }
162.1328 +
162.1329 + result.append(rs);
162.1330 +
162.1331 + if (g < 0x10) {
162.1332 + result.append('0');
162.1333 + }
162.1334 +
162.1335 + result.append(gs);
162.1336 +
162.1337 + if (b < 0x10) {
162.1338 + result.append('0');
162.1339 + }
162.1340 +
162.1341 + result.append(bs);
162.1342 +
162.1343 + return result.toString();
162.1344 + }
162.1345 +}
163.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
163.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/AstElement.java Wed Sep 02 20:31:18 2015 +0200
163.3 @@ -0,0 +1,117 @@
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.elements;
163.35 +
163.36 +import java.util.Set;
163.37 +import org.netbeans.modules.csl.api.ElementKind;
163.38 +import org.netbeans.modules.csl.api.Modifier;
163.39 +import org.netbeans.modules.csl.api.OffsetRange;
163.40 +import org.netbeans.modules.csl.spi.ParserResult;
163.41 +import org.netbeans.modules.python.source.PythonAstUtils;
163.42 +import org.netbeans.modules.python.source.PythonParserResult;
163.43 +import org.netbeans.modules.python.source.PythonStructureItem;
163.44 +import org.netbeans.modules.python.source.PythonStructureScanner;
163.45 +import org.netbeans.modules.python.source.scopes.SymbolTable;
163.46 +import org.python.antlr.PythonTree;
163.47 +import org.python.antlr.ast.Call;
163.48 +import org.python.antlr.ast.ClassDef;
163.49 +import org.python.antlr.ast.FunctionDef;
163.50 +import org.python.antlr.ast.Name;
163.51 +
163.52 +/**
163.53 + * Elements representing a node in a parse tree
163.54 + *
163.55 + * @author Tor Norbye
163.56 + */
163.57 +public class AstElement extends Element {
163.58 + protected PythonTree node;
163.59 + protected String name;
163.60 + protected ElementKind kind;
163.61 + //protected CompilationInfo info;
163.62 + protected Set<Modifier> modifiers;
163.63 + protected SymbolTable scopes;
163.64 +
163.65 + public AstElement(SymbolTable scopes, PythonTree node, String name, ElementKind kind) {
163.66 + //this.info = info;
163.67 + this.scopes = scopes;
163.68 + this.node = node;
163.69 + this.name = name;
163.70 + this.kind = kind;
163.71 + }
163.72 +
163.73 + public static AstElement create(PythonParserResult result, PythonTree node) {
163.74 + SymbolTable scopes = result.getSymbolTable();
163.75 +
163.76 + if (node instanceof FunctionDef) {
163.77 + return new PythonStructureItem(scopes, (FunctionDef)node);
163.78 + } else if (node instanceof ClassDef) {
163.79 + return new PythonStructureItem(scopes, (ClassDef)node);
163.80 + } else if (node instanceof Call) {
163.81 + String name = PythonAstUtils.getCallName((Call)node);
163.82 + return new AstElement(scopes, node, name, ElementKind.METHOD);
163.83 + } else if (node instanceof Name) {
163.84 + return new AstElement(scopes, node, ((Name)node).getInternalId(), ElementKind.VARIABLE);
163.85 + } else {
163.86 + return new AstElement(scopes, node, null, ElementKind.OTHER);
163.87 + }
163.88 + }
163.89 +
163.90 + public PythonTree getNode() {
163.91 + return node;
163.92 + }
163.93 +
163.94 + @Override
163.95 + public String getName() {
163.96 + return name;
163.97 + }
163.98 +
163.99 + @Override
163.100 + public ElementKind getKind() {
163.101 + return kind;
163.102 + }
163.103 +
163.104 + @Override
163.105 + public Set<Modifier> getModifiers() {
163.106 + if (modifiers == null) {
163.107 + if (name != null && scopes.isPrivate(node, name)) {
163.108 + modifiers = IndexedElement.PRIVATE_MODIFIERS;
163.109 + } else {
163.110 + modifiers = IndexedElement.PUBLIC_MODIFIERS;
163.111 + }
163.112 + }
163.113 +
163.114 + return modifiers;
163.115 + }
163.116 +
163.117 + public Object getSignature() {
163.118 + return name;
163.119 + }
163.120 +}
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
164.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/Element.java Wed Sep 02 20:31:18 2015 +0200
164.3 @@ -0,0 +1,85 @@
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.elements;
164.35 +
164.36 +import java.util.Collections;
164.37 +import java.util.Set;
164.38 +import org.netbeans.modules.csl.api.ElementHandle;
164.39 +import org.netbeans.modules.csl.api.ElementKind;
164.40 +import org.netbeans.modules.csl.api.Modifier;
164.41 +import org.netbeans.modules.csl.api.OffsetRange;
164.42 +import org.netbeans.modules.csl.spi.ParserResult;
164.43 +import org.netbeans.modules.python.api.PythonMIMEResolver;
164.44 +import org.openide.filesystems.FileObject;
164.45 +
164.46 +/**
164.47 + *
164.48 + * @author Tor Norbye
164.49 + */
164.50 +public abstract class Element implements ElementHandle {
164.51 + @Override
164.52 + public abstract String getName();
164.53 +
164.54 + @Override
164.55 + public abstract ElementKind getKind();
164.56 +
164.57 + @Override
164.58 + public String getMimeType() {
164.59 + return PythonMIMEResolver.PYTHON_MIME_TYPE;
164.60 + }
164.61 +
164.62 + @Override
164.63 + public boolean signatureEquals(ElementHandle handle) {
164.64 + // XXX TODO
164.65 + return false;
164.66 + }
164.67 +
164.68 + @Override
164.69 + public OffsetRange getOffsetRange(ParserResult pr) {
164.70 + // XXX TODO
164.71 + return null;
164.72 + }
164.73 +
164.74 + @Override
164.75 + public FileObject getFileObject() {
164.76 + return null;
164.77 + }
164.78 +
164.79 + @Override
164.80 + public Set<Modifier> getModifiers() {
164.81 + return Collections.emptySet();
164.82 + }
164.83 +
164.84 + @Override
164.85 + public String getIn() {
164.86 + return null;
164.87 + }
164.88 +}
165.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
165.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/IndexedElement.java Wed Sep 02 20:31:18 2015 +0200
165.3 @@ -0,0 +1,527 @@
165.4 +/*
165.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
165.6 + *
165.7 + * Copyright 1997-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 + * Contributor(s):
165.31 + *
165.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
165.33 + */
165.34 +package org.netbeans.modules.python.source.elements;
165.35 +
165.36 +import java.util.Collections;
165.37 +import java.util.EnumSet;
165.38 +import java.util.Set;
165.39 +import org.netbeans.modules.csl.api.ElementKind;
165.40 +import org.netbeans.modules.csl.api.Modifier;
165.41 +import org.netbeans.modules.csl.api.OffsetRange;
165.42 +import org.netbeans.modules.csl.spi.ParserResult;
165.43 +import org.netbeans.modules.python.source.PythonIndex;
165.44 +import org.netbeans.modules.python.source.PythonAstUtils;
165.45 +import org.openide.filesystems.FileObject;
165.46 +import org.python.antlr.PythonTree;
165.47 +
165.48 +/**
165.49 + * Elements representing information coming from the persistent index
165.50 + *
165.51 + * @author Tor Norbye
165.52 + */
165.53 +public class IndexedElement extends Element {
165.54 + public static final EnumSet<Modifier> PRIVATE_MODIFIERS = EnumSet.of(Modifier.PRIVATE);
165.55 + public static final EnumSet<Modifier> PROTECTED_MODIFIERS = EnumSet.of(Modifier.PROTECTED);
165.56 + public static final EnumSet<Modifier> STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC);
165.57 + public static final EnumSet<Modifier> PRIVATE_STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC, Modifier.PRIVATE);
165.58 + public static final EnumSet<Modifier> PROTECTED_STATIC_MODIFIERS = EnumSet.of(Modifier.STATIC, Modifier.PROTECTED);
165.59 + public static final Set<Modifier> PUBLIC_MODIFIERS = Collections.emptySet();
165.60 +
165.61 + // Plan: Stash a single item for class entries so I can search by document for the class.
165.62 + // Add more types into the types
165.63 + /** This method is documented */
165.64 + public static final int DOCUMENTED = 1 << 0;
165.65 + /** This method is private */
165.66 + public static final int PRIVATE = 1 << 2;
165.67 + /** This is a function, not a property */
165.68 + public static final int FUNCTION = 1 << 3;
165.69 + /** This element is "static" (e.g. it's a classvar for fields, class method for methods etc) */
165.70 + public static final int STATIC = 1 << 4;
165.71 + /** This element is deliberately not documented (rdoc :nodoc:) */
165.72 + public static final int NODOC = 1 << 5;
165.73 + /** This is a global variable */
165.74 + public static final int GLOBAL = 1 << 6;
165.75 + /** This is a constructor */
165.76 + public static final int CONSTRUCTOR = 1 << 7;
165.77 + /** This is a deprecated */
165.78 + public static final int DEPRECATED = 1 << 8;
165.79 + /** This is a documentation-only definition */
165.80 + public static final int DOC_ONLY = 1 << 9;
165.81 + /** This is a constant/final */
165.82 + public static final int FINAL = 1 << 10;
165.83 +
165.84 + // Flags noting semicolon positions in attributes
165.85 + public static final int NAME_INDEX = 0;
165.86 + public static final int TYPE_INDEX = 1;
165.87 + public static final int FLAG_INDEX = 2;
165.88 + public static final int ARG_INDEX = 3;
165.89 +// public static final int IN_INDEX = 1;
165.90 +// public static final int CASE_SENSITIVE_INDEX = 2;
165.91 +// public static final int FLAG_INDEX = 3;
165.92 +// public static final int ARG_INDEX = 4;
165.93 +// public static final int NODE_INDEX = 5;
165.94 +// public static final int DOC_INDEX = 6;
165.95 +// public static final int BROWSER_INDEX = 7;
165.96 +// public static final int TYPE_INDEX = 8;
165.97 + protected final String name;
165.98 + protected final ElementKind kind;
165.99 + protected String url;
165.100 + protected FileObject fileObject;
165.101 + protected final String module;
165.102 + protected String rhs;
165.103 + protected boolean smart;
165.104 + protected boolean inherited;
165.105 + protected Set<Modifier> modifiers;
165.106 + protected PythonTree node;
165.107 + protected int flags;
165.108 + protected final String attributes;
165.109 + protected final String clz;
165.110 + protected int order;
165.111 +
165.112 + public IndexedElement(String name, ElementKind kind, String url, String module, String clz, String attributes) {
165.113 + this.name = name;
165.114 + this.kind = kind;
165.115 + this.url = url;
165.116 + this.module = module;
165.117 + this.clz = clz;
165.118 + this.attributes = attributes;
165.119 +
165.120 + // Should be IndexedMethod:
165.121 + //assert !((!(this instanceof IndexedMethod)) && (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR)) : this;
165.122 + }
165.123 +
165.124 + public static IndexedElement create(String signature, String module, String url, String clz) {
165.125 + int semi = signature.indexOf(';');
165.126 + assert semi != -1;
165.127 +
165.128 + String name = signature.substring(0, semi);
165.129 + int flags = IndexedElement.decode(signature, semi + 3, 0);
165.130 +
165.131 + char type = signature.charAt(semi + 1);
165.132 + ElementKind kind;
165.133 + switch (type) {
165.134 + case 'C':
165.135 + kind = ElementKind.CLASS;
165.136 + break;
165.137 + case 'I':
165.138 + kind = ElementKind.MODULE;
165.139 + break;
165.140 + case 'D':
165.141 + kind = ElementKind.VARIABLE;
165.142 + break;
165.143 + case 'A':
165.144 + kind = ElementKind.ATTRIBUTE;
165.145 + break;
165.146 + case 'F':
165.147 + case 'M':
165.148 + case 'c': {
165.149 + kind = type == 'c' ? ElementKind.CONSTRUCTOR : ElementKind.METHOD;
165.150 + IndexedMethod method = new IndexedMethod(name, kind, url, module, clz, signature);
165.151 + method.flags = flags;
165.152 + return method;
165.153 + }
165.154 + default:
165.155 + kind = ElementKind.OTHER;
165.156 + break;
165.157 + }
165.158 +
165.159 + IndexedElement element = new IndexedElement(name, kind, url, module, clz, signature);
165.160 + element.flags = flags;
165.161 + return element;
165.162 + }
165.163 +
165.164 + @Override
165.165 + public boolean equals(Object obj) {
165.166 + if (obj == null) {
165.167 + return false;
165.168 + }
165.169 + if (getClass() != obj.getClass()) {
165.170 + return false;
165.171 + }
165.172 + final IndexedElement other = (IndexedElement)obj;
165.173 + if (this.name != other.name && (this.name == null || !this.name.equals(other.name))) {
165.174 + return false;
165.175 + }
165.176 + if (this.module != other.module && (this.module == null || !this.module.equals(other.module))) {
165.177 + return false;
165.178 + }
165.179 + if (this.kind != other.kind) {
165.180 + return false;
165.181 + }
165.182 + return true;
165.183 + }
165.184 +
165.185 + public String getModule() {
165.186 + return module;
165.187 + }
165.188 +
165.189 + @Override
165.190 + public int hashCode() {
165.191 + int hash = 3;
165.192 + hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
165.193 + hash = 67 * hash + (this.kind != null ? this.kind.hashCode() : 0);
165.194 + return hash;
165.195 + }
165.196 +
165.197 + @Override
165.198 + public String getName() {
165.199 + return name;
165.200 + }
165.201 +
165.202 + @Override
165.203 + public ElementKind getKind() {
165.204 + return kind;
165.205 + }
165.206 +
165.207 + public String getFilenameUrl() {
165.208 + return url;
165.209 + }
165.210 +
165.211 + @Override
165.212 + public FileObject getFileObject() {
165.213 + if ((fileObject == null) && (url != null)) {
165.214 + fileObject = PythonIndex.getFileObject(url);
165.215 +
165.216 + if (fileObject == null) {
165.217 + // Don't try again
165.218 + url = null;
165.219 + }
165.220 + }
165.221 +
165.222 + return fileObject;
165.223 + }
165.224 +
165.225 + public void setFlags(int flags) {
165.226 + this.flags = flags;
165.227 + }
165.228 +
165.229 + public void setInherited(boolean inherited) {
165.230 + this.inherited = inherited;
165.231 + }
165.232 +
165.233 + public boolean isInherited() {
165.234 + return inherited;
165.235 + }
165.236 +
165.237 + public String getType() {
165.238 + return null;
165.239 + }
165.240 +
165.241 + public String getOrigin() {
165.242 + return module;
165.243 + }
165.244 +
165.245 + public boolean isSmart() {
165.246 + return smart;
165.247 + }
165.248 +
165.249 + public void setSmart(boolean smart) {
165.250 + this.smart = smart;
165.251 + }
165.252 +
165.253 + public String getRhs() {
165.254 + if (rhs == null) {
165.255 + rhs = module;
165.256 + if (rhs.equals("stub_missing")) { // NOI18N
165.257 + rhs = "<i>builtin</i>";
165.258 + }
165.259 + }
165.260 + return rhs;
165.261 + }
165.262 +
165.263 + public void setRhs(String rhs) {
165.264 + this.rhs = rhs;
165.265 + }
165.266 +
165.267 + @Override
165.268 + public String getIn() {
165.269 + return module;
165.270 + }
165.271 +
165.272 + public String getSignature() {
165.273 + if (clz != null) {
165.274 + return clz + "." + name;
165.275 + }
165.276 +
165.277 + return name;
165.278 + }
165.279 +
165.280 + public String getClz() {
165.281 + return clz;
165.282 + }
165.283 +
165.284 + public int getOrder() {
165.285 + return order;
165.286 + }
165.287 +
165.288 + public void setOrder(int order) {
165.289 + this.order = order;
165.290 + }
165.291 +
165.292 + public static Set<Modifier> getModifiersForName(String name, boolean isPrivate, boolean isProtected, boolean isStatic) {
165.293 + Set<Modifier> modifiers;
165.294 +
165.295 + // Private variables: start with __ but doesn't end with __
165.296 + // Section 9.6 Private Variables - http://docs.python.org/tut/node11.html
165.297 + if (name != null && name.startsWith("__") && !name.endsWith("__")) { // NOI18N
165.298 + isPrivate = true;
165.299 + } else if (name != null && name.startsWith("_") && !name.endsWith("_")) { // NOI18N
165.300 + // From PEP8: Single_leading_underscore: weak "internal use" indicator
165.301 + // (e.g. "from M import *" does not import objects whose name
165.302 + // starts with an underscore).
165.303 + // The protected modifier might work well to visually indicate this.
165.304 + isProtected = true;
165.305 + }
165.306 + if (isPrivate) {
165.307 + if (isStatic) {
165.308 + modifiers = PRIVATE_STATIC_MODIFIERS;
165.309 + } else {
165.310 + modifiers = PRIVATE_MODIFIERS;
165.311 + }
165.312 + } else if (isProtected) {
165.313 + if (isStatic) {
165.314 + modifiers = PROTECTED_STATIC_MODIFIERS;
165.315 + } else {
165.316 + modifiers = PROTECTED_MODIFIERS;
165.317 + }
165.318 + } else {
165.319 + if (isStatic) {
165.320 + modifiers = STATIC_MODIFIERS;
165.321 + } else {
165.322 + modifiers = PUBLIC_MODIFIERS;
165.323 + }
165.324 + }
165.325 +
165.326 + return modifiers;
165.327 + }
165.328 +
165.329 + @Override
165.330 + public Set<Modifier> getModifiers() {
165.331 + if (modifiers == null) {
165.332 + modifiers = getModifiersForName(name, isPrivate(), false, isStatic());
165.333 + }
165.334 +
165.335 + return modifiers;
165.336 + }
165.337 +
165.338 + public PythonTree getNode() {
165.339 + if (node == null) {
165.340 + node = PythonAstUtils.getForeignNode(this, null);
165.341 + }
165.342 + return node;
165.343 + }
165.344 +
165.345 + @Override
165.346 + public String toString() {
165.347 + return "IndexedElement:" + name + "," + kind + "," + rhs;
165.348 + }
165.349 +
165.350 + protected int getAttributeSection(int section) {
165.351 + assert section != 0; // Obtain directly, and logic below (+1) is wrong
165.352 + int attributeIndex = 0;
165.353 + for (int i = 0; i < section; i++) {
165.354 + attributeIndex = attributes.indexOf(';', attributeIndex + 1);
165.355 + }
165.356 +
165.357 + assert attributeIndex != -1;
165.358 + return attributeIndex + 1;
165.359 + }
165.360 +
165.361 + /** Return a string (suitable for persistence) encoding the given flags */
165.362 + public static String encode(int flags) {
165.363 + return Integer.toString(flags, 16);
165.364 + }
165.365 +
165.366 + /** Return flag corresponding to the given encoding chars */
165.367 + public static int decode(String s, int startIndex, int defaultValue) {
165.368 + int value = 0;
165.369 + for (int i = startIndex, n = s.length(); i < n; i++) {
165.370 + char c = s.charAt(i);
165.371 + if (c == ';') {
165.372 + if (i == startIndex) {
165.373 + return defaultValue;
165.374 + }
165.375 + break;
165.376 + }
165.377 +
165.378 + value = value << 4;
165.379 +
165.380 + if (c > '9') {
165.381 + value += c - 'a' + 10;
165.382 + } else {
165.383 + value += c - '0';
165.384 + }
165.385 + }
165.386 +
165.387 + return value;
165.388 + }
165.389 +
165.390 + public static int getFlags(AstElement element) {
165.391 + // Return the flags corresponding to the given AST element
165.392 + int value = 0;
165.393 +
165.394 + ElementKind k = element.getKind();
165.395 + if (k == ElementKind.CONSTRUCTOR) {
165.396 + value = value | CONSTRUCTOR;
165.397 + }
165.398 + if (k == ElementKind.METHOD || k == ElementKind.CONSTRUCTOR) {
165.399 + value = value | FUNCTION;
165.400 + } else if (k == ElementKind.GLOBAL) {
165.401 + value = value | GLOBAL;
165.402 + }
165.403 + if (element.getModifiers().contains(Modifier.STATIC)) {
165.404 + value = value | STATIC;
165.405 + }
165.406 + if (element.getModifiers().contains(Modifier.DEPRECATED)) {
165.407 + value = value | DEPRECATED;
165.408 + }
165.409 + if (element.getModifiers().contains(Modifier.PRIVATE)) {
165.410 + value = value | PRIVATE;
165.411 + }
165.412 +
165.413 + return value;
165.414 + }
165.415 +
165.416 + public boolean isDocumented() {
165.417 + return (flags & DOCUMENTED) != 0;
165.418 + }
165.419 +
165.420 + public boolean isPublic() {
165.421 + return (flags & PRIVATE) == 0;
165.422 + }
165.423 +
165.424 + public boolean isPrivate() {
165.425 + return (flags & PRIVATE) != 0;
165.426 + }
165.427 +
165.428 + public boolean isFunction() {
165.429 + return (flags & FUNCTION) != 0;
165.430 + }
165.431 +
165.432 + public boolean isStatic() {
165.433 + return (flags & STATIC) != 0;
165.434 + }
165.435 +
165.436 + public boolean isNoDoc() {
165.437 + return (flags & NODOC) != 0;
165.438 + }
165.439 +
165.440 + public boolean isFinal() {
165.441 + return (flags & FINAL) != 0;
165.442 + }
165.443 +
165.444 + public boolean isConstructor() {
165.445 + return (flags & CONSTRUCTOR) != 0;
165.446 + }
165.447 +
165.448 + public boolean isDeprecated() {
165.449 + return (flags & DEPRECATED) != 0;
165.450 + }
165.451 +
165.452 + public boolean isDocOnly() {
165.453 + return (flags & DOC_ONLY) != 0;
165.454 + }
165.455 +
165.456 + public static String decodeFlags(int flags) {
165.457 + StringBuilder sb = new StringBuilder();
165.458 + if ((flags & DOCUMENTED) != 0) {
165.459 + sb.append("|DOCUMENTED");
165.460 + }
165.461 +
165.462 + if ((flags & PRIVATE) != 0) {
165.463 + sb.append("|PRIVATE");
165.464 + }
165.465 +
165.466 + if ((flags & CONSTRUCTOR) != 0) {
165.467 + sb.append("|CONSTRUCTOR");
165.468 + } else if ((flags & FUNCTION) != 0) {
165.469 + sb.append("|FUNCTION");
165.470 + } else if ((flags & GLOBAL) != 0) {
165.471 + sb.append("|GLOBAL");
165.472 + }
165.473 +
165.474 + if ((flags & STATIC) != 0) {
165.475 + sb.append("|STATIC");
165.476 + }
165.477 +
165.478 + if ((flags & NODOC) != 0) {
165.479 + sb.append("|NODOC");
165.480 + }
165.481 +
165.482 + if ((flags & DEPRECATED) != 0) {
165.483 + sb.append("|DEPRECATED");
165.484 + }
165.485 +
165.486 + if ((flags & DOC_ONLY) != 0) {
165.487 + sb.append("|DOC_ONLY");
165.488 + }
165.489 +
165.490 + if ((flags & FINAL) != 0) {
165.491 + sb.append("|FINAL");
165.492 + }
165.493 +
165.494 + if (sb.length() > 0) {
165.495 + sb.append("|");
165.496 + }
165.497 + return sb.toString();
165.498 + }
165.499 +
165.500 + // For testsuite
165.501 + public static int stringToFlags(String string) {
165.502 + int flags = 0;
165.503 + if (string.contains("|DOCUMENTED")) {
165.504 + flags |= DOCUMENTED;
165.505 + }
165.506 + if (string.contains("|PRIVATE")) {
165.507 + flags |= PRIVATE;
165.508 + }
165.509 + if (string.contains("|DEPRECATED")) {
165.510 + flags |= DEPRECATED;
165.511 + }
165.512 + if (string.contains("|CONSTRUCTOR")) {
165.513 + flags |= CONSTRUCTOR;
165.514 + }
165.515 +// if (string.indexOf("|PROTECTED") != -1) {
165.516 +// flags |= PROTECTED;
165.517 +// }
165.518 +// if (string.indexOf("|TOPLEVEL") != -1) {
165.519 +// flags |= TOPLEVEL;
165.520 +// }
165.521 + if (string.contains("|STATIC")) {
165.522 + flags |= STATIC;
165.523 + }
165.524 + if (string.contains("|NODOC")) {
165.525 + flags |= NODOC;
165.526 + }
165.527 +
165.528 + return flags;
165.529 + }
165.530 +}
166.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
166.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/IndexedMethod.java Wed Sep 02 20:31:18 2015 +0200
166.3 @@ -0,0 +1,88 @@
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 org.netbeans.modules.csl.api.ElementKind;
166.37 +
166.38 +/**
166.39 + *
166.40 + * @author Tor Norbye
166.41 + */
166.42 +public class IndexedMethod extends IndexedElement {
166.43 + private String[] params;
166.44 +
166.45 + public IndexedMethod(String name, ElementKind kind, String url, String module, String clz, String signature) {
166.46 + super(name, kind, url, module, clz, signature);
166.47 + }
166.48 +
166.49 + public String[] getParams() {
166.50 + if (params == null) {
166.51 + //int argsBegin = name.length()+3;
166.52 + int argsBegin = getAttributeSection(IndexedElement.ARG_INDEX);
166.53 + int argsEnd = attributes.indexOf(';', argsBegin);
166.54 + assert argsEnd != -1 : attributes;
166.55 + if (argsEnd > argsBegin) {
166.56 + String paramString = attributes.substring(argsBegin, argsEnd);
166.57 + params = paramString.split(",");
166.58 + } else {
166.59 + params = new String[0];
166.60 + }
166.61 + }
166.62 +
166.63 + return params;
166.64 + }
166.65 +
166.66 + @Override
166.67 + public boolean equals(Object obj) {
166.68 + if (obj == null) {
166.69 + return false;
166.70 + }
166.71 + if (getClass() != obj.getClass()) {
166.72 + return false;
166.73 + }
166.74 + final IndexedMethod other = (IndexedMethod)obj;
166.75 + if (this.attributes != other.attributes && (this.attributes == null || !this.attributes.equals(other.attributes))) {
166.76 + return false;
166.77 + }
166.78 + if (this.clz != other.clz && (this.clz == null || !this.clz.equals(other.clz))) {
166.79 + return false;
166.80 + }
166.81 + return true;
166.82 + }
166.83 +
166.84 + @Override
166.85 + public int hashCode() {
166.86 + int hash = 7;
166.87 + hash = 53 * hash + (this.attributes != null ? this.attributes.hashCode() : 0);
166.88 + hash = 53 * hash + (this.clz != null ? this.clz.hashCode() : 0);
166.89 + return hash;
166.90 + }
166.91 +}
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167.2 +++ b/python.source/src/org/netbeans/modules/python/source/elements/IndexedPackage.java Wed Sep 02 20:31:18 2015 +0200
167.3 @@ -0,0 +1,106 @@
167.4 +/*
167.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
167.6 + *
167.7 + * Copyright 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 + * If you wish your version of this file to be governed by only the CDDL
167.31 + * or only the GPL Version 2, indicate your decision by adding
167.32 + * "[Contributor] elects to include this software in this distribution
167.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
167.34 + * single choice of license, a recipient has the option to distribute
167.35 + * your version of this file under either the CDDL, the GPL Version 2 or
167.36 + * to extend the choice of license to its licensees as provided above.
167.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
167.38 + * Version 2 license, then the option applies only if the new code is
167.39 + * made subject to such option by the copyright holder.
167.40 + *
167.41 + * Contributor(s):
167.42 + *
167.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
167.44 + */
167.45 +package org.netbeans.modules.python.source.elements;
167.46 +
167.47 +import java.util.Collections;
167.48 +import java.util.Set;
167.49 +import org.netbeans.modules.csl.api.ElementKind;
167.50 +import org.netbeans.modules.csl.api.Modifier;
167.51 +
167.52 +/**
167.53 + *
167.54 + * @author Tor Norbye
167.55 + */
167.56 +public class IndexedPackage extends IndexedElement {
167.57 + private String pkg;
167.58 + private boolean hasMore;
167.59 +
167.60 + public IndexedPackage(String name, String pkg, String url, boolean hasMore) {
167.61 + super(name, ElementKind.PACKAGE, url, null, null, null);
167.62 + this.pkg = pkg;
167.63 + this.hasMore = hasMore;
167.64 + }
167.65 +
167.66 + @Override
167.67 + public Set<Modifier> getModifiers() {
167.68 + return Collections.emptySet();
167.69 + }
167.70 +
167.71 + public String getPkg() {
167.72 + return pkg;
167.73 + }
167.74 +
167.75 + public boolean hasMore() {
167.76 + return hasMore;
167.77 + }
167.78 +
167.79 + @Override
167.80 + public boolean equals(Object obj) {
167.81 + if (obj == null) {
167.82 + return false;
167.83 + }
167.84 + if (getClass() != obj.getClass()) {
167.85 + return false;
167.86 + }
167.87 + final IndexedPackage other = (IndexedPackage)obj;
167.88 +
167.89 + // Side effect:
167.90 + // If any element thinks we have more
167.91 + if (other.hasMore) {
167.92 + this.hasMore = other.hasMore;
167.93 + } else if (this.hasMore) {
167.94 + other.hasMore = this.hasMore;
167.95 + }
167.96 +
167.97 + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
167.98 + return false;
167.99 + }
167.100 + return true;
167.101 + }
167.102 +
167.103 + @Override
167.104 + public int hashCode() {
167.105 + int hash = 7;
167.106 + hash = 73 * hash + (this.name != null ? this.name.hashCode() : 0);
167.107 + return hash;
167.108 + }
167.109 +}
168.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
168.2 +++ b/python.source/src/org/netbeans/modules/python/source/impl/PythonProjectSourceLevelQuery.java Wed Sep 02 20:31:18 2015 +0200
168.3 @@ -0,0 +1,29 @@
168.4 +/*
168.5 + * To change this license header, choose License Headers in Project Properties.
168.6 + * To change this template file, choose Tools | Templates
168.7 + * and open the template in the editor.
168.8 + */
168.9 +package org.netbeans.modules.python.source.impl;
168.10 +
168.11 +import org.netbeans.modules.python.source.queries.SourceLevelQueryImplementation;
168.12 +import org.netbeans.api.project.FileOwnerQuery;
168.13 +import org.netbeans.api.project.Project;
168.14 +import org.openide.filesystems.FileObject;
168.15 +import org.openide.util.lookup.ServiceProvider;
168.16 +
168.17 +@ServiceProvider(service = SourceLevelQueryImplementation.class, position = 400)
168.18 +public class PythonProjectSourceLevelQuery implements SourceLevelQueryImplementation {
168.19 +
168.20 + @Override
168.21 + public Result getSourceLevel(FileObject pythonFile) {
168.22 + final Project project = FileOwnerQuery.getOwner(pythonFile);
168.23 + if (project != null) {
168.24 + SourceLevelQueryImplementation impl = project.getLookup().lookup(SourceLevelQueryImplementation.class);
168.25 + if (impl != null) {
168.26 + return impl.getSourceLevel(pythonFile);
168.27 + }
168.28 + }
168.29 + return null;
168.30 + }
168.31 +
168.32 +}
169.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
169.2 +++ b/python.source/src/org/netbeans/modules/python/source/impl/QuerySupportFactory.java Wed Sep 02 20:31:18 2015 +0200
169.3 @@ -0,0 +1,80 @@
169.4 +/*
169.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
169.6 + *
169.7 + * Copyright 2015 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 + * If you wish your version of this file to be governed by only the CDDL
169.31 + * or only the GPL Version 2, indicate your decision by adding
169.32 + * "[Contributor] elects to include this software in this distribution
169.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
169.34 + * single choice of license, a recipient has the option to distribute
169.35 + * your version of this file under either the CDDL, the GPL Version 2 or
169.36 + * to extend the choice of license to its licensees as provided above.
169.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
169.38 + * Version 2 license, then the option applies only if the new code is
169.39 + * made subject to such option by the copyright holder.
169.40 + *
169.41 + * Contributor(s):
169.42 + *
169.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
169.44 + */
169.45 +package org.netbeans.modules.python.source.impl;
169.46 +
169.47 +import java.io.IOException;
169.48 +import java.util.Collection;
169.49 +import java.util.Collections;
169.50 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
169.51 +import org.netbeans.modules.python.source.PythonIndexer;
169.52 +import org.openide.filesystems.FileObject;
169.53 +import org.openide.util.Exceptions;
169.54 +
169.55 +/**
169.56 + *
169.57 + * @author Ralph Ruijs
169.58 + */
169.59 +public final class QuerySupportFactory {
169.60 +
169.61 +
169.62 + public static QuerySupport getQuerySupport(final Collection<FileObject> roots) {
169.63 + try {
169.64 + return QuerySupport.forRoots(PythonIndexer.NAME,
169.65 + PythonIndexer.VERSION,
169.66 + roots.toArray(new FileObject[roots.size()]));
169.67 + } catch (IOException ex) {
169.68 + Exceptions.printStackTrace(ex);
169.69 + }
169.70 + return null;
169.71 + }
169.72 +
169.73 + public static QuerySupport getQuerySupport(final FileObject source) {
169.74 + return getQuerySupport(QuerySupport.findRoots(source,
169.75 + null,
169.76 + null,
169.77 + Collections.<String>emptySet()));
169.78 + }
169.79 +
169.80 + private QuerySupportFactory() {
169.81 + }
169.82 +
169.83 +}
170.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
170.2 +++ b/python.source/src/org/netbeans/modules/python/source/layer.xml Wed Sep 02 20:31:18 2015 +0200
170.3 @@ -0,0 +1,71 @@
170.4 +<?xml version="1.0" encoding="UTF-8"?>
170.5 +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
170.6 +<filesystem>
170.7 + <folder name="CslPlugins">
170.8 + <folder name="text">
170.9 + <folder name="x-python">
170.10 + <file name="structure.instance">
170.11 + <attr name="instanceClass" stringvalue="org.netbeans.modules.python.source.PythonStructureScanner"/>
170.12 + </file>
170.13 + </folder>
170.14 + </folder>
170.15 + </folder>
170.16 + <folder name="Editors">
170.17 + <folder name="text">
170.18 + <folder name="x-python">
170.19 + <file name="language.instance">
170.20 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.lexer.PythonTokenId.language"/>
170.21 + <attr name="instanceOf" stringvalue="org.netbeans.api.lexer.Language"/>
170.22 + </file>
170.23 + </folder>
170.24 + </folder>
170.25 + </folder>
170.26 + <folder name="OptionsDialog">
170.27 + <folder name="PreviewExamples">
170.28 + <folder name="text">
170.29 + <file name="x-python" url="PythonExample.py"/>
170.30 + </folder>
170.31 + </folder>
170.32 + <folder name="Editor">
170.33 + <folder name="Formatting">
170.34 + <attr name="position" intvalue="0"/>
170.35 + <folder name="text">
170.36 + <folder name="x-python">
170.37 + <file name="Imports.instance">
170.38 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
170.39 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtImports.getController"/>
170.40 + <attr name="position" intvalue="150"/>
170.41 + </file>
170.42 + <!-- Not yet implemented
170.43 + <file name="TabsAndIndents.instance">
170.44 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
170.45 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtTabsIndents.getController"/>
170.46 + <attr name="position" intvalue="100"/>
170.47 + </file>
170.48 + <file name="Alignment.instance">
170.49 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
170.50 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtAlignment.getController"/>
170.51 + <attr name="position" intvalue="200"/>
170.52 + </file>
170.53 + <file name="Wrapping.instance">
170.54 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
170.55 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtWrapping.getController"/>
170.56 + <attr name="position" intvalue="400"/>
170.57 + </file>
170.58 + <file name="BlankLines.instance">
170.59 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
170.60 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtBlankLines.getController"/>
170.61 + <attr name="position" intvalue="500"/>
170.62 + </file>
170.63 + -->
170.64 + <file name="Spaces.instance">
170.65 + <attr name="instanceOf" stringvalue="org.netbeans.modules.options.editor.spi.PreferencesCustomizer$Factory"/>
170.66 + <attr name="instanceCreate" methodvalue="org.netbeans.modules.python.source.ui.FmtSpaces.getController"/>
170.67 + <attr name="position" intvalue="600"/>
170.68 + </file>
170.69 + </folder>
170.70 + </folder>
170.71 + </folder>
170.72 + </folder>
170.73 + </folder>
170.74 +</filesystem>
171.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
171.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/Call.java Wed Sep 02 20:31:18 2015 +0200
171.3 @@ -0,0 +1,322 @@
171.4 +/*
171.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
171.6 + *
171.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
171.8 + *
171.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
171.10 + * Other names may be trademarks of their respective owners.
171.11 + *
171.12 + * The contents of this file are subject to the terms of either the GNU
171.13 + * General Public License Version 2 only ("GPL") or the Common
171.14 + * Development and Distribution License("CDDL") (collectively, the
171.15 + * "License"). You may not use this file except in compliance with the
171.16 + * License. You can obtain a copy of the License at
171.17 + * http://www.netbeans.org/cddl-gplv2.html
171.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
171.19 + * specific language governing permissions and limitations under the
171.20 + * License. When distributing the software, include this License Header
171.21 + * Notice in each file and include the License file at
171.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
171.23 + * particular file as subject to the "Classpath" exception as provided
171.24 + * by Oracle in the GPL Version 2 section of the License file that
171.25 + * accompanied this code. If applicable, add the following below the
171.26 + * License Header, with the fields enclosed by brackets [] replaced by
171.27 + * your own identifying information:
171.28 + * "Portions Copyrighted [year] [name of copyright owner]"
171.29 + *
171.30 + * Contributor(s):
171.31 + *
171.32 + * The Original Software is NetBeans. The Initial Developer of the Original
171.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
171.34 + * Microsystems, Inc. All Rights Reserved.
171.35 + *
171.36 + * If you wish your version of this file to be governed by only the CDDL
171.37 + * or only the GPL Version 2, indicate your decision by adding
171.38 + * "[Contributor] elects to include this software in this distribution
171.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
171.40 + * single choice of license, a recipient has the option to distribute
171.41 + * your version of this file under either the CDDL, the GPL Version 2 or
171.42 + * to extend the choice of license to its licensees as provided above.
171.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
171.44 + * Version 2 license, then the option applies only if the new code is
171.45 + * made subject to such option by the copyright holder.
171.46 + */
171.47 +package org.netbeans.modules.python.source.lexer;
171.48 +
171.49 +import javax.swing.text.BadLocationException;
171.50 +import javax.swing.text.Document;
171.51 +import org.netbeans.api.annotations.common.NonNull;
171.52 +
171.53 +import org.netbeans.api.lexer.Token;
171.54 +import org.netbeans.api.lexer.TokenHierarchy;
171.55 +import org.netbeans.api.lexer.TokenId;
171.56 +import org.netbeans.api.lexer.TokenSequence;
171.57 +import org.netbeans.editor.BaseDocument;
171.58 +import org.netbeans.editor.Utilities;
171.59 +import org.openide.util.Exceptions;
171.60 +
171.61 +/**
171.62 + * Class which represents a Call in the source
171.63 + */
171.64 +public class Call {
171.65 + public static final Call LOCAL = new Call(null, null, false, false);
171.66 + public static final Call NONE = new Call(null, null, false, false);
171.67 + public static final Call UNKNOWN = new Call(null, null, false, false);
171.68 + private final String type;
171.69 + private final String lhs;
171.70 + private final boolean isStatic;
171.71 + private final boolean methodExpected;
171.72 +
171.73 + public Call(String type, String lhs, boolean isStatic, boolean methodExpected) {
171.74 + super();
171.75 + this.type = type;
171.76 + this.lhs = lhs;
171.77 + this.methodExpected = methodExpected;
171.78 + if (lhs == null) {
171.79 + lhs = type;
171.80 + }
171.81 + this.isStatic = isStatic;
171.82 + }
171.83 +
171.84 + public String getType() {
171.85 + return type;
171.86 + }
171.87 +
171.88 + public String getLhs() {
171.89 + return lhs;
171.90 + }
171.91 +
171.92 + public boolean isStatic() {
171.93 + return isStatic;
171.94 + }
171.95 +
171.96 + public boolean isSimpleIdentifier() {
171.97 + if (lhs == null) {
171.98 + return false;
171.99 + }
171.100 + // TODO - replace with the new PythonUtil validations
171.101 + for (int i = 0, n = lhs.length(); i < n; i++) {
171.102 + char c = lhs.charAt(i);
171.103 + if (Character.isJavaIdentifierPart(c)) {
171.104 + continue;
171.105 + }
171.106 + return false;
171.107 + }
171.108 + return true;
171.109 + }
171.110 +
171.111 + @Override
171.112 + public String toString() {
171.113 + if (this == LOCAL) {
171.114 + return "LOCAL";
171.115 + } else if (this == NONE) {
171.116 + return "NONE";
171.117 + } else if (this == UNKNOWN) {
171.118 + return "UNKNOWN";
171.119 + } else {
171.120 + return "Call(" + type + "," + lhs + "," + isStatic + ")";
171.121 + }
171.122 + }
171.123 +
171.124 + /** foo.| or foo.b| -> we're expecting a method call. For Foo:: we don't know. */
171.125 + public boolean isMethodExpected() {
171.126 + return this.methodExpected;
171.127 + }
171.128 +
171.129 + /**
171.130 + * Determine whether the given offset corresponds to a method call on another
171.131 + * object. This would happen in these cases:
171.132 + * Foo::|, Foo::Bar::|, Foo.|, Foo.x|, foo.|, foo.x|
171.133 + * and not here:
171.134 + * |, Foo|, foo|
171.135 + * The method returns the left hand side token, if any, such as "Foo", Foo::Bar",
171.136 + * and "foo". If not, it will return null.
171.137 + * Note that "self" and "super" are possible return values for the lhs, which mean
171.138 + * that you don't have a call on another object. Clients of this method should
171.139 + * handle that return value properly (I could return null here, but clients probably
171.140 + * want to distinguish self and super in this case so it's useful to return the info.)
171.141 + *
171.142 + * This method will also try to be smart such that if you have a block or array
171.143 + * call, it will return the relevant classnames (e.g. for [1,2].x| it returns "Array").
171.144 + */
171.145 + @SuppressWarnings("unchecked")
171.146 + @NonNull
171.147 + public static Call getCallType(BaseDocument doc, TokenHierarchy<Document> th, int offset) {
171.148 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(th, offset);
171.149 +
171.150 + if (ts == null) {
171.151 + return Call.NONE;
171.152 + }
171.153 +
171.154 + ts.move(offset);
171.155 +
171.156 + boolean methodExpected = false;
171.157 +
171.158 + if (!ts.moveNext() && !ts.movePrevious()) {
171.159 + return Call.NONE;
171.160 + }
171.161 +
171.162 + if (ts.offset() == offset) {
171.163 + // We're looking at the offset to the RIGHT of the caret
171.164 + // position, which could be whitespace, e.g.
171.165 + // "foo.x| " <-- looking at the whitespace
171.166 + ts.movePrevious();
171.167 + }
171.168 +
171.169 + Token<? extends PythonTokenId> token = ts.token();
171.170 +
171.171 + if (token != null) {
171.172 + TokenId id = token.id();
171.173 +
171.174 + if (id == PythonTokenId.WHITESPACE) {
171.175 + return Call.LOCAL;
171.176 + }
171.177 +
171.178 + // See if we're in the identifier - "x" in "foo.x"
171.179 + // I could also be a keyword in case the prefix happens to currently
171.180 + // match a keyword, such as "next"
171.181 + // However, if we're at the end of the document, x. will lex . as an
171.182 + // identifier of text ".", so handle this case specially
171.183 + if ((id == PythonTokenId.IDENTIFIER)/* || (id == PythonTokenId.CONSTANT)*/ ||
171.184 + id.primaryCategory().equals("keyword")) {
171.185 + String tokenText = token.text().toString();
171.186 +
171.187 + if (".".equals(tokenText)) {
171.188 + // Special case - continue - we'll handle this part next
171.189 + methodExpected = true;
171.190 + } else {
171.191 + methodExpected = true;
171.192 +
171.193 + if (Character.isUpperCase(tokenText.charAt(0))) {
171.194 + methodExpected = false;
171.195 + }
171.196 +
171.197 + if (!ts.movePrevious()) {
171.198 + return Call.LOCAL;
171.199 + }
171.200 + }
171.201 +
171.202 + token = ts.token();
171.203 + id = token.id();
171.204 + }
171.205 +
171.206 + // If we're not in the identifier we need to be in the dot (in "foo.x").
171.207 + // I can't just check for tokens DOT and COLON3 because for unparseable source
171.208 + // (like "File.|") the lexer will return the "." as an identifier.
171.209 + if (id == PythonTokenId.DOT) {
171.210 + methodExpected = true;
171.211 + } else if (id == PythonTokenId.IDENTIFIER) {
171.212 + String t = token.text().toString();
171.213 +
171.214 + if (t.equals(".")) {
171.215 + methodExpected = true;
171.216 + } else {
171.217 + return Call.LOCAL;
171.218 + }
171.219 + } else {
171.220 + return Call.LOCAL;
171.221 + }
171.222 +
171.223 + int lastSeparatorOffset = ts.offset();
171.224 + int beginOffset = lastSeparatorOffset;
171.225 + int lineStart = 0;
171.226 +
171.227 + try {
171.228 + if (offset > doc.getLength()) {
171.229 + offset = doc.getLength();
171.230 + }
171.231 +
171.232 + lineStart = Utilities.getRowStart(doc, offset);
171.233 + } catch (BadLocationException ble) {
171.234 + Exceptions.printStackTrace(ble);
171.235 + }
171.236 +
171.237 + // Find the beginning of the expression. We'll go past keywords, identifiers
171.238 + // and dots or double-colons
171.239 + while (ts.movePrevious()) {
171.240 + // If we get to the previous line we're done
171.241 + if (ts.offset() < lineStart) {
171.242 + break;
171.243 + }
171.244 +
171.245 + token = ts.token();
171.246 + id = token.id();
171.247 +
171.248 + String tokenText = null;
171.249 + if (id == PythonTokenId.ANY_KEYWORD || id == PythonTokenId.IDENTIFIER) {
171.250 + tokenText = token.text().toString();
171.251 + }
171.252 +
171.253 + if (id == PythonTokenId.WHITESPACE) {
171.254 + break;
171.255 + } else if (id == PythonTokenId.RBRACKET) {
171.256 + return new Call("ListType", null, false, methodExpected);
171.257 + } else if (id == PythonTokenId.RBRACE) {
171.258 + return new Call("DictType", null, false, methodExpected);
171.259 + } else if ((id == PythonTokenId.STRING_END)/* || (id == PythonTokenId.QUOTED_STRING_END)*/) {
171.260 + return new Call("StringType", null, false, methodExpected);
171.261 + } else if ((id == PythonTokenId.IDENTIFIER) && "True".equals(tokenText)) { // NOI18N
171.262 + return new Call("BooleanType", null, false, methodExpected);
171.263 + } else if ((id == PythonTokenId.IDENTIFIER) && "False".equals(tokenText)) { // NOI18N
171.264 + return new Call("BooleanType", null, false, methodExpected);
171.265 + } else if (((id == PythonTokenId.IDENTIFIER)) ||
171.266 + id.primaryCategory().equals("keyword") || (id == PythonTokenId.DOT)) {
171.267 +
171.268 + // We're building up a potential expression such as "Test::Unit" so continue looking
171.269 + beginOffset = ts.offset();
171.270 +
171.271 + continue;
171.272 + } else if ((id == PythonTokenId.LPAREN) || (id == PythonTokenId.LBRACE) ||
171.273 + (id == PythonTokenId.LBRACKET)) {
171.274 + // It's an expression for example within a parenthesis, e.g.
171.275 + // yield(^File.join())
171.276 + // in this case we can do top level completion
171.277 + // TODO: There are probably more valid contexts here
171.278 + break;
171.279 + } else if (id == PythonTokenId.ANY_OPERATOR) {
171.280 + break;
171.281 + } else {
171.282 + // Something else - such as "getFoo().x|" - at this point we don't know the type
171.283 + // so we'll just return unknown
171.284 + return Call.UNKNOWN;
171.285 + }
171.286 + }
171.287 +
171.288 + if (beginOffset < lastSeparatorOffset) {
171.289 + try {
171.290 + String lhs = doc.getText(beginOffset, lastSeparatorOffset - beginOffset);
171.291 +
171.292 + if (lhs.equals("super") || lhs.equals("self")) { // NOI18N
171.293 +
171.294 + return new Call(lhs, lhs, false, true);
171.295 + } else if (Character.isUpperCase(lhs.charAt(0))) {
171.296 +
171.297 +// // Detect constructor calls of the form String.new.^
171.298 +// if (lhs.endsWith(".new")) { // NOI18N
171.299 +// // See if it looks like a type prior to that
171.300 +// String type = lhs.substring(0, lhs.length()-4); // 4=".new".length()
171.301 +// if (PythonUtils.isValidPythonModuleName(type)) {
171.302 +// return new Call(type, lhs, false, methodExpected);
171.303 +// }
171.304 +// }
171.305 +
171.306 + String type = null;
171.307 +// if (PythonUtils.isValidPythonModuleName(lhs)) {
171.308 + type = lhs;
171.309 +// }
171.310 +
171.311 + return new Call(type, lhs, true, methodExpected);
171.312 + } else {
171.313 + return new Call(null, lhs, false, methodExpected);
171.314 + }
171.315 + } catch (BadLocationException ble) {
171.316 + Exceptions.printStackTrace(ble);
171.317 + }
171.318 + } else {
171.319 + return Call.UNKNOWN;
171.320 + }
171.321 + }
171.322 +
171.323 + return Call.LOCAL;
171.324 + }
171.325 +}
172.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
172.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonCommentLexer.java Wed Sep 02 20:31:18 2015 +0200
172.3 @@ -0,0 +1,229 @@
172.4 +/*
172.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
172.6 + *
172.7 + * Copyright 1997-2010 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 + * Contributor(s):
172.31 + *
172.32 + * The Original Software is NetBeans. The Initial Developer of the Original
172.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
172.34 + * Microsystems, Inc. All Rights Reserved.
172.35 + *
172.36 + * If you wish your version of this file to be governed by only the CDDL
172.37 + * or only the GPL Version 2, indicate your decision by adding
172.38 + * "[Contributor] elects to include this software in this distribution
172.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
172.40 + * single choice of license, a recipient has the option to distribute
172.41 + * your version of this file under either the CDDL, the GPL Version 2 or
172.42 + * to extend the choice of license to its licensees as provided above.
172.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
172.44 + * Version 2 license, then the option applies only if the new code is
172.45 + * made subject to such option by the copyright holder.
172.46 + */
172.47 +package org.netbeans.modules.python.source.lexer;
172.48 +
172.49 +import org.netbeans.api.lexer.Token;
172.50 +import org.netbeans.spi.lexer.Lexer;
172.51 +import org.netbeans.spi.lexer.LexerInput;
172.52 +import org.netbeans.spi.lexer.LexerRestartInfo;
172.53 +import org.netbeans.spi.lexer.TokenFactory;
172.54 +
172.55 +/**
172.56 + * A lexer for python comments.
172.57 + *
172.58 + * Highlights TODO items and certain keywords (like @-param and @-type (without -)).
172.59 + *
172.60 + * @author Tor Norbye
172.61 + */
172.62 +public class PythonCommentLexer implements Lexer<PythonCommentTokenId> {
172.63 + private static final int EOF = LexerInput.EOF;
172.64 + private final LexerInput input;
172.65 + private final TokenFactory<PythonCommentTokenId> tokenFactory;
172.66 + private final boolean substituting;
172.67 +
172.68 + private static enum State {
172.69 + INIT,
172.70 + /** We've just seen @type */
172.71 + SEEN_TYPE_KEY,
172.72 + /** We've just seen @type< > */
172.73 + SEEN_TYPE_WS,
172.74 + /** We've just seen @type <varname> */
172.75 + SEEN_NAME,
172.76 + /** We've just seen @type varname< > */
172.77 + SEEN_NAME_WS
172.78 + };
172.79 + private State state;
172.80 +
172.81 + /**
172.82 + * A Lexer for Python strings
172.83 + * @param substituting If true, handle substitution rules for double quoted strings, otherwise
172.84 + * single quoted strings.
172.85 + */
172.86 + public PythonCommentLexer(LexerRestartInfo<PythonCommentTokenId> info, boolean substituting) {
172.87 + this.input = info.input();
172.88 + this.tokenFactory = info.tokenFactory();
172.89 + this.substituting = substituting;
172.90 + state = (State)info.state();
172.91 + if (state == null) {
172.92 + state = State.INIT;
172.93 + }
172.94 + }
172.95 +
172.96 + @Override
172.97 + public Object state() {
172.98 + return state;
172.99 + }
172.100 +
172.101 + @Override
172.102 + public Token<PythonCommentTokenId> nextToken() {
172.103 + switch (state) {
172.104 + case SEEN_NAME:
172.105 + case SEEN_TYPE_KEY:
172.106 + while (true) {
172.107 + int ch = input.read();
172.108 + if (ch == ':' && state == State.SEEN_NAME && input.readLength() == 1) {
172.109 + continue;
172.110 + }
172.111 + if (ch == EOF || !Character.isWhitespace(ch)) {
172.112 + if (ch != EOF) {
172.113 + input.backup(1);
172.114 + }
172.115 + if (input.readLength() > 0) {
172.116 + state = (state == State.SEEN_TYPE_KEY) ? State.SEEN_TYPE_WS : State.SEEN_NAME_WS;
172.117 + return tokenFactory.createToken(PythonCommentTokenId.SEPARATOR,
172.118 + input.readLength());
172.119 + } else {
172.120 + return null;
172.121 + }
172.122 + }
172.123 + }
172.124 +
172.125 + case SEEN_NAME_WS:
172.126 + case SEEN_TYPE_WS:
172.127 + while (true) {
172.128 + int ch = input.read();
172.129 + if (ch == EOF || Character.isWhitespace(ch) || ch == ':') {
172.130 + if (ch != EOF) {
172.131 + input.backup(1);
172.132 + }
172.133 + if (input.readLength() > 0) {
172.134 + State nextState;
172.135 + PythonCommentTokenId id;
172.136 + if (state == State.SEEN_TYPE_WS) {
172.137 + nextState = State.SEEN_NAME;
172.138 + id = PythonCommentTokenId.VARNAME;
172.139 + } else {
172.140 + nextState = State.INIT;
172.141 + id = PythonCommentTokenId.TYPE;
172.142 + }
172.143 + state = nextState;
172.144 + return tokenFactory.createToken(id, input.readLength());
172.145 + } else if (ch == EOF) {
172.146 + return null;
172.147 + } else {
172.148 + // Error - : without an actual var name
172.149 + state = State.INIT;
172.150 + return nextToken(); // recurse
172.151 + }
172.152 + }
172.153 + }
172.154 + default:
172.155 + case INIT: {
172.156 +
172.157 + int last = EOF;
172.158 + while (true) {
172.159 + int ch = input.read();
172.160 +
172.161 + switch (ch) {
172.162 + case EOF:
172.163 + if (input.readLength() > 0) {
172.164 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
172.165 + input.readLength());
172.166 + } else {
172.167 + return null;
172.168 + }
172.169 +
172.170 + case '@': {
172.171 + // Is it "@type"
172.172 + int initialReadLength = input.readLength();
172.173 + if (input.read() == 't' && input.read() == 'y' && input.read() == 'p' && input.read() == 'e') {
172.174 + if (input.readLength() > 5) {
172.175 + input.backup(5);
172.176 + // Finish this token such that we can do a dedicated token for the @type item.
172.177 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
172.178 + input.readLength());
172.179 + }
172.180 + state = State.SEEN_TYPE_KEY;
172.181 + return tokenFactory.createToken(PythonCommentTokenId.TYPEKEY,
172.182 + input.readLength());
172.183 + }
172.184 + if (input.readLength() > initialReadLength) {
172.185 + input.backup(input.readLength() - initialReadLength);
172.186 + } else {
172.187 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
172.188 + input.readLength());
172.189 + }
172.190 + }
172.191 + break;
172.192 +
172.193 + case 'T': {
172.194 + if (last == EOF || !Character.isLetter(last)) {
172.195 + // Is it "\wTODO\w" ?
172.196 + int initialReadLength = input.readLength();
172.197 + if (input.read() == 'O' && input.read() == 'D' && input.read() == 'O') {
172.198 + int peek = input.read();
172.199 + input.backup(1);
172.200 + if (peek == EOF || !Character.isLetter(peek)) {
172.201 + if (input.readLength() > 4) {
172.202 + input.backup(4);
172.203 + // Finish this token such that we can do a dedicated token for the @type item.
172.204 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
172.205 + input.readLength());
172.206 + }
172.207 + return tokenFactory.createToken(PythonCommentTokenId.TODO,
172.208 + input.readLength());
172.209 + }
172.210 + }
172.211 + if (input.readLength() > initialReadLength) {
172.212 + input.backup(input.readLength() - initialReadLength);
172.213 + } else {
172.214 + return tokenFactory.createToken(PythonCommentTokenId.TEXT,
172.215 + input.readLength());
172.216 + }
172.217 + }
172.218 + }
172.219 + break;
172.220 + }
172.221 +
172.222 + last = ch;
172.223 + }
172.224 +
172.225 + }
172.226 + }
172.227 + }
172.228 +
172.229 + @Override
172.230 + public void release() {
172.231 + }
172.232 +}
173.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
173.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonCommentTokenId.java Wed Sep 02 20:31:18 2015 +0200
173.3 @@ -0,0 +1,120 @@
173.4 +/*
173.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
173.6 + *
173.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
173.8 + *
173.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
173.10 + * Other names may be trademarks of their respective owners.
173.11 + *
173.12 + * The contents of this file are subject to the terms of either the GNU
173.13 + * General Public License Version 2 only ("GPL") or the Common
173.14 + * Development and Distribution License("CDDL") (collectively, the
173.15 + * "License"). You may not use this file except in compliance with the
173.16 + * License. You can obtain a copy of the License at
173.17 + * http://www.netbeans.org/cddl-gplv2.html
173.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
173.19 + * specific language governing permissions and limitations under the
173.20 + * License. When distributing the software, include this License Header
173.21 + * Notice in each file and include the License file at
173.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
173.23 + * particular file as subject to the "Classpath" exception as provided
173.24 + * by Oracle in the GPL Version 2 section of the License file that
173.25 + * accompanied this code. If applicable, add the following below the
173.26 + * License Header, with the fields enclosed by brackets [] replaced by
173.27 + * your own identifying information:
173.28 + * "Portions Copyrighted [year] [name of copyright owner]"
173.29 + *
173.30 + * Contributor(s):
173.31 + *
173.32 + * The Original Software is NetBeans. The Initial Developer of the Original
173.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
173.34 + * Microsystems, Inc. All Rights Reserved.
173.35 + *
173.36 + * If you wish your version of this file to be governed by only the CDDL
173.37 + * or only the GPL Version 2, indicate your decision by adding
173.38 + * "[Contributor] elects to include this software in this distribution
173.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
173.40 + * single choice of license, a recipient has the option to distribute
173.41 + * your version of this file under either the CDDL, the GPL Version 2 or
173.42 + * to extend the choice of license to its licensees as provided above.
173.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
173.44 + * Version 2 license, then the option applies only if the new code is
173.45 + * made subject to such option by the copyright holder.
173.46 + */
173.47 +package org.netbeans.modules.python.source.lexer;
173.48 +
173.49 +import java.util.Collection;
173.50 +import java.util.EnumSet;
173.51 +import java.util.Map;
173.52 +
173.53 +import org.netbeans.api.lexer.InputAttributes;
173.54 +import org.netbeans.api.lexer.Language;
173.55 +import org.netbeans.api.lexer.LanguagePath;
173.56 +import org.netbeans.api.lexer.Token;
173.57 +import org.netbeans.api.lexer.TokenId;
173.58 +import org.netbeans.spi.lexer.LanguageEmbedding;
173.59 +import org.netbeans.spi.lexer.LanguageHierarchy;
173.60 +import org.netbeans.spi.lexer.Lexer;
173.61 +import org.netbeans.spi.lexer.LexerRestartInfo;
173.62 +
173.63 +/**
173.64 + *
173.65 + * @author Tor Norbye
173.66 + */
173.67 +public enum PythonCommentTokenId implements TokenId {
173.68 + TEXT("comment"),
173.69 + KEYWORD("comment"),
173.70 + SEPARATOR("comment"),
173.71 + TYPEKEY("comment"),
173.72 + VARNAME("comment"),
173.73 + TYPE("comment"),
173.74 + TODO("comment");
173.75 + private final String primaryCategory;
173.76 +
173.77 + PythonCommentTokenId() {
173.78 + this(null);
173.79 + }
173.80 +
173.81 + PythonCommentTokenId(String primaryCategory) {
173.82 + this.primaryCategory = primaryCategory;
173.83 + }
173.84 +
173.85 + @Override
173.86 + public String primaryCategory() {
173.87 + return primaryCategory;
173.88 + }
173.89 + public static final Language<PythonCommentTokenId> language =
173.90 + new LanguageHierarchy<PythonCommentTokenId>() {
173.91 + @Override
173.92 + protected Collection<PythonCommentTokenId> createTokenIds() {
173.93 + return EnumSet.allOf(PythonCommentTokenId.class);
173.94 + }
173.95 +
173.96 + @Override
173.97 + protected Map<String, Collection<PythonCommentTokenId>> createTokenCategories() {
173.98 + return null; // no extra categories
173.99 + }
173.100 +
173.101 + @Override
173.102 + protected Lexer<PythonCommentTokenId> createLexer(
173.103 + LexerRestartInfo<PythonCommentTokenId> info) {
173.104 + return new PythonCommentLexer(info, true);
173.105 + }
173.106 +
173.107 + @Override
173.108 + protected LanguageEmbedding<?> embedding(
173.109 + Token<PythonCommentTokenId> token, LanguagePath languagePath,
173.110 + InputAttributes inputAttributes) {
173.111 + return null; // No embedding
173.112 + }
173.113 +
173.114 + @Override
173.115 + public String mimeType() {
173.116 + return "text/x-python-comment"; // NOI18N
173.117 + }
173.118 + }.language();
173.119 +
173.120 + public static Language<PythonCommentTokenId> language() {
173.121 + return language;
173.122 + }
173.123 +}
174.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
174.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonLexer.java Wed Sep 02 20:31:18 2015 +0200
174.3 @@ -0,0 +1,928 @@
174.4 +/*
174.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
174.6 + *
174.7 + * Copyright 1997-2010 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 + * Contributor(s):
174.31 + *
174.32 + * The Original Software is NetBeans. The Initial Developer of the Original
174.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
174.34 + * Microsystems, Inc. All Rights Reserved.
174.35 + *
174.36 + * If you wish your version of this file to be governed by only the CDDL
174.37 + * or only the GPL Version 2, indicate your decision by adding
174.38 + * "[Contributor] elects to include this software in this distribution
174.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
174.40 + * single choice of license, a recipient has the option to distribute
174.41 + * your version of this file under either the CDDL, the GPL Version 2 or
174.42 + * to extend the choice of license to its licensees as provided above.
174.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
174.44 + * Version 2 license, then the option applies only if the new code is
174.45 + * made subject to such option by the copyright holder.
174.46 + */
174.47 +package org.netbeans.modules.python.source.lexer;
174.48 +
174.49 +import org.netbeans.api.lexer.Token;
174.50 +import org.netbeans.api.lexer.TokenUtilities;
174.51 +import org.netbeans.spi.lexer.Lexer;
174.52 +import org.netbeans.spi.lexer.LexerInput;
174.53 +import org.netbeans.spi.lexer.LexerRestartInfo;
174.54 +import org.netbeans.spi.lexer.TokenFactory;
174.55 +
174.56 +/**
174.57 + * Lexer for Python.
174.58 + *
174.59 + * This is a hand written lexer for Python which recognizes the logical token types
174.60 + * we care about within the IDE support.
174.61 + *
174.62 + * Initially, we were using Jython's lexer directly here. However, that had some
174.63 + * problems:
174.64 + *
174.65 + * <ul>
174.66 + * <li>
174.67 + * In the IDE, we have to support incremental parsing. Not only is this a must
174.68 + * from a user performance perspective (typing a keystroke near the bottom of a
174.69 + * 2,000 line file shouldn't cause complete re-lexing of the entire document), but
174.70 + * the NetBeans APIs require it; they restart the lexer on the nearest token
174.71 + * boundary.
174.72 + * ANTLR doesn't support incremental lexing. I looked into what it would take
174.73 + * to patch it to do so (as I have done for JRuby in the Ruby support), but
174.74 + * it (a) wasn't trivial, and (b) would require a LOT of data to be stored for
174.75 + * every token boundary.
174.76 + * </li>
174.77 + * <li>
174.78 + * Similarly, we need to put our lexer on top of a LexerInput, and it is not
174.79 + * particularly compatible with the way ANTLR handles input. We had an
174.80 + * adapter class for this which was jumping through various hoops to expose
174.81 + * the LexerInput as ANTLR input. However, it had some severe problems with
174.82 + * large inputs.
174.83 + * </li>
174.84 + * <li>
174.85 + * We need slightly different token divisions. For example, for matching bracket
174.86 + * purposes, we'd like to have strings split into string delimiters and the
174.87 + * string contents. Similarly, Jython did some things like coalesce all whitespace
174.88 + * around a newline into that newline token which causes some complications
174.89 + * for our token analysis.
174.90 + * </li>
174.91 + * <li>
174.92 + * For Ruby, I decided to use the JRuby lexer because JRuby lexing is very
174.93 + * difficult. They have a huge complicated class to do the lexing - and there's
174.94 + * no Ruby language spec. Python on the other hand seems to have a very simple
174.95 + * lexing model, and a clear spec and grammar, so I don't feel worried that
174.96 + * our custom Python lexer is going to have a lot of corner case bugs.
174.97 + * </li>
174.98 + * </ul>
174.99 + *
174.100 + * @author Tor Norbye
174.101 + */
174.102 +public final class PythonLexer implements Lexer<PythonTokenId> {
174.103 + public static final String COMMENT_CAT = "comment";
174.104 + public static final String KEYWORD_CAT = "keyword"; // NOI18N
174.105 + public static final String STRING_CAT = "string"; // NOI18N
174.106 + public static final String WHITESPACE_CAT = "whitespace"; // NOI18N
174.107 + public static final String OPERATOR_CAT = "operator"; // NOI18N
174.108 + public static final String SEPARATOR_CAT = "separator"; // NOI18N
174.109 + public static final String ERROR_CAT = "error"; // NOI18N
174.110 + public static final String NUMBER_CAT = "number"; // NOI18N
174.111 + public static final String IDENTIFIER_CAT = "identifier"; // NOI18N
174.112 + private static final int EOF = LexerInput.EOF;
174.113 + private final LexerInput input;
174.114 + private final TokenFactory<PythonTokenId> tokenFactory;
174.115 +
174.116 + // Lexer state - preserved per token boundary
174.117 + private enum State {
174.118 + /** Normal state, same state as on entry into a Python file */
174.119 + INIT,
174.120 + /** We've processed the beginning string delimiter of a double-quoted short string */
174.121 + BEGIN_SHORTSTRING_DOUBLE,
174.122 + /** We've processed the beginning string delimiter of a single-quoted short string */
174.123 + BEGIN_SHORTSTRING_SINGLE,
174.124 + /** We've processed the beginning string delimiter of a double-quoted long string */
174.125 + BEGIN_LONGSTRING_DOUBLE,
174.126 + /** We've processed the beginning string delimiter of a singl-quoted long string */
174.127 + BEGIN_LONGSTRING_SINGLE,
174.128 + /** We've processed the string content in a double-quoted short string */
174.129 + END_SHORTSTRING_DOUBLE,
174.130 + /** We've processed the string content in a single-quoted short string */
174.131 + END_SHORTSTRING_SINGLE,
174.132 + /** We've processed the string content in a double-quoted long string */
174.133 + END_LONGSTRING_DOUBLE,
174.134 + /** We've processed the string content in a single-quoted long string */
174.135 + END_LONGSTRING_SINGLE,
174.136 + };
174.137 + private State state;
174.138 +
174.139 + public PythonLexer(LexerRestartInfo<PythonTokenId> info) {
174.140 + this.input = info.input();
174.141 + this.tokenFactory = info.tokenFactory();
174.142 +
174.143 + state = (State)info.state();
174.144 + if (state == null) {
174.145 + state = State.INIT;
174.146 + }
174.147 + }
174.148 +
174.149 + @Override
174.150 + public Object state() {
174.151 + return state;
174.152 + }
174.153 +
174.154 + private Token<PythonTokenId> createToken(PythonTokenId id, int tokenLength) {
174.155 + String fixedText = id.fixedText();
174.156 + return (fixedText != null) ? tokenFactory.getFlyweightToken(id, fixedText)
174.157 + : tokenFactory.createToken(id, tokenLength);
174.158 + }
174.159 +
174.160 + @SuppressWarnings("fallthrough")
174.161 + @Override
174.162 + public Token<PythonTokenId> nextToken() {
174.163 + switch (state) {
174.164 + case INIT: {
174.165 + int ch = input.read();
174.166 + switch (ch) {
174.167 + case EOF:
174.168 + return null;
174.169 +
174.170 + // Newline
174.171 + case '\n':
174.172 + assert input.readLength() == 1;
174.173 + return createToken(PythonTokenId.NEWLINE, 1);
174.174 +
174.175 + // Whitespace
174.176 + case ' ':
174.177 + case '\t': {
174.178 + for (; ch != EOF; ch = input.read()) {
174.179 + if (ch != ' ' && ch != '\t') {
174.180 + break;
174.181 + }
174.182 + }
174.183 + input.backup(1);
174.184 + return createToken(PythonTokenId.WHITESPACE, input.readLength());
174.185 + }
174.186 +
174.187 + // Comment
174.188 + case '#': {
174.189 + ch = input.read();
174.190 + while (ch != EOF && ch != '\n') {
174.191 + ch = input.read();
174.192 + }
174.193 + input.backup(1);
174.194 + return createToken(PythonTokenId.COMMENT, input.readLength());
174.195 + }
174.196 +
174.197 + case '.': {
174.198 + assert input.readLength() == 1;
174.199 + int peek = input.read();
174.200 + input.backup(1);
174.201 + if (!Character.isDigit(peek)) {
174.202 + return createToken(PythonTokenId.DOT, 1);
174.203 + } // else: Fallthrough to process the number!!
174.204 + } // FALLTHROUGH
174.205 + // FALLTHROUGH!!!!
174.206 +
174.207 + // Number (integer, float, complex)
174.208 + case '0':
174.209 + case '1':
174.210 + case '2':
174.211 + case '3':
174.212 + case '4':
174.213 + case '5':
174.214 + case '6':
174.215 + case '7':
174.216 + case '8':
174.217 + case '9': {
174.218 + if (ch == '0') {
174.219 + int peek = input.read();
174.220 + if (peek == 'x' || peek == 'X') {
174.221 + // Hex
174.222 + ch = input.read();
174.223 + while (ch != EOF) {
174.224 + if (!(Character.isDigit(ch) ||
174.225 + (ch >= 'a' && ch <= 'f') ||
174.226 + (ch >= 'A' && ch <= 'F'))) {
174.227 + break;
174.228 + }
174.229 + ch = input.read();
174.230 + }
174.231 + if (ch != 'l' && (ch != 'L')) {
174.232 + input.backup(1);
174.233 + }
174.234 + return createToken(PythonTokenId.INT_LITERAL, input.readLength());
174.235 + }
174.236 + input.backup(1);
174.237 + }
174.238 + boolean isFloat = false;
174.239 + digitLoop:
174.240 + for (; ch != EOF; ch = input.read()) {
174.241 + switch (ch) {
174.242 + case '0':
174.243 + case '1':
174.244 + case '2':
174.245 + case '3':
174.246 + case '4':
174.247 + case '5':
174.248 + case '6':
174.249 + case '7':
174.250 + case '8':
174.251 + case '9':
174.252 + continue;
174.253 + case '.':
174.254 + isFloat = true;
174.255 + continue;
174.256 + case 'e': // Exponent
174.257 + case 'E': {
174.258 + int peek = input.read();
174.259 + if (peek != '+' && peek != '-') {
174.260 + input.backup(1);
174.261 + }
174.262 + ch = input.read();
174.263 + while (ch != EOF) {
174.264 + if (!Character.isDigit(ch)) {
174.265 + break;
174.266 + }
174.267 + ch = input.read();
174.268 + }
174.269 + if (ch != 'j' && ch != 'J') {
174.270 + input.backup(1);
174.271 + }
174.272 + return createToken(PythonTokenId.FLOAT_LITERAL, input.readLength());
174.273 + }
174.274 + case 'j': // Imaginary
174.275 + case 'J':
174.276 + isFloat = true;
174.277 + break digitLoop;
174.278 + case 'l': // Long
174.279 + case 'L':
174.280 + break digitLoop;
174.281 + case EOF:
174.282 + default:
174.283 + input.backup(1);
174.284 + break digitLoop;
174.285 +
174.286 + }
174.287 + }
174.288 +
174.289 + return createToken(isFloat ? PythonTokenId.FLOAT_LITERAL : PythonTokenId.INT_LITERAL, input.readLength());
174.290 + }
174.291 +
174.292 + // Operators and delimiters
174.293 + case '+': // +,+=
174.294 + if (input.read() != '=') {
174.295 + input.backup(1);
174.296 + }
174.297 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.298 + case '-': // -,-=
174.299 + if (input.read() != '=') {
174.300 + input.backup(1);
174.301 + }
174.302 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.303 + case '*': { // *,**,*=, **=
174.304 + int peek = input.read();
174.305 + if (peek == '=') {
174.306 + // No need to back up, include it
174.307 + } else if (peek == '*') {
174.308 + peek = input.read();
174.309 + if (peek != '=') {
174.310 + input.backup(1);
174.311 + }
174.312 + } else {
174.313 + input.backup(1);
174.314 + }
174.315 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.316 + }
174.317 + case '/': {
174.318 + // Look for /,//, /=, //=
174.319 + int peek = input.read();
174.320 + if (peek == '=') {
174.321 + // No need to back up, include it
174.322 + } else if (peek == '/') {
174.323 + peek = input.read();
174.324 + if (peek != '=') {
174.325 + input.backup(1);
174.326 + }
174.327 + } else {
174.328 + input.backup(1);
174.329 + }
174.330 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.331 + }
174.332 + case '%': { // Look for %, %=
174.333 + if (input.read() != '=') {
174.334 + input.backup(1);
174.335 + }
174.336 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.337 + }
174.338 + case '<': {
174.339 + // Look for <, <<, <=, <>, <<=
174.340 + int peek = input.read();
174.341 + if (peek == '=') {
174.342 + // No need to back up, include it
174.343 + } else if (peek == '<') {
174.344 + peek = input.read();
174.345 + if (peek != '=') {
174.346 + input.backup(1);
174.347 + }
174.348 + } else if (peek != '>') {
174.349 + input.backup(1);
174.350 + }
174.351 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.352 + }
174.353 + case '>': {
174.354 + // Look for >, >>, >=, >>=
174.355 + int peek = input.read();
174.356 + if (peek == '=') {
174.357 + // No need to back up, include it
174.358 + } else if (peek == '>') {
174.359 + peek = input.read();
174.360 + if (peek != '=') {
174.361 + input.backup(1);
174.362 + }
174.363 + } else {
174.364 + input.backup(1);
174.365 + }
174.366 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.367 + }
174.368 + case '&': { // Look for &,&=
174.369 + if (input.read() != '=') {
174.370 + input.backup(1);
174.371 + }
174.372 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.373 + }
174.374 + case '|': { // Look for |, |=
174.375 + if (input.read() != '=') {
174.376 + input.backup(1);
174.377 + }
174.378 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.379 + }
174.380 + case '^': { // ^,^=
174.381 + if (input.read() != '=') {
174.382 + input.backup(1);
174.383 + }
174.384 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.385 + }
174.386 + case '=': {
174.387 + // Look for =,==
174.388 + if (input.read() != '=') {
174.389 + input.backup(1);
174.390 + }
174.391 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.392 + }
174.393 + case '!': {
174.394 + // Look for !=
174.395 + if (input.read() != '=') {
174.396 + input.backup(1);
174.397 + }
174.398 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.399 + }
174.400 + case '~':
174.401 + case '`':
174.402 + case ';':
174.403 + return createToken(PythonTokenId.ANY_OPERATOR, input.readLength());
174.404 +
174.405 + case ':':
174.406 + assert input.readLength() == 1;
174.407 + return createToken(PythonTokenId.COLON, 1);
174.408 + case '(':
174.409 + assert input.readLength() == 1;
174.410 + return createToken(PythonTokenId.LPAREN, 1);
174.411 + case ')':
174.412 + assert input.readLength() == 1;
174.413 + return createToken(PythonTokenId.RPAREN, 1);
174.414 + case '[':
174.415 + assert input.readLength() == 1;
174.416 + return createToken(PythonTokenId.LBRACKET, 1);
174.417 + case ']':
174.418 + assert input.readLength() == 1;
174.419 + return createToken(PythonTokenId.RBRACKET, 1);
174.420 + case '{':
174.421 + assert input.readLength() == 1;
174.422 + return createToken(PythonTokenId.LBRACE, 1);
174.423 + case '}':
174.424 + assert input.readLength() == 1;
174.425 + return createToken(PythonTokenId.RBRACE, 1);
174.426 + case ',':
174.427 + assert input.readLength() == 1;
174.428 + return createToken(PythonTokenId.COMMA, 1);
174.429 + case '\\':
174.430 + assert input.readLength() == 1;
174.431 + return createToken(PythonTokenId.ESC, 1);
174.432 +
174.433 + case '$':
174.434 + case '?':
174.435 + assert input.readLength() == 1;
174.436 + return createToken(PythonTokenId.ERROR, 1);
174.437 +
174.438 + // String?
174.439 + case '\'':
174.440 + case '"': {
174.441 + int peek = input.read();
174.442 + if (peek != ch) {
174.443 + input.backup(1);
174.444 + assert input.readLength() == 1;
174.445 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
174.446 + return createToken(PythonTokenId.STRING_BEGIN, 1);
174.447 + }
174.448 + // We've seen two quotes... it's either an empty string,
174.449 + // or the beginning of a longstring
174.450 + int peek2 = input.read();
174.451 + if (peek2 == peek) {
174.452 + // It's a longstring!
174.453 + assert input.readLength() == 3;
174.454 + state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
174.455 + return createToken(PythonTokenId.STRING_BEGIN, 3);
174.456 + } else {
174.457 + input.backup(2);
174.458 + assert input.readLength() == 1;
174.459 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
174.460 + return createToken(PythonTokenId.STRING_BEGIN, 1);
174.461 + }
174.462 + }
174.463 + case '@': { // Decorator
174.464 + // Identifier or keyword?
174.465 + ch = input.read();
174.466 + if (Character.isJavaIdentifierStart(ch)) {
174.467 + while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
174.468 + ch = input.read();
174.469 + }
174.470 + input.backup(1);
174.471 +
174.472 + return createToken(PythonTokenId.DECORATOR, input.readLength());
174.473 + }
174.474 + input.backup(1); // Remove the peeked char
174.475 +
174.476 + assert input.readLength() == 1;
174.477 + return createToken(PythonTokenId.DECORATOR, 1);
174.478 + }
174.479 +
174.480 + case 'r':
174.481 + case 'R':
174.482 + case 'u':
174.483 + case 'U': {
174.484 + // Digest the "u" and the "r" and position the input
174.485 + // before the following ' or "
174.486 + boolean isStringPrefix = false;
174.487 + int peek = input.read();
174.488 + if (ch == 'r' || ch == 'R') {
174.489 + if (peek == '\'' || peek == '"') {
174.490 + isStringPrefix = true;
174.491 + }
174.492 + input.backup(1);
174.493 + } else {
174.494 + assert ch == 'u' || ch == 'U';
174.495 + if (peek == 'r' || peek == 'R') {
174.496 + int peek2 = input.read();
174.497 + if (peek2 == '\'' || peek2 == '"') {
174.498 + isStringPrefix = true;
174.499 + }
174.500 + input.backup(1);
174.501 + } else if (peek == '\'' || peek == '"') {
174.502 + isStringPrefix = true;
174.503 + input.backup(1);
174.504 + }
174.505 + if (!isStringPrefix) {
174.506 + input.backup(1);
174.507 + }
174.508 + }
174.509 + if (isStringPrefix) {
174.510 + ch = input.read();
174.511 + assert ch == '\'' || ch == '"';
174.512 +
174.513 + peek = input.read();
174.514 + if (peek != ch) {
174.515 + input.backup(1);
174.516 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
174.517 + return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
174.518 + }
174.519 + // We've seen two quotes... it's either an empty string,
174.520 + // or the beginning of a longstring
174.521 + int peek2 = input.read();
174.522 + if (peek2 == peek) {
174.523 + // It's a longstring!
174.524 + state = (ch == '"') ? State.BEGIN_LONGSTRING_DOUBLE : State.BEGIN_LONGSTRING_SINGLE;
174.525 + return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
174.526 + } else {
174.527 + input.backup(2);
174.528 + state = (ch == '"') ? State.BEGIN_SHORTSTRING_DOUBLE : State.BEGIN_SHORTSTRING_SINGLE;
174.529 + return createToken(PythonTokenId.STRING_BEGIN, input.readLength());
174.530 + }
174.531 + }// else: FALLTHROUGH!!! The "u" or "r" is probably an identifier prefix!!
174.532 + }
174.533 + // Fallthrough...
174.534 +
174.535 + default: {
174.536 + // Identifier or keyword?
174.537 + if (Character.isJavaIdentifierStart(ch)) {
174.538 + while (ch != EOF && Character.isJavaIdentifierPart(ch) && ch != '$') {
174.539 + ch = input.read();
174.540 + }
174.541 + input.backup(1);
174.542 +
174.543 + // See if it's a keyword
174.544 + PythonTokenId pid = getKeywordToken(input.readText());
174.545 + if (pid != null) {
174.546 + return createToken(pid, input.readLength());
174.547 + } else {
174.548 + return createToken(PythonTokenId.IDENTIFIER, input.readLength());
174.549 + }
174.550 + }
174.551 +
174.552 + assert input.readLength() == 1;
174.553 + return createToken(PythonTokenId.ANY_OPERATOR, 1);
174.554 + }
174.555 + }
174.556 + }
174.557 +
174.558 + case BEGIN_LONGSTRING_SINGLE:
174.559 + case BEGIN_LONGSTRING_DOUBLE: {
174.560 + // In a long string. Look for the end.
174.561 + int ch = input.read();
174.562 + if (ch == EOF) {
174.563 + return null;
174.564 + }
174.565 + int term = (state == State.BEGIN_LONGSTRING_DOUBLE) ? '"' : '\'';
174.566 + while (ch != EOF) {
174.567 + if (ch == '\\') {
174.568 + // It's an escape - read escaped char
174.569 + input.read();
174.570 + } else if (ch == term) {
174.571 + int peek = input.read();
174.572 + if (peek == term) {
174.573 + int peek2 = input.read();
174.574 + if (peek2 == term) {
174.575 + // Found the end
174.576 + if (input.readLength() == 3) {
174.577 + // Empty string - go straight to closed state
174.578 + state = State.INIT;
174.579 + return createToken(PythonTokenId.STRING_END, input.readLength());
174.580 + }
174.581 + input.backup(3);
174.582 + if (state == State.BEGIN_LONGSTRING_DOUBLE) {
174.583 + state = State.END_LONGSTRING_DOUBLE;
174.584 + } else {
174.585 + assert state == State.BEGIN_LONGSTRING_SINGLE;
174.586 + state = State.END_LONGSTRING_SINGLE;
174.587 + }
174.588 + return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
174.589 + }
174.590 + input.backup(1);
174.591 + }
174.592 + input.backup(1);
174.593 + }
174.594 + ch = input.read();
174.595 + }
174.596 + // Literal not terminated
174.597 + state = State.INIT;
174.598 + return createToken(PythonTokenId.ERROR, input.readLength());
174.599 + }
174.600 + case BEGIN_SHORTSTRING_SINGLE:
174.601 + case BEGIN_SHORTSTRING_DOUBLE: {
174.602 + // In a short string. Look for the end.
174.603 + int ch = input.read();
174.604 + if (ch == EOF) {
174.605 + return null;
174.606 + }
174.607 + int term = (state == State.BEGIN_SHORTSTRING_DOUBLE) ? '"' : '\'';
174.608 + while (ch != EOF) {
174.609 + if (ch == '\\') {
174.610 + // It's an escape - read escaped char
174.611 + input.read();
174.612 + } else if (ch == '\n') {
174.613 + // Literal not terminated
174.614 + state = State.INIT;
174.615 + return createToken(PythonTokenId.ERROR, input.readLength());
174.616 + } else if (ch == term) {
174.617 + if (input.readLength() == 1) {
174.618 + // It's an empty string! Skip straight to the end state
174.619 + state = State.INIT;
174.620 + return createToken(PythonTokenId.STRING_END, input.readLength());
174.621 + }
174.622 + input.backup(1);
174.623 + if (state == State.BEGIN_SHORTSTRING_DOUBLE) {
174.624 + state = State.END_SHORTSTRING_DOUBLE;
174.625 + } else {
174.626 + assert state == State.BEGIN_SHORTSTRING_SINGLE;
174.627 + state = State.END_SHORTSTRING_SINGLE;
174.628 + }
174.629 + return createToken(PythonTokenId.STRING_LITERAL, input.readLength());
174.630 + }
174.631 + ch = input.read();
174.632 + }
174.633 + // Literal not terminated
174.634 + state = State.INIT;
174.635 + return createToken(PythonTokenId.ERROR, input.readLength());
174.636 + }
174.637 +
174.638 + case END_LONGSTRING_SINGLE:
174.639 + case END_LONGSTRING_DOUBLE: {
174.640 + // In a long string. Look for the end.
174.641 + int ch = input.read();
174.642 + if (ch == EOF) {
174.643 + return null;
174.644 + }
174.645 + int term = (state == State.END_LONGSTRING_DOUBLE) ? '"' : '\'';
174.646 + while (ch != EOF) {
174.647 + if (ch == term) {
174.648 + int peek = input.read();
174.649 + if (peek == term) {
174.650 + int peek2 = input.read();
174.651 + if (peek2 == term) {
174.652 + // Found the end
174.653 + state = State.INIT;
174.654 + return createToken(PythonTokenId.STRING_END, input.readLength());
174.655 + }
174.656 + input.backup(1);
174.657 + }
174.658 + input.backup(1);
174.659 + }
174.660 + ch = input.read();
174.661 + }
174.662 + // Literal not terminated
174.663 + state = State.INIT;
174.664 + return createToken(PythonTokenId.ERROR, input.readLength());
174.665 + }
174.666 + case END_SHORTSTRING_SINGLE:
174.667 + case END_SHORTSTRING_DOUBLE: {
174.668 + // In a short string. Look for the end.
174.669 + int ch = input.read();
174.670 + if (ch == EOF) {
174.671 + return null;
174.672 + }
174.673 + int term = (state == State.END_SHORTSTRING_DOUBLE) ? '"' : '\'';
174.674 + if (ch == term) {
174.675 + state = State.INIT;
174.676 + return createToken(PythonTokenId.STRING_END, input.readLength());
174.677 + }
174.678 + state = State.INIT;
174.679 + return createToken(PythonTokenId.ERROR, input.readLength());
174.680 + }
174.681 +
174.682 + default:
174.683 + assert false : state;
174.684 + }
174.685 +
174.686 + return null;
174.687 + }
174.688 +
174.689 + @Override
174.690 + public void release() {
174.691 + }
174.692 +
174.693 + private PythonTokenId getKeywordToken(CharSequence s) {
174.694 + int length = s.length();
174.695 + if (length < 2) {
174.696 + return null;
174.697 + }
174.698 +
174.699 + if (s.toString().endsWith("Error")) {
174.700 + return PythonTokenId.ERROR;
174.701 + }
174.702 +
174.703 + char c1 = s.charAt(0);
174.704 + char c2 = s.charAt(1);
174.705 +
174.706 + switch (c1) {
174.707 + case 'a': // and, as, assert, async, await
174.708 + switch (c2) {
174.709 + case 'n': // and
174.710 + if (TokenUtilities.textEquals(s, "and")) { // NOI18N
174.711 + return PythonTokenId.ANY_KEYWORD;
174.712 + }
174.713 + break;
174.714 + case 's': // as, assert, async
174.715 + if (length == 2) { // as
174.716 + return PythonTokenId.ANY_KEYWORD;
174.717 + }
174.718 + if (length == 6 && TokenUtilities.textEquals(s, "assert")) { // NOI18N
174.719 + return PythonTokenId.ANY_KEYWORD;
174.720 + }
174.721 + if (length == 5 && TokenUtilities.textEquals(s, "async")) { // NOI18N
174.722 + return PythonTokenId.ANY_KEYWORD;
174.723 + }
174.724 + break;
174.725 + case 'w': // await
174.726 + if (length == 5 && TokenUtilities.textEquals(s, "await")) { // NOI18N
174.727 + return PythonTokenId.ANY_KEYWORD;
174.728 + }
174.729 + }
174.730 + break;
174.731 + case 'b': // break, bytes
174.732 + if (length == 5 && TokenUtilities.textEquals(s, "break")) { // NOI18N
174.733 + return PythonTokenId.ANY_KEYWORD;
174.734 + } else if (length == 5 && TokenUtilities.textEquals(s, "bytes")) { // NOI18N
174.735 + return PythonTokenId.STD_SYMBOLS;
174.736 + }
174.737 + break;
174.738 + case 'c': // class, continue
174.739 + switch (c2) {
174.740 + case 'l': // class
174.741 + if (length == 5 && TokenUtilities.textEquals(s, "class")) { // NOI18N
174.742 + return PythonTokenId.CLASS;
174.743 + }
174.744 + break;
174.745 + case 'o': // continue
174.746 + if (length == 8 && TokenUtilities.textEquals(s, "continue")) { // NOI18N
174.747 + return PythonTokenId.ANY_KEYWORD;
174.748 + }
174.749 + break;
174.750 + }
174.751 + break;
174.752 + case 'd': // def, del
174.753 + if (c2 == 'e' && length == 3) { // def, del
174.754 + char c3 = s.charAt(2);
174.755 + if (c3 == 'f') { // def
174.756 + return PythonTokenId.DEF;
174.757 + } else if (c3 == 'l') { // del
174.758 + return PythonTokenId.ANY_KEYWORD;
174.759 + }
174.760 + }
174.761 + break;
174.762 + case 'e': // elif, else, except, exec
174.763 + switch (c2) {
174.764 + case 'l': // elif, else
174.765 + if (length == 4) {
174.766 + if (TokenUtilities.textEquals(s, "elif")) { // NOI18N
174.767 + return PythonTokenId.ELIF;
174.768 + }
174.769 + if (TokenUtilities.textEquals(s, "else")) { // NOI18N
174.770 + return PythonTokenId.ELSE;
174.771 + }
174.772 + }
174.773 + break;
174.774 + case 'n': // enumerate
174.775 + if (length == 9 && TokenUtilities.textEquals(s, "enumerate")) { // NOI18N
174.776 + return PythonTokenId.STD_SYMBOLS;
174.777 + }
174.778 + case 'x': // except, exec
174.779 + if (length == 4 && TokenUtilities.textEquals(s, "exec")) { // NOI18N
174.780 + return PythonTokenId.ANY_KEYWORD;
174.781 + }
174.782 + if (length == 6 && TokenUtilities.textEquals(s, "except")) { // NOI18N
174.783 + return PythonTokenId.EXCEPT;
174.784 + }
174.785 + break;
174.786 + }
174.787 + break;
174.788 + case 'f': // finally,for,from
174.789 + switch (c2) {
174.790 + case 'i': // finally
174.791 + if (length == 7 && TokenUtilities.textEquals(s, "finally")) { // NOI18N
174.792 + return PythonTokenId.FINALLY;
174.793 + }
174.794 + break;
174.795 + case 'o': // for
174.796 + if (length == 3 && TokenUtilities.textEquals(s, "for")) { // NOI18N
174.797 + return PythonTokenId.ANY_KEYWORD;
174.798 + }
174.799 + break;
174.800 + case 'r': // from
174.801 + if (length == 4 && TokenUtilities.textEquals(s, "from")) { // NOI18N
174.802 + return PythonTokenId.FROM;
174.803 + }
174.804 + break;
174.805 + case 'l':
174.806 + if (length == 5 && TokenUtilities.textEquals(s, "float")) {
174.807 + return PythonTokenId.STD_SYMBOLS;
174.808 + }
174.809 + }
174.810 + break;
174.811 + case 'g': // global
174.812 + if (length == 6 && TokenUtilities.textEquals(s, "global")) { // NOI18N
174.813 + return PythonTokenId.ANY_KEYWORD;
174.814 + }
174.815 + break;
174.816 + case 'i': // if,import,in,is, int
174.817 + if (length == 2) {
174.818 + switch (c2) {
174.819 + case 'f': // if
174.820 + return PythonTokenId.IF;
174.821 + case 'n': // in
174.822 + if (length == 2 && TokenUtilities.textEquals(s, "in")) { //NOI18N
174.823 + return PythonTokenId.ANY_KEYWORD;
174.824 + }
174.825 + case 's': // is
174.826 + return PythonTokenId.ANY_KEYWORD;
174.827 + }
174.828 + } else if (c2 == 'm' && length == 6 && TokenUtilities.textEquals(s, "import")) { // NOI18N
174.829 + // import
174.830 + return PythonTokenId.IMPORT;
174.831 + } else if (length == 3 && TokenUtilities.textEquals(s, "int")) { // NOI18N
174.832 + return PythonTokenId.STD_SYMBOLS;
174.833 + } else if (length == 10 && TokenUtilities.textEquals(s, "isinstance")) { // NOI18N
174.834 + return PythonTokenId.STD_SYMBOLS;
174.835 + }
174.836 + break;
174.837 + case 'l': // lambda, len, list
174.838 + if (length == 6 && TokenUtilities.textEquals(s, "lambda")) { // NOI18N
174.839 + return PythonTokenId.ANY_KEYWORD;
174.840 + } else if (length == 3 && TokenUtilities.textEquals(s, "len")) { // NOI18N
174.841 + return PythonTokenId.STD_SYMBOLS;
174.842 + } else if (length == 4 && TokenUtilities.textEquals(s, "list")) { // NOI18N
174.843 + return PythonTokenId.STD_SYMBOLS;
174.844 + }
174.845 + break;
174.846 + case 'n': // not
174.847 + if (length == 3 && TokenUtilities.textEquals(s, "not")) { // NOI18N
174.848 + return PythonTokenId.ANY_KEYWORD;
174.849 + }
174.850 + break;
174.851 + case 'o': // or, object
174.852 + if (length == 2 && TokenUtilities.textEquals(s, "or")) { // NOI18N
174.853 + return PythonTokenId.ANY_KEYWORD;
174.854 + } else if (length == 6 && TokenUtilities.textEquals(s, "object")) { // NOI18N
174.855 + return PythonTokenId.STD_SYMBOLS;
174.856 + }
174.857 + break;
174.858 + case 'p': // pass,print
174.859 + if (c2 == 'a') { // pass
174.860 + if (length == 4 && TokenUtilities.textEquals(s, "pass")) { // NOI18N
174.861 + return PythonTokenId.PASS;
174.862 + }
174.863 + } else if (c2 == 'r') { // print
174.864 + if (length == 5 && TokenUtilities.textEquals(s, "print")) { // NOI18N
174.865 + return PythonTokenId.ANY_KEYWORD;
174.866 + }
174.867 + }
174.868 + break;
174.869 + case 'r': // raise,return
174.870 + if (c2 == 'a') { // raise
174.871 + if (length == 5 && TokenUtilities.textEquals(s, "raise")) { // NOI18N
174.872 + return PythonTokenId.RAISE;
174.873 + }
174.874 + } else if (c2 == 'e') { // return
174.875 + if (length == 6 && TokenUtilities.textEquals(s, "return")) { // NOI18N
174.876 + return PythonTokenId.RETURN;
174.877 + }
174.878 + }
174.879 + break;
174.880 + case 's': // self, set, str, super
174.881 + if (length == 4 && TokenUtilities.textEquals(s, "self")) { // NOI18N
174.882 + return PythonTokenId.ANY_KEYWORD;
174.883 + } else if (length == 3 && TokenUtilities.textEquals(s, "set")) { // NOI18N
174.884 + return PythonTokenId.STD_SYMBOLS;
174.885 + } else if (length == 3 && TokenUtilities.textEquals(s, "str")) { // NOI18N
174.886 + return PythonTokenId.STD_SYMBOLS;
174.887 + } else if (length == 5 && TokenUtilities.textEquals(s, "super")) { // NOI18N
174.888 + return PythonTokenId.ANY_KEYWORD;
174.889 + }
174.890 + case 't': // try, tuple, type
174.891 + if (length == 3 && TokenUtilities.textEquals(s, "try")) { // NOI18N
174.892 + return PythonTokenId.TRY;
174.893 + } else if (length == 5 && TokenUtilities.textEquals(s, "tuple")) { // NOI18N
174.894 + return PythonTokenId.STD_SYMBOLS;
174.895 + } else if (length == 4 && TokenUtilities.textEquals(s, "type")) { // NOI18N
174.896 + return PythonTokenId.STD_SYMBOLS;
174.897 + }
174.898 + break;
174.899 + case 'w': // while,with
174.900 + if (c2 == 'h') { // while
174.901 + if (length == 5 && TokenUtilities.textEquals(s, "while")) { // NOI18N
174.902 + return PythonTokenId.ANY_KEYWORD;
174.903 + }
174.904 + } else if (c2 == 'i') { // with
174.905 + if (length == 4 && TokenUtilities.textEquals(s, "with")) { // NOI18N
174.906 + return PythonTokenId.ANY_KEYWORD;
174.907 + }
174.908 + }
174.909 + break;
174.910 + case 'y': // yield
174.911 + if (length == 5 && TokenUtilities.textEquals(s, "yield")) { // NOI18N
174.912 + return PythonTokenId.ANY_KEYWORD;
174.913 + }
174.914 + break;
174.915 + case 'F': // False
174.916 + if (length == 5 && TokenUtilities.textEquals(s, "False")) { // NOI18N
174.917 + return PythonTokenId.FALSE;
174.918 + }
174.919 + case 'N': // None
174.920 + if (length == 4 && TokenUtilities.textEquals(s, "None")) { // NOI18N
174.921 + return PythonTokenId.NONE;
174.922 + }
174.923 + case 'T': // True
174.924 + if (length == 4 && TokenUtilities.textEquals(s, "True")) { // NOI18N
174.925 + return PythonTokenId.TRUE;
174.926 + }
174.927 + }
174.928 +
174.929 + return null;
174.930 + }
174.931 +}
175.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
175.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonLexerUtils.java Wed Sep 02 20:31:18 2015 +0200
175.3 @@ -0,0 +1,558 @@
175.4 +/*
175.5 + * To change this template, choose Tools | Templates
175.6 + * and open the template in the editor.
175.7 + */
175.8 +package org.netbeans.modules.python.source.lexer;
175.9 +
175.10 +import java.util.Arrays;
175.11 +import java.util.List;
175.12 +import java.util.regex.Matcher;
175.13 +import java.util.regex.Pattern;
175.14 +import javax.swing.text.BadLocationException;
175.15 +import javax.swing.text.Document;
175.16 +import org.netbeans.api.lexer.Token;
175.17 +import org.netbeans.api.lexer.TokenHierarchy;
175.18 +import org.netbeans.api.lexer.TokenId;
175.19 +import org.netbeans.api.lexer.TokenSequence;
175.20 +import org.netbeans.editor.BaseDocument;
175.21 +import org.netbeans.editor.Utilities;
175.22 +import org.netbeans.modules.csl.api.OffsetRange;
175.23 +import org.netbeans.modules.python.source.PythonParserResult;
175.24 +import org.openide.filesystems.FileUtil;
175.25 +import org.openide.loaders.DataObject;
175.26 +import org.openide.util.Exceptions;
175.27 +import org.python.antlr.PythonTree;
175.28 +
175.29 +/**
175.30 + * Utility functions around the Python lexer
175.31 + *
175.32 + * @author Tor Norbye
175.33 + */
175.34 +public class PythonLexerUtils {
175.35 + /**
175.36 + * Try to produce a more accurate location for the given name in the given import statement, located
175.37 + * at the lexRange provided
175.38 + */
175.39 + public static OffsetRange getImportNameOffset(BaseDocument doc, OffsetRange lexRange, PythonTree node, String name) {
175.40 + int docLength = doc.getLength();
175.41 + int start = Math.min(docLength, lexRange.getStart());
175.42 + int end = Math.min(docLength, lexRange.getEnd());
175.43 + try {
175.44 + String s = doc.getText(start, end - start);
175.45 +
175.46 + Pattern p = Pattern.compile(".*import\\s+\\b(" + name + ")\\b.*");
175.47 + Matcher m = p.matcher(s);
175.48 + if (m.matches()) {
175.49 + int offset = start + m.start(1);
175.50 + return new OffsetRange(offset, offset + name.length());
175.51 + }
175.52 +
175.53 + // Lame
175.54 + int searchIndex = s.indexOf("import ");
175.55 + if (searchIndex == -1) {
175.56 + searchIndex = 0;
175.57 + } else {
175.58 + searchIndex += 7;
175.59 + }
175.60 + int match = s.indexOf(name, searchIndex + 7);
175.61 + if (match != -1) {
175.62 + int offset = start + match;
175.63 + return new OffsetRange(offset, offset + name.length());
175.64 + }
175.65 +
175.66 + // Give up - use the whole range
175.67 + } catch (BadLocationException ex) {
175.68 + Exceptions.printStackTrace(ex);
175.69 + }
175.70 +
175.71 + return lexRange;
175.72 + }
175.73 +
175.74 + /** For a possibly generated offset in an AST, return the corresponding lexing/true document offset */
175.75 + public static int getLexerOffset(PythonParserResult result, int astOffset) {
175.76 + return result.getSnapshot().getOriginalOffset(astOffset);
175.77 + }
175.78 +
175.79 + public static OffsetRange getLexerOffsets(PythonParserResult result, OffsetRange astRange) {
175.80 + if (result != null) {
175.81 + int rangeStart = astRange.getStart();
175.82 + int start = result.getSnapshot().getOriginalOffset(rangeStart);
175.83 + if (start == rangeStart) {
175.84 + return astRange;
175.85 + } else if (start == -1) {
175.86 + return OffsetRange.NONE;
175.87 + } else {
175.88 + // Assumes the translated range maintains size
175.89 + return new OffsetRange(start, start + astRange.getLength());
175.90 + }
175.91 + }
175.92 +
175.93 + return astRange;
175.94 + }
175.95 +
175.96 + /**
175.97 + * Narrow a given lexical offset range to the closest AST-relevant offsets.
175.98 + * This means it will pass over things like comments and whitespace.
175.99 + * @param doc The document containing the range
175.100 + * @param range The start/end lexical range we want to narrow
175.101 + * @return An OffsetRange where the offsets begin and end at AST-relevant tokens
175.102 + */
175.103 + public static OffsetRange narrow(BaseDocument doc, OffsetRange range, boolean skipComments) {
175.104 + try {
175.105 + doc.readLock(); // For token hiearchy use
175.106 + // For token hiearchy use
175.107 + int start = range.getStart();
175.108 + TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, start);
175.109 + if (ts != null) {
175.110 + int delta = ts.move(start);
175.111 + while (ts.moveNext()) {
175.112 + Token<? extends PythonTokenId> token = ts.token();
175.113 + PythonTokenId id = token.id();
175.114 + if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
175.115 + if (delta != 0) {
175.116 + return OffsetRange.NONE;
175.117 + }
175.118 + start = ts.offset();
175.119 + break;
175.120 + } else {
175.121 + delta = 0;
175.122 + }
175.123 + }
175.124 + }
175.125 + int end = range.getEnd();
175.126 + ts = getPositionedSequence(doc, end);
175.127 + if (ts != null) {
175.128 + int delta = ts.move(end);
175.129 + while (delta > 0 ? ts.moveNext() : ts.movePrevious()) {
175.130 + Token<? extends PythonTokenId> token = ts.token();
175.131 + PythonTokenId id = token.id();
175.132 + if (id != PythonTokenId.NEWLINE && (!skipComments || id != PythonTokenId.COMMENT) && id != PythonTokenId.WHITESPACE) {
175.133 + if (delta != 0) {
175.134 + return OffsetRange.NONE;
175.135 + }
175.136 + end = ts.offset() + token.length();
175.137 + break;
175.138 + } else {
175.139 + delta = 0;
175.140 + }
175.141 + }
175.142 + }
175.143 +
175.144 + if (end < start) {
175.145 + return OffsetRange.NONE;
175.146 + }
175.147 +
175.148 + return new OffsetRange(start, end);
175.149 + } finally {
175.150 + doc.readUnlock();
175.151 + }
175.152 + }
175.153 +
175.154 + /** Find the ruby token sequence (in case it's embedded in something else at the top level */
175.155 + @SuppressWarnings("unchecked")
175.156 + public static TokenSequence<? extends PythonTokenId> getPythonSequence(BaseDocument doc, int offset) {
175.157 + TokenHierarchy<Document> th = TokenHierarchy.get((Document)doc);
175.158 + return getPythonSequence(th, offset);
175.159 + }
175.160 +
175.161 + @SuppressWarnings("unchecked")
175.162 + public static TokenSequence<? extends PythonTokenId> getPythonSequence(TokenHierarchy<Document> th, int offset) {
175.163 + TokenSequence<? extends PythonTokenId> ts = th.tokenSequence(PythonTokenId.language());
175.164 +
175.165 + if (ts == null) {
175.166 + // Possibly an embedding scenario such as an RHTML file
175.167 + // First try with backward bias true
175.168 + List<TokenSequence<?>> list = th.embeddedTokenSequences(offset, true);
175.169 +
175.170 + for (TokenSequence t : list) {
175.171 + if (t.language() == PythonTokenId.language()) {
175.172 + ts = t;
175.173 +
175.174 + break;
175.175 + }
175.176 + }
175.177 +
175.178 + if (ts == null) {
175.179 + list = th.embeddedTokenSequences(offset, false);
175.180 +
175.181 + for (TokenSequence t : list) {
175.182 + if (t.language() == PythonTokenId.language()) {
175.183 + ts = t;
175.184 +
175.185 + break;
175.186 + }
175.187 + }
175.188 + }
175.189 + }
175.190 +
175.191 + return ts;
175.192 + }
175.193 +
175.194 + public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset) {
175.195 + return getPositionedSequence(doc, offset, true);
175.196 + }
175.197 +
175.198 + public static TokenSequence<? extends PythonTokenId> getPositionedSequence(BaseDocument doc, int offset, boolean lookBack) {
175.199 + TokenSequence<? extends PythonTokenId> ts = getPythonSequence(doc, offset);
175.200 +
175.201 + if (ts != null) {
175.202 + try {
175.203 + ts.move(offset);
175.204 + } catch (AssertionError e) {
175.205 + DataObject dobj = (DataObject)doc.getProperty(Document.StreamDescriptionProperty);
175.206 +
175.207 + if (dobj != null) {
175.208 + Exceptions.attachMessage(e, FileUtil.getFileDisplayName(dobj.getPrimaryFile()));
175.209 + }
175.210 +
175.211 + throw e;
175.212 + }
175.213 +
175.214 + if (!lookBack && !ts.moveNext()) {
175.215 + return null;
175.216 + } else if (lookBack && !ts.moveNext() && !ts.movePrevious()) {
175.217 + return null;
175.218 + }
175.219 +
175.220 + /* TODO - allow Python inside strings
175.221 + if (ts.token().id() == PythonTokenId.STRING_LITERAL) {
175.222 + TokenSequence<? extends PythonStringTokenId> ets = ts.embedded(PythonStringTokenId.language());
175.223 + if (ets != null) {
175.224 + ets.move(offset);
175.225 + if ((!lookBack && ets.moveNext()) || (lookBack && ets.movePrevious())) {
175.226 + TokenSequence<?extends PythonTokenId> epts = ets.embedded(PythonTokenId.language());
175.227 + if (epts != null) {
175.228 + epts.move(offset);
175.229 + if (!lookBack && !epts.moveNext()) {
175.230 + return null;
175.231 + } else if (lookBack && !epts.moveNext() && !epts.movePrevious()) {
175.232 + return null;
175.233 + }
175.234 + return epts;
175.235 + }
175.236 + }
175.237 + }
175.238 + }
175.239 + */
175.240 +
175.241 + return ts;
175.242 + }
175.243 +
175.244 + return null;
175.245 + }
175.246 +
175.247 + public static Token<? extends PythonTokenId> getToken(BaseDocument doc, int offset) {
175.248 + TokenSequence<? extends PythonTokenId> ts = getPositionedSequence(doc, offset);
175.249 +
175.250 + if (ts != null) {
175.251 + return ts.token();
175.252 + }
175.253 +
175.254 + return null;
175.255 + }
175.256 +
175.257 + public static char getTokenChar(BaseDocument doc, int offset) {
175.258 + Token<? extends PythonTokenId> token = getToken(doc, offset);
175.259 +
175.260 + if (token != null) {
175.261 + String text = token.text().toString();
175.262 +
175.263 + if (text.length() > 0) { // Usually true, but I could have gotten EOF right?
175.264 +
175.265 + return text.charAt(0);
175.266 + }
175.267 + }
175.268 +
175.269 + return 0;
175.270 + }
175.271 +
175.272 + public static Token<? extends PythonTokenId> findNextNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
175.273 + return findNext(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
175.274 + }
175.275 +
175.276 + public static Token<? extends PythonTokenId> findPreviousNonWsNonComment(TokenSequence<? extends PythonTokenId> ts) {
175.277 + return findPrevious(ts, Arrays.asList(PythonTokenId.WHITESPACE, PythonTokenId.NEWLINE, PythonTokenId.COMMENT));
175.278 + }
175.279 +
175.280 + public static Token<? extends PythonTokenId> findNext(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
175.281 + if (ignores.contains(ts.token().id())) {
175.282 + while (ts.moveNext() && ignores.contains(ts.token().id())) {
175.283 + }
175.284 + }
175.285 + return ts.token();
175.286 + }
175.287 +
175.288 + public static Token<? extends PythonTokenId> findNextIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
175.289 + while (ts.moveNext() && !includes.contains(ts.token().id())) {
175.290 + }
175.291 + return ts.token();
175.292 + }
175.293 +
175.294 + public static Token<? extends PythonTokenId> findPreviousIncluding(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> includes) {
175.295 + while (ts.movePrevious() && !includes.contains(ts.token().id())) {
175.296 + }
175.297 + return ts.token();
175.298 + }
175.299 +
175.300 + public static Token<? extends PythonTokenId> findPrevious(TokenSequence<? extends PythonTokenId> ts, List<PythonTokenId> ignores) {
175.301 + if (ignores.contains(ts.token().id())) {
175.302 + while (ts.movePrevious() && ignores.contains(ts.token().id())) {
175.303 + }
175.304 + }
175.305 + return ts.token();
175.306 + }
175.307 +
175.308 + static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts) {
175.309 + return skipParenthesis(ts, false);
175.310 + }
175.311 +
175.312 + /**
175.313 + * Tries to skip parenthesis
175.314 + */
175.315 + public static boolean skipParenthesis(TokenSequence<? extends PythonTokenId> ts, boolean back) {
175.316 + int balance = 0;
175.317 +
175.318 + Token<? extends PythonTokenId> token = ts.token();
175.319 + if (token == null) {
175.320 + return false;
175.321 + }
175.322 +
175.323 + TokenId id = token.id();
175.324 +
175.325 + if (id == PythonTokenId.WHITESPACE || id == PythonTokenId.NEWLINE) {
175.326 + while ((back ? ts.movePrevious() : ts.moveNext()) && (ts.token().id() == PythonTokenId.WHITESPACE || ts.token().id() == PythonTokenId.NEWLINE)) {
175.327 + }
175.328 + }
175.329 +
175.330 + // if current token is not left parenthesis
175.331 + if (ts.token().id() != (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
175.332 + return false;
175.333 + }
175.334 +
175.335 + do {
175.336 + token = ts.token();
175.337 + id = token.id();
175.338 +
175.339 + if (id == (back ? PythonTokenId.RPAREN : PythonTokenId.LPAREN)) {
175.340 + balance++;
175.341 + } else if (id == (back ? PythonTokenId.LPAREN : PythonTokenId.RPAREN)) {
175.342 + if (balance == 0) {
175.343 + return false;
175.344 + } else if (balance == 1) {
175.345 + //int length = ts.offset() + token.length();
175.346 + if (back) {
175.347 + ts.movePrevious();
175.348 + } else {
175.349 + ts.moveNext();
175.350 + }
175.351 + return true;
175.352 + }
175.353 +
175.354 + balance--;
175.355 + }
175.356 + } while (back ? ts.movePrevious() : ts.moveNext());
175.357 +
175.358 + return false;
175.359 + }
175.360 +
175.361 + /** Search forwards in the token sequence until a token of type <code>down</code> is found */
175.362 + public static OffsetRange findFwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
175.363 + TokenId down) {
175.364 + int balance = 0;
175.365 +
175.366 + while (ts.moveNext()) {
175.367 + Token<? extends PythonTokenId> token = ts.token();
175.368 + TokenId id = token.id();
175.369 +
175.370 + if (id == up) {
175.371 + balance++;
175.372 + } else if (id == down) {
175.373 + if (balance == 0) {
175.374 + return new OffsetRange(ts.offset(), ts.offset() + token.length());
175.375 + }
175.376 +
175.377 + balance--;
175.378 + }
175.379 + }
175.380 +
175.381 + return OffsetRange.NONE;
175.382 + }
175.383 +
175.384 + /** Search backwards in the token sequence until a token of type <code>up</code> is found */
175.385 + public static OffsetRange findBwd(BaseDocument doc, TokenSequence<? extends PythonTokenId> ts, TokenId up,
175.386 + TokenId down) {
175.387 + int balance = 0;
175.388 +
175.389 + while (ts.movePrevious()) {
175.390 + Token<? extends PythonTokenId> token = ts.token();
175.391 + TokenId id = token.id();
175.392 +
175.393 + if (id == up) {
175.394 + if (balance == 0) {
175.395 + return new OffsetRange(ts.offset(), ts.offset() + token.length());
175.396 + }
175.397 +
175.398 + balance++;
175.399 + } else if (id == down) {
175.400 + balance--;
175.401 + }
175.402 + }
175.403 +
175.404 + return OffsetRange.NONE;
175.405 + }
175.406 +
175.407 + /** Compute the balance of begin/end tokens on the line */
175.408 + public static int getLineBalance(BaseDocument doc, int offset, TokenId up, TokenId down) {
175.409 + try {
175.410 + int begin = Utilities.getRowStart(doc, offset);
175.411 + int end = Utilities.getRowEnd(doc, offset);
175.412 +
175.413 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, begin);
175.414 + if (ts == null) {
175.415 + return 0;
175.416 + }
175.417 +
175.418 + ts.move(begin);
175.419 +
175.420 + if (!ts.moveNext()) {
175.421 + return 0;
175.422 + }
175.423 +
175.424 + int balance = 0;
175.425 +
175.426 + do {
175.427 + Token<? extends PythonTokenId> token = ts.token();
175.428 + TokenId id = token.id();
175.429 +
175.430 + if (id == up) {
175.431 + balance++;
175.432 + } else if (id == down) {
175.433 + balance--;
175.434 + }
175.435 + } while (ts.moveNext() && (ts.offset() <= end));
175.436 +
175.437 + return balance;
175.438 + } catch (BadLocationException ble) {
175.439 + Exceptions.printStackTrace(ble);
175.440 +
175.441 + return 0;
175.442 + }
175.443 + }
175.444 +
175.445 + /**
175.446 + * The same as braceBalance but generalized to any pair of matching
175.447 + * tokens.
175.448 + * @param open the token that increses the count
175.449 + * @param close the token that decreses the count
175.450 + */
175.451 + public static int getTokenBalance(BaseDocument doc, TokenId open, TokenId close, int offset)
175.452 + throws BadLocationException {
175.453 + TokenSequence<? extends PythonTokenId> ts = PythonLexerUtils.getPythonSequence(doc, 0);
175.454 + if (ts == null) {
175.455 + return 0;
175.456 + }
175.457 +
175.458 + // XXX Why 0? Why not offset?
175.459 + ts.moveIndex(0);
175.460 +
175.461 + if (!ts.moveNext()) {
175.462 + return 0;
175.463 + }
175.464 +
175.465 + int balance = 0;
175.466 +
175.467 + do {
175.468 + Token t = ts.token();
175.469 +
175.470 + if (t.id() == open) {
175.471 + balance++;
175.472 + } else if (t.id() == close) {
175.473 + balance--;
175.474 + }
175.475 + } while (ts.moveNext());
175.476 +
175.477 + return balance;
175.478 + }
175.479 +
175.480 + /**
175.481 + * Return true iff the line for the given offset is a JavaScript comment line.
175.482 + * This will return false for lines that contain comments (even when the
175.483 + * offset is within the comment portion) but also contain code.
175.484 + */
175.485 + public static boolean isCommentOnlyLine(BaseDocument doc, int offset)
175.486 + throws BadLocationException {
175.487 + int begin = Utilities.getRowFirstNonWhite(doc, offset);
175.488 +
175.489 + if (begin == -1) {
175.490 + return false; // whitespace only
175.491 + }
175.492 +
175.493 + Token<? extends PythonTokenId> token = PythonLexerUtils.getToken(doc, begin);
175.494 + if (token != null) {
175.495 + return token.id() == PythonTokenId.COMMENT;
175.496 + }
175.497 +
175.498 + return false;
175.499 + }
175.500 +
175.501 + /**
175.502 + * Back up to the first space character prior to the given offset - as long as
175.503 + * it's on the same line! If there's only leading whitespace on the line up
175.504 + * to the lex offset, return the offset itself
175.505 + * @todo Rewrite this now that I have a separate newline token, EOL, that I can
175.506 + * break on - no need to call Utilities.getRowStart.
175.507 + */
175.508 + public static int findSpaceBegin(BaseDocument doc, int lexOffset) {
175.509 + TokenSequence ts = getPythonSequence(doc, lexOffset);
175.510 + if (ts == null) {
175.511 + return lexOffset;
175.512 + }
175.513 + boolean allowPrevLine = false;
175.514 + int lineStart;
175.515 + try {
175.516 + lineStart = Utilities.getRowStart(doc, Math.min(lexOffset, doc.getLength()));
175.517 + int prevLast = lineStart - 1;
175.518 + if (lineStart > 0) {
175.519 + prevLast = Utilities.getRowLastNonWhite(doc, lineStart - 1);
175.520 + if (prevLast != -1) {
175.521 + char c = doc.getText(prevLast, 1).charAt(0);
175.522 + if (c == ',') {
175.523 + // Arglist continuation? // TODO : check lexing
175.524 + allowPrevLine = true;
175.525 + }
175.526 + }
175.527 + }
175.528 + if (!allowPrevLine) {
175.529 + int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
175.530 + if (lexOffset <= firstNonWhite || firstNonWhite == -1) {
175.531 + return lexOffset;
175.532 + }
175.533 + } else {
175.534 + // Make lineStart so small that Math.max won't cause any problems
175.535 + int firstNonWhite = Utilities.getRowFirstNonWhite(doc, lineStart);
175.536 + if (prevLast >= 0 && (lexOffset <= firstNonWhite || firstNonWhite == -1)) {
175.537 + return prevLast + 1;
175.538 + }
175.539 + lineStart = 0;
175.540 + }
175.541 + } catch (BadLocationException ble) {
175.542 + Exceptions.printStackTrace(ble);
175.543 + return lexOffset;
175.544 + }
175.545 + ts.move(lexOffset);
175.546 + if (ts.moveNext()) {
175.547 + if (lexOffset > ts.offset()) {
175.548 + // We're in the middle of a token
175.549 + return Math.max((ts.token().id() == PythonTokenId.WHITESPACE) ? ts.offset() : lexOffset, lineStart);
175.550 + }
175.551 + while (ts.movePrevious()) {
175.552 + Token token = ts.token();
175.553 + if (token.id() != PythonTokenId.WHITESPACE) {
175.554 + return Math.max(ts.offset() + token.length(), lineStart);
175.555 + }
175.556 + }
175.557 + }
175.558 +
175.559 + return lexOffset;
175.560 + }
175.561 +}
176.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
176.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonStringLexer.java Wed Sep 02 20:31:18 2015 +0200
176.3 @@ -0,0 +1,292 @@
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 strings. Highlights escape sequences, and recognizes
176.57 + * doctest sections and highlights these as well.
176.58 + * http://docs.python.org/lib/module-doctest.html
176.59 + *
176.60 + * @todo Track whether strings are raw or not, and don't do escape sequence
176.61 + * highlighting in raw strings
176.62 + *
176.63 + * @author Tor Norbye
176.64 + */
176.65 +public class PythonStringLexer implements Lexer<PythonStringTokenId> {
176.66 + private static final int EOF = LexerInput.EOF;
176.67 + private final LexerInput input;
176.68 + private final TokenFactory<PythonStringTokenId> tokenFactory;
176.69 + private final boolean substituting;
176.70 +
176.71 + /**
176.72 + * A Lexer for Python strings
176.73 + * @param substituting If true, handle substitution rules for double quoted strings, otherwise
176.74 + * single quoted strings.
176.75 + */
176.76 + public PythonStringLexer(LexerRestartInfo<PythonStringTokenId> info, boolean substituting) {
176.77 + this.input = info.input();
176.78 + this.tokenFactory = info.tokenFactory();
176.79 + this.substituting = substituting;
176.80 + assert (info.state() == null); // passed argument always null
176.81 + }
176.82 +
176.83 + @Override
176.84 + public Object state() {
176.85 + return null;
176.86 + }
176.87 +
176.88 + @Override
176.89 + public Token<PythonStringTokenId> nextToken() {
176.90 + boolean inWord = false;
176.91 + while (true) {
176.92 + int ch = input.read();
176.93 +
176.94 + switch (ch) {
176.95 + case EOF:
176.96 +
176.97 + if (input.readLength() > 0) {
176.98 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
176.99 + input.readLength());
176.100 + } else {
176.101 + return null;
176.102 + }
176.103 +
176.104 + case '>':
176.105 + // Look for doctest: \n, whitespace, >>>{embedded python}\n
176.106 + int initialReadLength = input.readLength();
176.107 + input.read();
176.108 + if (ch == '>') {
176.109 + ch = input.read();
176.110 + if (ch == '>') {
176.111 + if (input.readLength() > 3) {
176.112 + input.backup(3);
176.113 + // Finish this token such that we can do a dedicated token for the ">>>" line.
176.114 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
176.115 + input.readLength());
176.116 + }
176.117 + // Find end...
176.118 + boolean nonempty = false;
176.119 + while (true) {
176.120 + ch = input.read();
176.121 + if (ch == EOF) {
176.122 + break;
176.123 + } else if (ch == '\n') {
176.124 + if (nonempty) {
176.125 + input.backup(1); // Don't include the \n
176.126 + return tokenFactory.createToken(PythonStringTokenId.EMBEDDED_PYTHON,
176.127 + input.readLength());
176.128 +
176.129 + }
176.130 + break;
176.131 + } else if (!Character.isWhitespace(ch)) {
176.132 + nonempty = true;
176.133 + }
176.134 + }
176.135 + }
176.136 + }
176.137 + if (input.readLength() > initialReadLength) {
176.138 + input.backup(input.readLength() - initialReadLength);
176.139 + } else {
176.140 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
176.141 + input.readLength());
176.142 + }
176.143 + break;
176.144 +
176.145 + case '\\':
176.146 +
176.147 + if (input.readLength() > 1) { // already read some text
176.148 + input.backup(1);
176.149 +
176.150 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
176.151 + input.readLength());
176.152 + }
176.153 +
176.154 + ch = input.read();
176.155 + if (ch == EOF) {
176.156 + return tokenFactory.createToken(PythonStringTokenId.STRING_INVALID,
176.157 + input.readLength());
176.158 + } else {
176.159 + return tokenFactory.createToken(PythonStringTokenId.STRING_ESCAPE,
176.160 + input.readLength());
176.161 + }
176.162 +
176.163 + case 'f': // ftp:
176.164 + case 'm': // mailto:
176.165 + case 'w': // www.
176.166 + case 'h': { // http links. TODO: link:, ftp:, mailto:, and www.
176.167 +
176.168 + if (inWord) {
176.169 + break;
176.170 + }
176.171 +
176.172 + int originalLength = input.readLength();
176.173 + boolean foundLinkBegin = false;
176.174 +
176.175 + if (ch == 'h') { // http:
176.176 +
176.177 + if (input.read() == 't') {
176.178 + if (input.read() == 't') {
176.179 + if (input.read() == 'p') {
176.180 + int r = input.read();
176.181 + if (r == ':') {
176.182 + foundLinkBegin = true;
176.183 + } else if (r == 's') {
176.184 + if (input.read() == ':') {
176.185 + foundLinkBegin = true;
176.186 + } else {
176.187 + input.backup(5);
176.188 + }
176.189 + } else {
176.190 + input.backup(4);
176.191 + }
176.192 + } else {
176.193 + input.backup(3);
176.194 + }
176.195 + } else {
176.196 + input.backup(2);
176.197 + }
176.198 + } else {
176.199 + input.backup(1);
176.200 + }
176.201 + } else if (ch == 'f') { // ftp:
176.202 +
176.203 + if (input.read() == 't') {
176.204 + if (input.read() == 'p') {
176.205 + if (input.read() == ':') {
176.206 + foundLinkBegin = true;
176.207 + } else {
176.208 + input.backup(3);
176.209 + }
176.210 + } else {
176.211 + input.backup(2);
176.212 + }
176.213 + } else {
176.214 + input.backup(1);
176.215 + }
176.216 + } else if (ch == 'm') { // mailto:
176.217 +
176.218 + if (input.read() == 'a') {
176.219 + if (input.read() == 'i') {
176.220 + if (input.read() == 'l') {
176.221 + if (input.read() == 't') {
176.222 + if (input.read() == 'o') {
176.223 + if (input.read() == ':') {
176.224 + foundLinkBegin = true;
176.225 + } else {
176.226 + input.backup(6);
176.227 + }
176.228 + } else {
176.229 + input.backup(5);
176.230 + }
176.231 + } else {
176.232 + input.backup(4);
176.233 + }
176.234 + } else {
176.235 + input.backup(3);
176.236 + }
176.237 + } else {
176.238 + input.backup(2);
176.239 + }
176.240 + } else {
176.241 + input.backup(1);
176.242 + }
176.243 + } else if (ch == 'w') { // www.
176.244 +
176.245 + if (input.read() == 'w') {
176.246 + if (input.read() == 'w') {
176.247 + if (input.read() == '.') {
176.248 + foundLinkBegin = true;
176.249 + } else {
176.250 + input.backup(3);
176.251 + }
176.252 + } else {
176.253 + input.backup(2);
176.254 + }
176.255 + } else {
176.256 + input.backup(1);
176.257 + }
176.258 + }
176.259 +
176.260 + if (foundLinkBegin) {
176.261 + while (ch != EOF) {
176.262 + ch = input.read();
176.263 +
176.264 + if ((ch == ']') || (ch == ')') || Character.isWhitespace(ch) ||
176.265 + (ch == '\'') || (ch == '"')) {
176.266 + input.backup(1);
176.267 +
176.268 + break;
176.269 + }
176.270 + }
176.271 +
176.272 + if (originalLength > 1) {
176.273 + input.backup(input.readLengthEOF() - originalLength + 1);
176.274 +
176.275 + return tokenFactory.createToken(PythonStringTokenId.STRING_TEXT,
176.276 + input.readLength());
176.277 + }
176.278 +
176.279 + if (input.readLength() > 2) {
176.280 + return tokenFactory.createToken(PythonStringTokenId.URL,
176.281 + input.readLength());
176.282 + }
176.283 + }
176.284 + break;
176.285 + }
176.286 + }
176.287 +
176.288 + inWord = Character.isJavaIdentifierPart(ch);
176.289 + }
176.290 + }
176.291 +
176.292 + @Override
176.293 + public void release() {
176.294 + }
176.295 +}
177.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
177.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonStringTokenId.java Wed Sep 02 20:31:18 2015 +0200
177.3 @@ -0,0 +1,125 @@
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.api.lexer.TokenUtilities;
177.59 +import org.netbeans.spi.lexer.LanguageEmbedding;
177.60 +import org.netbeans.spi.lexer.LanguageHierarchy;
177.61 +import org.netbeans.spi.lexer.Lexer;
177.62 +import org.netbeans.spi.lexer.LexerRestartInfo;
177.63 +
177.64 +/**
177.65 + *
177.66 + * @author Tor Norbye
177.67 + */
177.68 +public enum PythonStringTokenId implements TokenId {
177.69 + STRING_TEXT("string"),
177.70 + STRING_ESCAPE("string-escape"),
177.71 + STRING_INVALID("string-escape-invalid"),
177.72 + URL("url"),
177.73 + EMBEDDED_PYTHON("string");
177.74 + private final String primaryCategory;
177.75 +
177.76 + PythonStringTokenId() {
177.77 + this(null);
177.78 + }
177.79 +
177.80 + PythonStringTokenId(String primaryCategory) {
177.81 + this.primaryCategory = primaryCategory;
177.82 + }
177.83 +
177.84 + @Override
177.85 + public String primaryCategory() {
177.86 + return primaryCategory;
177.87 + }
177.88 + public static final Language<PythonStringTokenId> language =
177.89 + new LanguageHierarchy<PythonStringTokenId>() {
177.90 + @Override
177.91 + protected Collection<PythonStringTokenId> createTokenIds() {
177.92 + return EnumSet.allOf(PythonStringTokenId.class);
177.93 + }
177.94 +
177.95 + @Override
177.96 + protected Map<String, Collection<PythonStringTokenId>> createTokenCategories() {
177.97 + return null; // no extra categories
177.98 + }
177.99 +
177.100 + @Override
177.101 + protected Lexer<PythonStringTokenId> createLexer(
177.102 + LexerRestartInfo<PythonStringTokenId> info) {
177.103 + return new PythonStringLexer(info, true);
177.104 + }
177.105 +
177.106 + @Override
177.107 + protected LanguageEmbedding<?> embedding(
177.108 + Token<PythonStringTokenId> token, LanguagePath languagePath,
177.109 + InputAttributes inputAttributes) {
177.110 + PythonStringTokenId id = token.id();
177.111 +
177.112 + if (id == EMBEDDED_PYTHON && token.text() != null) {
177.113 + return LanguageEmbedding.create(PythonTokenId.language(), 3, 0); // 3: Exlude ">>>" prefix
177.114 + }
177.115 +
177.116 + return null; // No embedding
177.117 + }
177.118 +
177.119 + @Override
177.120 + public String mimeType() {
177.121 + return "text/x-python-string"; // NOI18N
177.122 + }
177.123 + }.language();
177.124 +
177.125 + public static Language<PythonStringTokenId> language() {
177.126 + return language;
177.127 + }
177.128 +}
178.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
178.2 +++ b/python.source/src/org/netbeans/modules/python/source/lexer/PythonTokenId.java Wed Sep 02 20:31:18 2015 +0200
178.3 @@ -0,0 +1,206 @@
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 java.util.Collection;
178.50 +import java.util.EnumSet;
178.51 +import java.util.HashMap;
178.52 +import java.util.Map;
178.53 +import org.netbeans.api.lexer.InputAttributes;
178.54 +import org.netbeans.api.lexer.Language;
178.55 +import org.netbeans.api.lexer.LanguagePath;
178.56 +import org.netbeans.api.lexer.Token;
178.57 +import org.netbeans.api.lexer.TokenId;
178.58 +import org.netbeans.modules.python.api.PythonMIMEResolver;
178.59 +import org.netbeans.modules.python.source.PythonUtils;
178.60 +import org.netbeans.spi.lexer.LanguageEmbedding;
178.61 +import org.netbeans.spi.lexer.LanguageHierarchy;
178.62 +import org.netbeans.spi.lexer.Lexer;
178.63 +import org.netbeans.spi.lexer.LexerInput;
178.64 +import org.netbeans.spi.lexer.LexerRestartInfo;
178.65 +
178.66 +import org.netbeans.spi.lexer.TokenFactory;
178.67 +import org.openide.filesystems.FileObject;
178.68 +import static org.netbeans.modules.python.source.lexer.PythonLexer.*;
178.69 +
178.70 +/**
178.71 + * @todo add the rest of the tokens
178.72 + *
178.73 + * @author Martin Adamek
178.74 + * @author alley
178.75 + */
178.76 +public enum PythonTokenId implements TokenId {
178.77 + ERROR(null, ERROR_CAT),
178.78 + IDENTIFIER(null, IDENTIFIER_CAT),
178.79 + INT_LITERAL(null, NUMBER_CAT),
178.80 + FLOAT_LITERAL(null, NUMBER_CAT),
178.81 + STRING_LITERAL(null, STRING_CAT),
178.82 + WHITESPACE(null, WHITESPACE_CAT),
178.83 + NEWLINE(null, WHITESPACE_CAT),
178.84 + DECORATOR(null, OPERATOR_CAT), // NOI18N
178.85 + // CONTINUED_LINE(null, WHITESPACE_CAT), // NOI18N
178.86 + COMMENT(null, COMMENT_CAT),
178.87 + STD_SYMBOLS(null, KEYWORD_CAT), // NOI18N
178.88 + LPAREN("(", SEPARATOR_CAT), // NOI18N
178.89 + RPAREN(")", SEPARATOR_CAT), // NOI18N
178.90 + LBRACE("{", SEPARATOR_CAT), // NOI18N
178.91 + RBRACE("}", SEPARATOR_CAT), // NOI18N
178.92 + LBRACKET("[", SEPARATOR_CAT), // NOI18N
178.93 + RBRACKET("]", SEPARATOR_CAT), // NOI18N
178.94 + STRING_BEGIN(null, STRING_CAT),
178.95 + STRING_END(null, STRING_CAT),
178.96 + // Cheating: out of laziness just map all keywords returning from Jython
178.97 + // into a single KEYWORD token; eventually we will have separate tokens
178.98 + // for each here such that the various helper methods for formatting,
178.99 + // smart indent, brace matching etc. can refer to specific keywords
178.100 + ANY_KEYWORD(null, KEYWORD_CAT),
178.101 + ANY_OPERATOR(null, OPERATOR_CAT),
178.102 + DEF("def", KEYWORD_CAT), // NOI18N
178.103 + CLASS("class", KEYWORD_CAT), // NOI18N
178.104 + IF("if", KEYWORD_CAT), // NOI18N
178.105 + ELSE("else", KEYWORD_CAT), // NOI18N
178.106 + ELIF("elif", KEYWORD_CAT), // NOI18N
178.107 + RAISE("raise", KEYWORD_CAT), // NOI18N
178.108 + PASS("pass", KEYWORD_CAT), // NOI18N
178.109 + RETURN("return", KEYWORD_CAT), // NOI18N
178.110 + EXCEPT("except", KEYWORD_CAT), // NOI18N
178.111 + FINALLY("finally", KEYWORD_CAT), // NOI18N
178.112 + IMPORT("import", KEYWORD_CAT), // NOI18N
178.113 + FROM("from", KEYWORD_CAT), // NOI18N
178.114 + TRUE("True", KEYWORD_CAT), // NOI18N
178.115 + FALSE("False", KEYWORD_CAT), // NOI18N
178.116 + NONE("None", KEYWORD_CAT), // NOI18N
178.117 + TRY("try", KEYWORD_CAT), // NOI18N
178.118 + DOT(".", OPERATOR_CAT), // NOI18N
178.119 + COMMA(",", OPERATOR_CAT), // NOI18N
178.120 + COLON(":", OPERATOR_CAT), // NOI18N
178.121 + ESC("\\", OPERATOR_CAT), // NOI18N
178.122 +
178.123 + // Non-unary operators which indicate a line continuation if used at the end of a line
178.124 + NONUNARY_OP(null, OPERATOR_CAT);
178.125 + private final String fixedText;
178.126 + private final String primaryCategory;
178.127 +
178.128 + PythonTokenId(String fixedText, String primaryCategory) {
178.129 + this.fixedText = fixedText;
178.130 + this.primaryCategory = primaryCategory;
178.131 + }
178.132 +
178.133 + @Override
178.134 + public String primaryCategory() {
178.135 + return primaryCategory;
178.136 + }
178.137 +
178.138 + public String fixedText() {
178.139 + return fixedText;
178.140 + }
178.141 + private static final Language<PythonTokenId> language =
178.142 + new LanguageHierarchy<PythonTokenId>() {
178.143 + @Override
178.144 + protected String mimeType() {
178.145 + return PythonMIMEResolver.PYTHON_MIME_TYPE;
178.146 + }
178.147 +
178.148 + @Override
178.149 + protected Collection<PythonTokenId> createTokenIds() {
178.150 + return EnumSet.allOf(PythonTokenId.class);
178.151 + }
178.152 +
178.153 + @Override
178.154 + protected Map<String, Collection<PythonTokenId>> createTokenCategories() {
178.155 + Map<String, Collection<PythonTokenId>> cats =
178.156 + new HashMap<>();
178.157 + return cats;
178.158 + }
178.159 +
178.160 + @Override
178.161 + protected Lexer<PythonTokenId> createLexer(LexerRestartInfo<PythonTokenId> info) {
178.162 + FileObject fileObject = (FileObject)info.getAttributeValue(FileObject.class);
178.163 + final TokenFactory<PythonTokenId> tokenFactory = info.tokenFactory();
178.164 + final LexerInput input = info.input();
178.165 + // Lex .rst files just as literal strings
178.166 + if (fileObject != null && PythonUtils.isRstFile(fileObject)) {
178.167 + return new Lexer<PythonTokenId>() {
178.168 + @Override
178.169 + public Token<PythonTokenId> nextToken() {
178.170 + if (input.read() == LexerInput.EOF) {
178.171 + return null;
178.172 + }
178.173 + while (input.read() != LexerInput.EOF) {
178.174 + ;
178.175 + }
178.176 + return tokenFactory.createToken(PythonTokenId.STRING_LITERAL, input.readLength());
178.177 + }
178.178 +
178.179 + @Override
178.180 + public Object state() {
178.181 + return null;
178.182 + }
178.183 +
178.184 + @Override
178.185 + public void release() {
178.186 + }
178.187 + };
178.188 + }
178.189 + return new PythonLexer(info);
178.190 + }
178.191 +
178.192 + @Override
178.193 + protected LanguageEmbedding<?> embedding(Token<PythonTokenId> token,
178.194 + LanguagePath languagePath, InputAttributes inputAttributes) {
178.195 + PythonTokenId id = token.id();
178.196 + if (id == STRING_LITERAL) {
178.197 + return LanguageEmbedding.create(PythonStringTokenId.language, 0, 0);
178.198 + } else if (id == COMMENT) {
178.199 + return LanguageEmbedding.create(PythonCommentTokenId.language(), 1, 0);
178.200 + }
178.201 +
178.202 + return null; // No embedding
178.203 + }
178.204 + }.language();
178.205 +
178.206 + public static Language<PythonTokenId> language() {
178.207 + return language;
178.208 + }
178.209 +}
179.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
179.2 +++ b/python.source/src/org/netbeans/modules/python/source/queries/DeprecationQuery.java Wed Sep 02 20:31:18 2015 +0200
179.3 @@ -0,0 +1,169 @@
179.4 +/*
179.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
179.6 + *
179.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
179.8 + *
179.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
179.10 + * Other names may be trademarks of their respective owners.
179.11 + *
179.12 + * The contents of this file are subject to the terms of either the GNU
179.13 + * General Public License Version 2 only ("GPL") or the Common
179.14 + * Development and Distribution License("CDDL") (collectively, the
179.15 + * "License"). You may not use this file except in compliance with the
179.16 + * License. You can obtain a copy of the License at
179.17 + * http://www.netbeans.org/cddl-gplv2.html
179.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
179.19 + * specific language governing permissions and limitations under the
179.20 + * License. When distributing the software, include this License Header
179.21 + * Notice in each file and include the License file at
179.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
179.23 + * particular file as subject to the "Classpath" exception as provided
179.24 + * by Oracle in the GPL Version 2 section of the License file that
179.25 + * accompanied this code. If applicable, add the following below the
179.26 + * License Header, with the fields enclosed by brackets [] replaced by
179.27 + * your own identifying information:
179.28 + * "Portions Copyrighted [year] [name of copyright owner]"
179.29 + *
179.30 + * If you wish your version of this file to be governed by only the CDDL
179.31 + * or only the GPL Version 2, indicate your decision by adding
179.32 + * "[Contributor] elects to include this software in this distribution
179.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
179.34 + * single choice of license, a recipient has the option to distribute
179.35 + * your version of this file under either the CDDL, the GPL Version 2 or
179.36 + * to extend the choice of license to its licensees as provided above.
179.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
179.38 + * Version 2 license, then the option applies only if the new code is
179.39 + * made subject to such option by the copyright holder.
179.40 + *
179.41 + * Contributor(s):
179.42 + *
179.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
179.44 + */
179.45 +package org.netbeans.modules.python.source.queries;
179.46 +
179.47 +import java.util.HashMap;
179.48 +import java.util.Map;
179.49 +
179.50 +/**
179.51 + *
179.52 + * @author Ralph Ruijs
179.53 + */
179.54 +public final class DeprecationQuery {
179.55 + private static final Map<String, String> DEPRECATED = new HashMap<>();
179.56 +
179.57 +
179.58 + static {
179.59 + for (String module : new String[]{"cl", "sv", "timing"}) {
179.60 + DEPRECATED.put(module, "Listed as obsolete in the library documentation");
179.61 + }
179.62 +
179.63 + for (String module : new String[]{
179.64 + "addpack", "cmp", "cmpcache", "codehack", "dircmp", "dump", "find", "fmt",
179.65 + "grep", "lockfile", "newdir", "ni", "packmail", "Para", "poly",
179.66 + "rand", "reconvert", "regex", "regsub", "statcache", "tb", "tzparse",
179.67 + "util", "whatsound", "whrandom", "zmod"}) {
179.68 + DEPRECATED.put(module, "Obsolete module, removed in Python 2.5");
179.69 +
179.70 + }
179.71 +
179.72 + for (String module : new String[]{"gopherlib", "rgbimg", "macfs"}) {
179.73 + DEPRECATED.put(module, "Obsolete module, removed in Python 2.6");
179.74 + }
179.75 +
179.76 + /*
179.77 + al.rst: The :mod:`al` module has been deprecated for removal in Python 3.0.
179.78 + al.rst: The :mod:`AL` module has been deprecated for removal in Python 3.0.
179.79 + bsddb.rst: The :mod:`bsddb` module has been deprecated for removal in Python 3.0.
179.80 + cd.rst: The :mod:`cd` module has been deprecated for removal in Python 3.0.
179.81 + dbhash.rst: The :mod:`dbhash` module has been deprecated for removal in Python 3.0.
179.82 + fl.rst: The :mod:`fl` module has been deprecated for removal in Python 3.0.
179.83 + fl.rst: The :mod:`FL` module has been deprecated for removal in Python 3.0.
179.84 + fl.rst: The :mod:`flp` module has been deprecated for removal in Python 3.0.
179.85 + fm.rst: The :mod:`fm` module has been deprecated for removal in Python 3.0.
179.86 + gl.rst: The :mod:`gl` module has been deprecated for removal in Python 3.0.
179.87 + gl.rst: The :mod:`DEVICE` module has been deprecated for removal in Python 3.0.
179.88 + gl.rst: The :mod:`GL` module has been deprecated for removal in Python 3.0.
179.89 + imgfile.rst: The :mod:`imgfile` module has been deprecated for removal in Python 3.0.
179.90 + jpeg.rst: The :mod:`jpeg` module has been deprecated for removal in Python 3.0.
179.91 + statvfs.rst: The :mod:`statvfs` module has been deprecated for removal in Python 3.0.
179.92 + sunaudio.rst: The :mod:`sunaudiodev` module has been deprecated for removal in Python 3.0.
179.93 + sunaudio.rst: The :mod:`SUNAUDIODEV` module has been deprecated for removal in Python 3.0.
179.94 + tarfile.rst: The :class:`TarFileCompat` class has been deprecated for removal in Python 3.0.
179.95 + */
179.96 +
179.97 + DEPRECATED.put("posixfile",
179.98 + "Locking is better done by fcntl.lockf().");
179.99 +
179.100 + DEPRECATED.put("gopherlib",
179.101 + "The gopher protocol is not in active use anymore.");
179.102 +
179.103 + DEPRECATED.put("rgbimgmodule",
179.104 + "");
179.105 +
179.106 + DEPRECATED.put("pre",
179.107 + "The underlying PCRE engine doesn't support Unicode, and has been unmaintained since Python 1.5.2.");
179.108 +
179.109 + DEPRECATED.put("whrandom",
179.110 + "The module's default seed computation was inherently insecure; the random module should be used instead.");
179.111 +
179.112 + DEPRECATED.put("rfc822",
179.113 + "Supplanted by Python 2.2's email package.");
179.114 +
179.115 + DEPRECATED.put("mimetools",
179.116 + "Supplanted by Python 2.2's email package.");
179.117 +
179.118 + DEPRECATED.put("MimeWriter",
179.119 + "Supplanted by Python 2.2's email package.");
179.120 +
179.121 + DEPRECATED.put("mimify",
179.122 + "Supplanted by Python 2.2's email package.");
179.123 +
179.124 + DEPRECATED.put("rotor",
179.125 + "Uses insecure algorithm.");
179.126 +
179.127 + DEPRECATED.put("TERMIOS.py",
179.128 + "The constants in this file are now in the 'termios' module.");
179.129 +
179.130 + DEPRECATED.put("statcache",
179.131 + "Using the cache can be fragile and error-prone; applications should just use os.stat() directly.");
179.132 +
179.133 + DEPRECATED.put("mpz",
179.134 + "Third-party packages provide similiar features and wrap more of GMP's API.");
179.135 +
179.136 +
179.137 + DEPRECATED.put("xreadlines",
179.138 + "Using 'for line in file', introduced in 2.3, is preferable.");
179.139 +
179.140 + DEPRECATED.put("multifile",
179.141 + "Supplanted by the email package.");
179.142 +
179.143 + DEPRECATED.put("sets",
179.144 + "The built-in set/frozenset types, introduced in Python 2.4, supplant the module.");
179.145 +
179.146 + DEPRECATED.put("buildtools",
179.147 + "");
179.148 +
179.149 + DEPRECATED.put("cfmfile",
179.150 + "");
179.151 +
179.152 + DEPRECATED.put("macfs",
179.153 + "");
179.154 +
179.155 + DEPRECATED.put("md5",
179.156 + "Replaced by the 'hashlib' module.");
179.157 +
179.158 + DEPRECATED.put("sha",
179.159 + "Replaced by the 'hashlib' module.");
179.160 + }
179.161 +
179.162 + public static boolean isDeprecatedModule(String module) {
179.163 + return DEPRECATED.containsKey(module);
179.164 + }
179.165 +
179.166 + public static String getDeprecatedModuleDescription(String module) {
179.167 + return DEPRECATED.get(module);
179.168 + }
179.169 +
179.170 + private DeprecationQuery() {
179.171 + }
179.172 +}
180.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ArgListCompiler.java Wed Sep 02 20:31:18 2015 +0200
180.3 @@ -0,0 +1,121 @@
180.4 +// Copyright (c) Corporation for National Research Initiatives
180.5 +package org.netbeans.modules.python.source.scopes;
180.6 +
180.7 +import java.util.ArrayList;
180.8 +
180.9 +import java.util.List;
180.10 +import org.python.antlr.PythonTree;
180.11 +import org.python.antlr.Visitor;
180.12 +import org.python.antlr.ast.Assign;
180.13 +import org.python.antlr.ast.Name;
180.14 +import org.python.antlr.ast.Suite;
180.15 +import org.python.antlr.ast.Tuple;
180.16 +import org.python.antlr.ast.arguments;
180.17 +import org.python.antlr.ast.expr_contextType;
180.18 +import org.python.antlr.base.expr;
180.19 +import org.python.antlr.base.stmt;
180.20 +
180.21 +/** Based on org.python.compiler.ArgListCompiler */
180.22 +public class ArgListCompiler extends Visitor {
180.23 + public boolean arglist, keywordlist;
180.24 + public List<expr> defaults;
180.25 + public List<String> names;
180.26 + public ArrayList<PythonTree> nodes;
180.27 + public List<String> fpnames;
180.28 + public List<stmt> init_code;
180.29 + private SymbolTable symbolTable;
180.30 +
180.31 + public ArgListCompiler(SymbolTable symbolTable) {
180.32 + this.symbolTable = symbolTable;
180.33 + arglist = keywordlist = false;
180.34 + defaults = null;
180.35 + names = new ArrayList<>();
180.36 + nodes = new ArrayList<>();
180.37 + fpnames = new ArrayList<>();
180.38 + init_code = new ArrayList<>();
180.39 + }
180.40 +
180.41 + public void reset() {
180.42 + arglist = keywordlist = false;
180.43 + defaults = null;
180.44 + names.clear();
180.45 + nodes.clear();
180.46 + init_code.clear();
180.47 + }
180.48 +
180.49 + public void appendInitCode(Suite node) {
180.50 + node.getInternalBody().addAll(0, init_code);
180.51 + }
180.52 +
180.53 + public List<expr> getDefaults() {
180.54 + return defaults;
180.55 + }
180.56 +
180.57 + public void visitArgs(arguments args) throws Exception {
180.58 + for (int i = 0; i < args.getInternalArgs().size(); i++) {
180.59 + expr node = args.getInternalArgs().get(i);
180.60 + String name = (String)visit(node);
180.61 + names.add(name);
180.62 + nodes.add(node);
180.63 + if (node instanceof Tuple) {
180.64 + List<expr> targets = new ArrayList<>();
180.65 + targets.add(node);
180.66 + Assign ass = new Assign(node,
180.67 + targets,
180.68 + new Name(node, name, expr_contextType.Load));
180.69 + init_code.add(ass);
180.70 + }
180.71 + }
180.72 + if (args.getInternalVararg() != null) {
180.73 + arglist = true;
180.74 + names.add(args.getInternalVararg());
180.75 + //nodes.add(null); // no corresponding node?
180.76 + nodes.add(args); // just use the corresponding args node instead
180.77 + }
180.78 + if (args.getInternalKwarg() != null) {
180.79 + keywordlist = true;
180.80 + names.add(args.getInternalKwarg());
180.81 + //nodes.add(null); // no corresponding node?
180.82 + nodes.add(args); // just use the corresponding args node instead
180.83 + }
180.84 +
180.85 + defaults = args.getInternalDefaults();
180.86 + for (int i = 0; i < defaults.size(); i++) {
180.87 + if (defaults.get(i) == null) {
180.88 + symbolTable.error("non-default argument follows default argument", true,
180.89 + args.getInternalArgs().get(args.getInternalArgs().size() - defaults.size() + i));
180.90 + }
180.91 + }
180.92 + }
180.93 +
180.94 + @Override
180.95 + public Object visitName(Name node) throws Exception {
180.96 + //FIXME: do we need Store and Param, or just Param?
180.97 + if (node.getInternalCtx() != expr_contextType.Store && node.getInternalCtx() != expr_contextType.Param) {
180.98 + return null;
180.99 + }
180.100 +
180.101 + if (fpnames.contains(node.getInternalId())) {
180.102 + symbolTable.error("duplicate argument name found: " +
180.103 + node.getInternalId(), true, node);
180.104 + }
180.105 + fpnames.add(node.getInternalId());
180.106 + return node.getInternalId();
180.107 + }
180.108 +
180.109 + @Override
180.110 + public Object visitTuple(Tuple node) throws Exception {
180.111 + StringBuffer name = new StringBuffer("(");
180.112 + List<expr> elts = node.getInternalElts();
180.113 + if (elts != null) {
180.114 + int n = elts.size();
180.115 + for (int i = 0; i < n - 1; i++) {
180.116 + name.append(visit(elts.get(i)));
180.117 + name.append(", ");
180.118 + }
180.119 + name.append(visit(elts.get(n - 1)));
180.120 + }
180.121 + name.append(")");
180.122 + return name.toString();
180.123 + }
180.124 +}
181.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
181.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ScopeConstants.java Wed Sep 02 20:31:18 2015 +0200
181.3 @@ -0,0 +1,28 @@
181.4 +package org.netbeans.modules.python.source.scopes;
181.5 +
181.6 +/** Based on org.python.compiler.ScopeConstants in Jython */
181.7 +public interface ScopeConstants {
181.8 + public final static int BOUND = 1 << 0;
181.9 + public final static int NGLOBAL = 1 << 1; // func scope expl global
181.10 + public final static int PARAM = 1 << 2;
181.11 + public final static int FROM_PARAM = 1 << 3;
181.12 + public final static int CELL = 1 << 4;
181.13 + public final static int FREE = 1 << 5;
181.14 + public final static int CLASS_GLOBAL = 1 << 6; // class scope expl global
181.15 + public final static int READ = 1 << 7;
181.16 + public final static int CALLED = 1 << 8;
181.17 + public final static int DEF = 1 << 9;
181.18 + public final static int IMPORTED = 1 << 10;
181.19 + public final static int CLASS = 1 << 11;
181.20 + public final static int FUNCTION = 1 << 12;
181.21 + public final static int MEMBER = 1 << 13;
181.22 + public final static int GENERATOR = 1 << 13; // it's a generator expression
181.23 + public final static int PRIVATE = 1 << 14;
181.24 + public final static int ALIAS = 1 << 15;
181.25 + public final static int PROTECTED = 1 << 16;
181.26 + public final static int BOUND_IN_CONSTRUCTOR = 1 << 17;
181.27 + public final static int GLOBAL = NGLOBAL | CLASS_GLOBAL; // all global
181.28 + public final static int TOPSCOPE = 0;
181.29 + public final static int FUNCSCOPE = 1;
181.30 + public final static int CLASSSCOPE = 2;
181.31 +}
182.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
182.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ScopeInfo.java Wed Sep 02 20:31:18 2015 +0200
182.3 @@ -0,0 +1,576 @@
182.4 +// (C) Copyright 2001 Samuele Pedroni
182.5 +package org.netbeans.modules.python.source.scopes;
182.6 +
182.7 +import java.util.ArrayList;
182.8 +import java.util.Collections;
182.9 +import java.util.HashMap;
182.10 +import java.util.LinkedHashMap;
182.11 +import java.util.Map;
182.12 +import java.util.List;
182.13 +
182.14 +import org.netbeans.modules.python.source.AstPath;
182.15 +import org.netbeans.modules.python.source.PythonAstUtils;
182.16 +import org.python.antlr.ParseException;
182.17 +import org.python.antlr.PythonTree;
182.18 +import org.python.antlr.ast.Assign;
182.19 +import org.python.antlr.ast.Attribute;
182.20 +import org.python.antlr.ast.ClassDef;
182.21 +import org.python.antlr.ast.Name;
182.22 +import org.python.antlr.ast.Return;
182.23 +import org.python.antlr.ast.Tuple;
182.24 +import org.python.antlr.base.expr;
182.25 +import static org.netbeans.modules.python.source.scopes.ScopeConstants.*;
182.26 +import org.netbeans.modules.python.source.NameStyle;
182.27 +
182.28 +/**
182.29 + * Based on org.python.compiler.ScopeInfo in Jython
182.30 + *
182.31 + * See {@link ScopesCompiler} for details on my modifications
182.32 + */
182.33 +@SuppressWarnings("unchecked")
182.34 +public class ScopeInfo extends Object {
182.35 + public PythonTree scope_node;
182.36 + public String scope_name;
182.37 + public int level;
182.38 + public int func_level;
182.39 + public boolean hidden;
182.40 +
182.41 + public String dump() {
182.42 + StringBuilder sb = new StringBuilder();
182.43 +
182.44 + for (int i = 0; i < level; i++) {
182.45 + sb.append(" ");
182.46 + }
182.47 + sb.append("=============================================\n");
182.48 + for (int i = 0; i < level; i++) {
182.49 + sb.append(" ");
182.50 + }
182.51 + sb.append(((kind != CLASSSCOPE) ? scope_name : "class " +
182.52 + scope_name) + ": " + scope_node + " : " + PythonAstUtils.getRange(scope_node) + "\n");
182.53 + //for(int i=0; i<level; i++) sb.append(" ");
182.54 + //sb.append("UP=" + up);
182.55 + //sb.append(" NESTED=" + nested);
182.56 + //sb.append("\n");
182.57 +
182.58 +
182.59 + // Sort to make test output stable
182.60 + List<String> keys = new ArrayList<>(tbl.keySet());
182.61 + Collections.sort(keys);
182.62 + for (String name : keys) {
182.63 + SymInfo info = tbl.get(name);
182.64 + for (int i = 0; i < level; i++) {
182.65 + sb.append(" ");
182.66 + }
182.67 + sb.append(name);
182.68 + sb.append(" ");
182.69 + sb.append(info.dumpFlags(this));
182.70 + sb.append("\n");
182.71 + }
182.72 +
182.73 + if (inner_free.size() > 0 || cellvars.size() > 0 || jy_paramcells.size() > 0 ||
182.74 + jy_npurecell != 0 /*|| cell != 0 || distance != 0 || up != null*/) {
182.75 + for (int i = 0; i < level; i++) {
182.76 + sb.append(" ");
182.77 + }
182.78 + sb.append("---------------------------------------------\n");
182.79 + }
182.80 +
182.81 + if (inner_free.size() > 0) {
182.82 + List<String> sorted = new ArrayList<>();
182.83 + for (String s : inner_free.keySet()) {
182.84 + sorted.add(s + "=" + inner_free.get(s));
182.85 + }
182.86 + Collections.sort(sorted);
182.87 +
182.88 + for (int i = 0; i < level; i++) {
182.89 + sb.append(" ");
182.90 + }
182.91 + sb.append("inner_free: {"); // NOI18N
182.92 + boolean first = true;
182.93 + for (String s : sorted) {
182.94 + if (first) {
182.95 + first = false;
182.96 + } else {
182.97 + sb.append(", "); // NOI18N
182.98 + }
182.99 + sb.append(s);
182.100 + }
182.101 + sb.append("}\n"); // NOI18N
182.102 + }
182.103 + if (cellvars.size() > 0) {
182.104 + Collections.sort(cellvars);
182.105 + for (int i = 0; i < level; i++) {
182.106 + sb.append(" ");
182.107 + }
182.108 + sb.append("cellvars: " + cellvars.toString() + "\n"); // TODO - sort
182.109 + }
182.110 + if (jy_paramcells.size() > 0) {
182.111 + Collections.sort(jy_paramcells);
182.112 + for (int i = 0; i < level; i++) {
182.113 + sb.append(" ");
182.114 + }
182.115 + sb.append("jy_paramcells: " + jy_paramcells.toString() + "\n"); // TODO - sort
182.116 + }
182.117 + if (jy_npurecell != 0) {
182.118 + for (int i = 0; i < level; i++) {
182.119 + sb.append(" ");
182.120 + }
182.121 + sb.append("jy_npurecell: " + jy_npurecell + "\n"); // TODO - sort
182.122 + }
182.123 + //if (cell != 0) {
182.124 + // for(int i=0; i<level; i++) sb.append(" ");
182.125 + // sb.append("cell: " + cell + "\n"); // TODO - sort
182.126 + //}
182.127 + //if (distance != 0) {
182.128 + // for(int i=0; i<level; i++) sb.append(" ");
182.129 + // sb.append("distance: " + distance + "\n"); // TODO - sort
182.130 + //}
182.131 + //if (up != null) {
182.132 + // for(int i=0; i<level; i++) sb.append(" ");
182.133 + // sb.append("up: " + up.scope_node);
182.134 + //}
182.135 +
182.136 + if (attributes.size() > 0) {
182.137 + for (int i = 0; i < level; i++) {
182.138 + sb.append(" ");
182.139 + }
182.140 + sb.append("------ Attributes ---------------------------------------\n"); // NOI18N
182.141 + // Sort
182.142 + List<String> attributeNames = new ArrayList<>(attributes.keySet());
182.143 + Collections.sort(attributeNames);
182.144 + for (String attributeName : attributeNames) {
182.145 + for (int i = 0; i < level; i++) {
182.146 + sb.append(" ");
182.147 + }
182.148 + sb.append(attributeName);
182.149 + sb.append(" : "); // NOI18N
182.150 + sb.append(attributes.get(attributeName));
182.151 + sb.append("\n"); // NOI18N
182.152 + }
182.153 + }
182.154 +
182.155 + return sb.toString();
182.156 + }
182.157 +
182.158 + public ScopeInfo(String name, PythonTree node, int level, int kind,
182.159 + int func_level, ArgListCompiler ac) {
182.160 + scope_name = name;
182.161 + scope_node = node;
182.162 + this.level = level;
182.163 + this.kind = kind;
182.164 + this.func_level = func_level;
182.165 + this.ac = ac;
182.166 + }
182.167 + public int kind;
182.168 + public boolean unqual_exec;
182.169 + public boolean exec;
182.170 + public boolean from_import_star;
182.171 + public boolean contains_ns_free_vars;
182.172 + public boolean generator;
182.173 + private boolean hasReturnWithValue;
182.174 + public int yield_count;
182.175 + public int max_with_count;
182.176 + public ArgListCompiler ac;
182.177 + public Map<String, SymInfo> tbl = new LinkedHashMap<>();
182.178 +
182.179 + // define a separate dictionary for dynamic bounded variables
182.180 + public Map<String, SymInfo> attributes = new HashMap<>();
182.181 + public List<String> names = new ArrayList<>();
182.182 +
182.183 + private void addAttributeEntry(String name, PythonTree node, int flags) {
182.184 + SymInfo info = attributes.get(name);
182.185 + if (info == null) {
182.186 + SymInfo entry = new SymInfo(flags);
182.187 + if (NameStyle.isPrivateName(name)) {
182.188 + entry.flags |= PRIVATE;
182.189 + } else if (NameStyle.isProtectedName(name)) {
182.190 + entry.flags |= PROTECTED;
182.191 + }
182.192 + entry.node = node;
182.193 + attributes.put(name, entry);
182.194 + }
182.195 + }
182.196 +
182.197 + private void addToClassScope(String name, PythonTree node, boolean inConstructor) {
182.198 + int flags = CLASSSCOPE | BOUND | MEMBER;
182.199 + if (inConstructor) {
182.200 + flags |= BOUND_IN_CONSTRUCTOR;
182.201 + }
182.202 + addAttributeEntry(name, node, flags);
182.203 + }
182.204 +
182.205 + public ScopeInfo getClassScope() {
182.206 + ScopeInfo cur = this;
182.207 + while ((cur != null) &&
182.208 + (!(cur.scope_node instanceof ClassDef))) {
182.209 + cur = cur.nested;
182.210 + }
182.211 + return cur;
182.212 + }
182.213 +
182.214 + private boolean belongsToExprList(List<expr> types, expr cur) {
182.215 + return types != null && types.contains(cur);
182.216 + }
182.217 +
182.218 + boolean isAttributeAssigment(AstPath path, Attribute attr) {
182.219 + PythonTree leaf = path.leaf();
182.220 + Assign assign = null;
182.221 + expr target = attr; // default to single
182.222 + if (leaf instanceof Assign) {
182.223 + assign = (Assign)leaf;
182.224 + } else if (leaf instanceof Tuple) {
182.225 + // check for tuple assignment
182.226 + Tuple tuple = (Tuple)leaf;
182.227 + PythonTree tupleParent = path.leafParent();
182.228 + if (belongsToExprList(tuple.getInternalElts(), attr)) {
182.229 + if (tupleParent instanceof Assign) {
182.230 + assign = (Assign)tupleParent;
182.231 + target = tuple; // tuple assignment target
182.232 + }
182.233 + }
182.234 + }
182.235 + // check if we got assignment
182.236 + if (assign == null) {
182.237 + return false;
182.238 + }
182.239 + if (belongsToExprList(assign.getInternalTargets(), target)) {
182.240 + return true;
182.241 + }
182.242 + return false;
182.243 + }
182.244 +
182.245 + public void addAttribute(AstPath path, String name, PythonTree node) {
182.246 + // deeply check assignment context for attribute.
182.247 + Attribute curAttr = (Attribute)node;
182.248 +
182.249 + if (curAttr.getInternalValue() instanceof Attribute) {
182.250 + // recursice attributes( x.y.z.w ) to be handled later
182.251 + } else if (curAttr.getInternalValue() instanceof Name) {
182.252 +
182.253 + Name parentName = (Name)curAttr.getInternalValue();
182.254 +
182.255 + ScopeInfo classScope = getClassScope();
182.256 + boolean inConstructor = false;
182.257 + String parName = parentName.getInternalId();
182.258 +
182.259 + // for simplicity handle only at classScope in current source
182.260 + if (classScope != null) {
182.261 + // check for self or inherited parent name prefix
182.262 + if ((parName.equals("self")) ||
182.263 + (PythonAstUtils.getParentClassFromNode(path, classScope.scope_node, parName) != null)) {
182.264 + if (!(parName.equals("self"))) {
182.265 + // check classname not overridden by local scope variable
182.266 + if (tbl.get(parName) != null) {
182.267 + return;
182.268 + }
182.269 + }
182.270 + if (scope_name.equals("__init__") || scope_name.equals("__new__")) {
182.271 + inConstructor = true; // set in constructor
182.272 + }
182.273 + //
182.274 + // put in class scope
182.275 + if (isAttributeAssigment(path, curAttr)) {
182.276 + classScope.addToClassScope(name, node, inConstructor);
182.277 + } else {
182.278 + // store at current scope if parName is not overriding
182.279 + // classname at current scope
182.280 + int flags = CLASSSCOPE | READ;
182.281 + addAttributeEntry(name, node, flags);
182.282 + }
182.283 + }
182.284 + }
182.285 + }
182.286 + }
182.287 +
182.288 + public int addGlobal(String name, PythonTree node) {
182.289 + // global kind = func vs. class
182.290 + int global = kind == CLASSSCOPE ? CLASS_GLOBAL : NGLOBAL;
182.291 + SymInfo info = tbl.get(name);
182.292 + if (info == null) {
182.293 + SymInfo entry = new SymInfo(global | BOUND);
182.294 + if (NameStyle.isPrivateName(name)) {
182.295 + entry.flags |= PRIVATE;
182.296 + } else if (NameStyle.isProtectedName(name)) {
182.297 + entry.flags |= PROTECTED;
182.298 + }
182.299 + entry.node = node;
182.300 + tbl.put(name, entry);
182.301 + return -1;
182.302 + }
182.303 + int prev = info.flags;
182.304 + info.flags |= global | BOUND;
182.305 + return prev;
182.306 + }
182.307 + public int local = 0;
182.308 +
182.309 + public void addParam(String name, PythonTree node) {
182.310 + SymInfo entry = new SymInfo(PARAM | BOUND, local++);
182.311 + entry.node = node;
182.312 + tbl.put(name, entry);
182.313 + names.add(name);
182.314 + }
182.315 +
182.316 + // <netbeans>
182.317 + public boolean isUnused(String name) {
182.318 + SymInfo info = tbl.get(name);
182.319 + if (info != null) {
182.320 + return info.isUnused(this);
182.321 + }
182.322 + return false;
182.323 + }
182.324 +
182.325 + public boolean isParameter(String name) {
182.326 + SymInfo info = tbl.get(name);
182.327 + if (info != null) {
182.328 + return info.isParameter();
182.329 + }
182.330 + return false;
182.331 + }
182.332 + // </netbeans>
182.333 +
182.334 + public void markFromParam() {
182.335 + for (SymInfo info : tbl.values()) {
182.336 + info.flags |= FROM_PARAM;
182.337 + }
182.338 + }
182.339 +
182.340 + public SymInfo addBound(String name, PythonTree node) {
182.341 + SymInfo info = tbl.get(name);
182.342 + if (info == null) {
182.343 + info = new SymInfo(BOUND);
182.344 + if (NameStyle.isPrivateName(name)) {
182.345 + info.flags |= PRIVATE;
182.346 + } else if (NameStyle.isProtectedName(name)) {
182.347 + info.flags |= PROTECTED;
182.348 + }
182.349 + tbl.put(name, info);
182.350 + info.node = node;
182.351 + return info;
182.352 + }
182.353 + info.flags |= BOUND;
182.354 +
182.355 + return info;
182.356 + }
182.357 +
182.358 + public SymInfo addUsed(String name, PythonTree node) {
182.359 + SymInfo info = tbl.get(name);
182.360 + if (info == null) {
182.361 + // <netbeans>
182.362 + info = new SymInfo(0);
182.363 + tbl.put(name, info);
182.364 + info.node = node;
182.365 + }
182.366 + info.flags |= READ;
182.367 +
182.368 + return info;
182.369 + // </netbeans>
182.370 + }
182.371 +
182.372 +
182.373 + // <netbeans>
182.374 + void markCall(String name) {
182.375 + SymInfo entry = tbl.get(name);
182.376 + if (entry != null) {
182.377 + entry.flags |= CALLED;
182.378 + }
182.379 + }
182.380 + // </netbeans>
182.381 + private final static String PRESENT = new String("PRESENT");
182.382 + public HashMap<String, String> inner_free = new HashMap<>();
182.383 + public List<String> cellvars = new ArrayList<>();
182.384 + public List<String> jy_paramcells = new ArrayList<>();
182.385 + public int jy_npurecell;
182.386 + public int cell, distance;
182.387 + public ScopeInfo up;
182.388 + public ScopeInfo nested;
182.389 +
182.390 + //Resolve the names used in the given scope, and mark any freevars used in the up scope
182.391 + public void cook(ScopeInfo up, int distance, SymbolTable ctxt) throws Exception {
182.392 + if (up == null) {
182.393 + return; // top level => nop
182.394 + }
182.395 + this.up = up;
182.396 + this.distance = distance;
182.397 + boolean func = kind == FUNCSCOPE;
182.398 + List<String> purecells = new ArrayList<>();
182.399 + cell = 0;
182.400 + boolean some_inner_free = inner_free.size() > 0;
182.401 +
182.402 + for (String name : inner_free.keySet()) {
182.403 +
182.404 + SymInfo info = tbl.get(name);
182.405 + if (info == null) {
182.406 + tbl.put(name, new SymInfo(FREE));
182.407 + continue;
182.408 + }
182.409 + int flags = info.flags;
182.410 + if (func) {
182.411 + // not func global and bound ?
182.412 + if ((flags & NGLOBAL) == 0 && (flags & BOUND) != 0) {
182.413 + info.flags |= CELL;
182.414 + if ((info.flags & PARAM) != 0) {
182.415 + jy_paramcells.add(name);
182.416 + }
182.417 + cellvars.add(name);
182.418 + info.env_index = cell++;
182.419 + if ((flags & PARAM) == 0) {
182.420 + purecells.add(name);
182.421 + }
182.422 + continue;
182.423 + }
182.424 + } else {
182.425 + info.flags |= FREE;
182.426 + }
182.427 + }
182.428 + boolean some_free = false;
182.429 +
182.430 + boolean nested = up.kind != TOPSCOPE;
182.431 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
182.432 + String name = entry.getKey();
182.433 + SymInfo info = entry.getValue();
182.434 + int flags = info.flags;
182.435 + if (nested && (flags & FREE) != 0) {
182.436 + up.inner_free.put(name, PRESENT);
182.437 + }
182.438 + if ((flags & (GLOBAL | PARAM | CELL)) == 0) {
182.439 + if ((flags & BOUND) != 0) { // ?? only func
182.440 + // System.err.println("local: "+name);
182.441 + names.add(name);
182.442 + info.locals_index = local++;
182.443 + continue;
182.444 + }
182.445 + info.flags |= FREE;
182.446 + some_free = true;
182.447 + if (nested) {
182.448 + up.inner_free.put(name, PRESENT);
182.449 + }
182.450 + }
182.451 +
182.452 + // <netbeans>
182.453 + if ((info.flags & FREE) != 0) {
182.454 + // Mark definition symbol as read as well
182.455 + ScopeInfo curr = up;
182.456 + while (curr != null) {
182.457 + SymInfo s = curr.tbl.get(name);
182.458 + if (s != null && ((s.flags & BOUND) != 0)) {
182.459 + s.flags |= READ;
182.460 + s.flags |= (info.flags & (CALLED));
182.461 + break;
182.462 + }
182.463 + curr = curr.up;
182.464 + while (curr != null && curr.kind == CLASSSCOPE) {
182.465 + curr = curr.up;
182.466 + }
182.467 + }
182.468 + }
182.469 +
182.470 + // </netbeans>
182.471 + }
182.472 + if ((jy_npurecell = purecells.size()) > 0) {
182.473 + int sz = purecells.size();
182.474 + for (int i = 0; i < sz; i++) {
182.475 + names.add(purecells.get(i));
182.476 + }
182.477 + }
182.478 +
182.479 + if (some_free && nested) {
182.480 + up.contains_ns_free_vars = true;
182.481 + }
182.482 + // XXX - this doesn't catch all cases - may depend subtly
182.483 + // on how visiting NOW works with antlr compared to javacc
182.484 + if ((unqual_exec || from_import_star)) {
182.485 + if (some_inner_free) {
182.486 + dynastuff_trouble(true, ctxt);
182.487 + } else if (func_level > 1 && some_free) {
182.488 + dynastuff_trouble(false, ctxt);
182.489 + }
182.490 + }
182.491 +
182.492 + }
182.493 +
182.494 + private void dynastuff_trouble(boolean inner_free,
182.495 + SymbolTable ctxt) throws Exception {
182.496 + String illegal;
182.497 + if (unqual_exec && from_import_star) {
182.498 + illegal = "function '" + scope_name +
182.499 + "' uses import * and bare exec, which are illegal";
182.500 + } else if (unqual_exec) {
182.501 + illegal = "unqualified exec is not allowed in function '" +
182.502 + scope_name + "'";
182.503 + } else {
182.504 + illegal = "import * is not allowed in function '" + scope_name + "'";
182.505 + }
182.506 + String why;
182.507 + if (inner_free) {
182.508 + why = " because it contains a function with free variables";
182.509 + } else {
182.510 + why = " because it contains free variables";
182.511 + }
182.512 + ctxt.error(illegal + why, true, scope_node);
182.513 + }
182.514 + public List<String> freevars = new ArrayList<>();
182.515 +
182.516 + /**
182.517 + * setup the closure on this scope using the scope passed into cook as up as
182.518 + * the containing scope
182.519 + */
182.520 + public void setup_closure() {
182.521 + setup_closure(up);
182.522 + }
182.523 +
182.524 + /**
182.525 + * setup the closure on this scope using the passed in scope. This is used
182.526 + * by jythonc to setup its closures.
182.527 + */
182.528 + public void setup_closure(ScopeInfo up) {
182.529 + int free = cell; // env = cell...,free...
182.530 + Map<String, SymInfo> up_tbl = up.tbl;
182.531 + boolean nested = up.kind != TOPSCOPE;
182.532 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
182.533 + String name = entry.getKey();
182.534 + SymInfo info = entry.getValue();
182.535 + int flags = info.flags;
182.536 + if ((flags & FREE) != 0) {
182.537 + SymInfo up_info = up_tbl.get(name);
182.538 + // ?? differs from CPython -- what is the intended behaviour?
182.539 + if (up_info != null) {
182.540 + int up_flags = up_info.flags;
182.541 + if ((up_flags & (CELL | FREE)) != 0) {
182.542 + info.env_index = free++;
182.543 + freevars.add(name);
182.544 + continue;
182.545 + }
182.546 + // ! func global affect nested scopes
182.547 + if (nested && (up_flags & NGLOBAL) != 0) {
182.548 + info.flags = NGLOBAL | BOUND;
182.549 + continue;
182.550 + }
182.551 + }
182.552 + info.flags &= ~FREE;
182.553 + }
182.554 + }
182.555 +
182.556 + }
182.557 +
182.558 + @Override
182.559 + public String toString() {
182.560 + return "ScopeInfo[" + scope_name + " " + kind + "]@" +
182.561 + System.identityHashCode(this);
182.562 + }
182.563 +
182.564 + public void defineAsGenerator(expr node) {
182.565 + generator = true;
182.566 + if (hasReturnWithValue) {
182.567 + throw new ParseException("'return' with argument " +
182.568 + "inside generator", node);
182.569 + }
182.570 + }
182.571 +
182.572 + public void noteReturnValue(Return node) {
182.573 + if (generator) {
182.574 + throw new ParseException("'return' with argument " +
182.575 + "inside generator", node);
182.576 + }
182.577 + hasReturnWithValue = true;
182.578 + }
182.579 +}
183.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
183.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/ScopesCompiler.java Wed Sep 02 20:31:18 2015 +0200
183.3 @@ -0,0 +1,641 @@
183.4 +// (C) Copyright 2001 Samuele Pedroni
183.5 +package org.netbeans.modules.python.source.scopes;
183.6 +
183.7 +import java.util.ArrayList;
183.8 +import java.util.List;
183.9 +import java.util.Map;
183.10 +import java.util.Set;
183.11 +import java.util.Stack;
183.12 +import org.netbeans.modules.python.source.AstPath;
183.13 +import org.openide.util.Exceptions;
183.14 +import org.python.antlr.PythonTree;
183.15 +import org.python.antlr.Visitor;
183.16 +import org.python.antlr.ast.Assign;
183.17 +import org.python.antlr.ast.Attribute;
183.18 +import org.python.antlr.ast.Call;
183.19 +import org.python.antlr.ast.ClassDef;
183.20 +import org.python.antlr.ast.Delete;
183.21 +import org.python.antlr.ast.Exec;
183.22 +import org.python.antlr.ast.Expression;
183.23 +import org.python.antlr.ast.FunctionDef;
183.24 +import org.python.antlr.ast.GeneratorExp;
183.25 +import org.python.antlr.ast.Global;
183.26 +import org.python.antlr.ast.Import;
183.27 +import org.python.antlr.ast.ImportFrom;
183.28 +import org.python.antlr.ast.Interactive;
183.29 +import org.python.antlr.ast.Lambda;
183.30 +import org.python.antlr.ast.ListComp;
183.31 +import org.python.antlr.ast.Name;
183.32 +import org.python.antlr.ast.Return;
183.33 +import org.python.antlr.ast.Str;
183.34 +import org.python.antlr.ast.With;
183.35 +import org.python.antlr.ast.Yield;
183.36 +import org.python.antlr.ast.alias;
183.37 +import org.python.antlr.ast.arguments;
183.38 +import org.python.antlr.base.expr;
183.39 +import org.python.antlr.ast.expr_contextType;
183.40 +import org.python.antlr.base.stmt;
183.41 +
183.42 +/**
183.43 + * Based on org.python.compiler.ScopesCompiler in Jython
183.44 + *
183.45 + * Modifications I've made:
183.46 + * - Methods for finding all the free variables
183.47 + * - Methods for identifying unused bound variables
183.48 + * - Track whether symbols are referenced as calls or not
183.49 + * (so I can determine whether to look in the index for
183.50 + * functions or data etc. when trying to resolve imports)
183.51 + * - Track variable reads/writes
183.52 + * - Track imports etc.
183.53 + * - Add nodes to each SymInfo
183.54 + * - Replace old style Java (Hashtable, Vector, implements ScopeConstants) with
183.55 + * modern Java (HashMap, ArrayList, import static)
183.56 + *
183.57 + */
183.58 +@SuppressWarnings("unchecked")
183.59 +public class ScopesCompiler extends Visitor implements ScopeConstants {
183.60 + private SymbolTable symbolTable;
183.61 + private Stack scopes;
183.62 + private ScopeInfo cur = null;
183.63 + private Map<PythonTree, ScopeInfo> nodeScopes;
183.64 + private int level = 0;
183.65 + private int func_level = 0;
183.66 + private List<Import> imports;
183.67 + private List<PythonTree> mainImports;
183.68 + private List<ImportFrom> importsFrom;
183.69 + private Set<PythonTree> topLevelImports;
183.70 + private PythonTree root;
183.71 + private PythonTree parent;
183.72 + private AstPath path = new AstPath();
183.73 + /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
183.74 + private List<Str> publicSymbols;
183.75 + /** Set to true if we encountered manipulation on __all__ that I don't understand */
183.76 + private boolean invalidPublicSymbols;
183.77 +
183.78 + public ScopesCompiler(SymbolTable symbolTable, Map<PythonTree, ScopeInfo> nodeScopes, PythonTree root,
183.79 + List<Import> imports, List<ImportFrom> importsFrom, List<PythonTree> mainImports, Set<PythonTree> topLevelImports) {
183.80 + this.symbolTable = symbolTable;
183.81 + this.nodeScopes = nodeScopes;
183.82 + scopes = new Stack();
183.83 + this.root = root;
183.84 +
183.85 + this.imports = imports;
183.86 + this.importsFrom = importsFrom;
183.87 + this.mainImports = mainImports;
183.88 + this.topLevelImports = topLevelImports;
183.89 + }
183.90 +
183.91 + @Override
183.92 + public void traverse(PythonTree node) throws Exception {
183.93 + // Jython's parser often doesn't set the parent references correctly
183.94 + // so try to fix that here
183.95 + node.setParent(parent);
183.96 +
183.97 + PythonTree oldParent = parent;
183.98 + parent = node;
183.99 +
183.100 + path.descend(node);
183.101 + super.traverse(node);
183.102 + parent = oldParent;
183.103 + path.ascend();
183.104 + }
183.105 +
183.106 + public void beginScope(String name, int kind, PythonTree node,
183.107 + ArgListCompiler ac) {
183.108 + if (cur != null) {
183.109 + scopes.push(cur);
183.110 + }
183.111 + if (kind == FUNCSCOPE) {
183.112 + func_level++;
183.113 + }
183.114 + cur = new ScopeInfo(name, node, level++, kind, func_level, ac);
183.115 + nodeScopes.put(node, cur);
183.116 + }
183.117 +
183.118 + public void endScope() throws Exception {
183.119 + if (cur.kind == FUNCSCOPE) {
183.120 + func_level--;
183.121 + }
183.122 + level--;
183.123 + ScopeInfo up = null;
183.124 + if (!scopes.empty()) {
183.125 + up = (ScopeInfo)scopes.pop();
183.126 + }
183.127 + //Go into the stack to find a non class containing scope to use making the closure
183.128 + //See PEP 227
183.129 + int dist = 1;
183.130 + ScopeInfo referenceable = up;
183.131 + for (int i = scopes.size() - 1; i >= 0 && referenceable.kind == CLASSSCOPE; i--, dist++) {
183.132 + referenceable = ((ScopeInfo)scopes.get(i));
183.133 + }
183.134 + cur.cook(referenceable, dist, symbolTable);
183.135 +// cur.dump(); // debug
183.136 + cur = up;
183.137 + }
183.138 +
183.139 + public void parse() {
183.140 + try {
183.141 + visit(root);
183.142 + } catch (Throwable t) {
183.143 + Exceptions.printStackTrace(t);
183.144 + //throw org.python.core.ParserFacade.fixParseError(null, t,
183.145 + // code_compiler.getFilename());
183.146 + }
183.147 + }
183.148 +
183.149 + @Override
183.150 + public Object visitInteractive(Interactive node) throws Exception {
183.151 + beginScope("<single-top>", TOPSCOPE, node, null);
183.152 + PythonTree oldParent = parent;
183.153 + parent = node;
183.154 + suite(node.getInternalBody());
183.155 + parent = oldParent;
183.156 + endScope();
183.157 + return null;
183.158 + }
183.159 +
183.160 + @Override
183.161 + public Object visitModule(org.python.antlr.ast.Module node)
183.162 + throws Exception {
183.163 + List<stmt> body = node.getInternalBody();
183.164 + if (body != null && body.size() > 0) {
183.165 + boolean foundFirst = false;
183.166 + for (stmt stmt : body) {
183.167 + if (stmt != null) {
183.168 + if (stmt instanceof Import || stmt instanceof ImportFrom) {
183.169 + if (!foundFirst) {
183.170 + foundFirst = true;
183.171 + }
183.172 + mainImports.add(stmt);
183.173 + } else if (foundFirst) {
183.174 + break;
183.175 + }
183.176 + }
183.177 + }
183.178 + }
183.179 +
183.180 + beginScope("<file-top>", TOPSCOPE, node, null);
183.181 +
183.182 + PythonTree oldParent = parent;
183.183 + parent = node;
183.184 + suite(node.getInternalBody());
183.185 + parent = oldParent;
183.186 +
183.187 + endScope();
183.188 + return null;
183.189 + }
183.190 +
183.191 + @Override
183.192 + public Object visitExpression(Expression node) throws Exception {
183.193 + beginScope("<eval-top>", TOPSCOPE, node, null);
183.194 + visit(new Return(node, node.getInternalBody()));
183.195 + endScope();
183.196 + return null;
183.197 + }
183.198 +
183.199 + private void def(String name, int extraFlags, PythonTree node) {
183.200 + SymInfo info = cur.addBound(name, node);
183.201 + // <netbeans>
183.202 + info.flags |= (DEF | extraFlags);
183.203 + info.node = node;
183.204 + // </netbeans>
183.205 + }
183.206 +
183.207 + @Override
183.208 + public Object visitAssign(Assign node) throws Exception {
183.209 + List<expr> targets = node.getInternalTargets();
183.210 + if (targets != null && targets.size() == 1 && targets.get(0) instanceof Name) {
183.211 + Name lhs = (Name)targets.get(0);
183.212 + if ("__all__".equals(lhs.getInternalId())) { // NOI18N
183.213 + expr nodeValue = node.getInternalValue();
183.214 + if (!invalidPublicSymbols && nodeValue instanceof org.python.antlr.ast.List) {
183.215 + org.python.antlr.ast.List allList = (org.python.antlr.ast.List)nodeValue;
183.216 + if (allList != null) {
183.217 + for (expr expr : allList.getInternalElts()) {
183.218 + if (expr instanceof Str) {
183.219 + Str str = (Str)expr;
183.220 + if (publicSymbols == null) {
183.221 + publicSymbols = new ArrayList<>();
183.222 + }
183.223 + publicSymbols.add(str);
183.224 + } else {
183.225 + invalidPublicSymbols = true;
183.226 + }
183.227 + }
183.228 + }
183.229 + } else {
183.230 + invalidPublicSymbols = true;
183.231 + }
183.232 + }
183.233 + }
183.234 +
183.235 + if (targets.size() > 0) {
183.236 + List<Name> names = new ArrayList<>(targets.size());
183.237 + boolean valid = true;
183.238 + for (expr et : targets) {
183.239 + if (et instanceof Name) {
183.240 + Name name = (Name)et;
183.241 + names.add(name);
183.242 + } else {
183.243 + valid = false;
183.244 + }
183.245 + }
183.246 + if (valid) {
183.247 + expr nodeValue = node.getInternalValue();
183.248 + if (nodeValue instanceof Name) {
183.249 + Name value = (Name)nodeValue;
183.250 +
183.251 + SymInfo rhsSym = cur.tbl.get(value.getInternalId());
183.252 + if (rhsSym != null && rhsSym.isDef()) {
183.253 + for (Name name : names) {
183.254 + visitName(name);
183.255 + SymInfo sym = cur.tbl.get(name.getInternalId());
183.256 + if (sym != null) {
183.257 + sym.flags |= ALIAS;
183.258 + sym.flags |= (rhsSym.flags & (CLASS | FUNCTION));
183.259 + sym.node = rhsSym.node;
183.260 + }
183.261 + }
183.262 + }
183.263 + }
183.264 + }
183.265 + }
183.266 +
183.267 + return super.visitAssign(node);
183.268 + }
183.269 +
183.270 + @Override
183.271 + public Object visitFunctionDef(FunctionDef node) throws Exception {
183.272 + def(node.getInternalName(), FUNCTION, node);
183.273 + ArgListCompiler ac = new ArgListCompiler(symbolTable);
183.274 + ac.visitArgs(node.getInternalArgs());
183.275 +
183.276 + List<expr> defaults = ac.getDefaults();
183.277 + for (int i = 0; i < defaults.size(); i++) {
183.278 + visit(defaults.get(i));
183.279 + }
183.280 +
183.281 + List<expr> decs = node.getInternalDecorator_list();
183.282 + for (int i = decs.size() - 1; i >= 0; i--) {
183.283 + visit(decs.get(i));
183.284 + }
183.285 +
183.286 + ScopeInfo parentScope = cur;
183.287 + beginScope(node.getInternalName(), FUNCSCOPE, node, ac);
183.288 + cur.nested = parentScope;
183.289 +
183.290 + int n = ac.names.size();
183.291 + for (int i = 0; i < n; i++) {
183.292 + cur.addParam(ac.names.get(i), ac.nodes.get(i));
183.293 + }
183.294 + for (int i = 0; i < ac.init_code.size(); i++) {
183.295 + visit(ac.init_code.get(i));
183.296 + }
183.297 + cur.markFromParam();
183.298 +
183.299 + PythonTree oldParent = parent;
183.300 + parent = node;
183.301 + suite(node.getInternalBody());
183.302 + parent = oldParent;
183.303 +
183.304 + endScope();
183.305 + return null;
183.306 + }
183.307 +
183.308 + @Override
183.309 + public Object visitLambda(Lambda node) throws Exception {
183.310 + ArgListCompiler ac = new ArgListCompiler(symbolTable);
183.311 + ac.visitArgs(node.getInternalArgs());
183.312 +
183.313 + List<expr> defaults = ac.getDefaults();
183.314 + for (expr expr : defaults) {
183.315 + visit(expr);
183.316 + }
183.317 +
183.318 + beginScope("<lambda>", FUNCSCOPE, node, ac);
183.319 + assert ac.names.size() == ac.nodes.size();
183.320 + for (int i = 0; i < ac.names.size(); i++) {
183.321 + cur.addParam(ac.names.get(i), ac.nodes.get(i));
183.322 + }
183.323 + for (Object o : ac.init_code) {
183.324 + visit((stmt)o);
183.325 + }
183.326 + cur.markFromParam();
183.327 + visit(node.getInternalBody());
183.328 + endScope();
183.329 + return null;
183.330 + }
183.331 +
183.332 + public void suite(List<stmt> stmts) throws Exception {
183.333 + if (stmts != null) {
183.334 + for (int i = 0; i < stmts.size(); i++) {
183.335 + stmt s = stmts.get(i);
183.336 + path.descend(s);
183.337 + visit(s);
183.338 + path.ascend();
183.339 + }
183.340 + }
183.341 + }
183.342 +
183.343 + @Override
183.344 + public Object visitImport(Import node) throws Exception {
183.345 + if (parent == root) {
183.346 + topLevelImports.add(node);
183.347 + }
183.348 + imports.add(node);
183.349 +
183.350 + List<alias> names = node.getInternalNames();
183.351 + if (names != null) {
183.352 + for (alias alias : names) {
183.353 + String asname = alias.getInternalAsname();
183.354 + if (asname != null) {
183.355 + SymInfo entry = cur.addBound(asname, node);
183.356 + entry.flags |= IMPORTED;
183.357 + } else {
183.358 + String name = alias.getInternalName();
183.359 + if (name.indexOf('.') > 0) {
183.360 + name = name.substring(0, name.indexOf('.'));
183.361 + }
183.362 + SymInfo entry = cur.addBound(name, node);
183.363 + entry.flags |= IMPORTED;
183.364 + }
183.365 + }
183.366 + }
183.367 + return null;
183.368 + }
183.369 +
183.370 + @Override
183.371 + public Object visitImportFrom(ImportFrom node) throws Exception {
183.372 + if (parent == root) {
183.373 + topLevelImports.add(node);
183.374 + }
183.375 + importsFrom.add(node);
183.376 +
183.377 + //Future.checkFromFuture(node); // future stmt support
183.378 + List<alias> names = node.getInternalNames();
183.379 + if (names == null || names.size() == 0) {
183.380 + cur.from_import_star = true;
183.381 + return null;
183.382 + }
183.383 + for (alias alias : names) {
183.384 + String asname = alias.getInternalAsname();
183.385 + if (asname != null) {
183.386 + SymInfo entry = cur.addBound(asname, node);
183.387 + entry.flags |= IMPORTED;
183.388 + } else {
183.389 + SymInfo entry = cur.addBound(alias.getInternalName(), node);
183.390 + entry.flags |= IMPORTED;
183.391 + }
183.392 + }
183.393 + return null;
183.394 + }
183.395 +
183.396 + @Override
183.397 + public Object visitGlobal(Global node) throws Exception {
183.398 + List<String> names = node.getInternalNames();
183.399 + for (String name : names) {
183.400 + int prev = cur.addGlobal(name, node);
183.401 + if (prev >= 0) {
183.402 + if ((prev & FROM_PARAM) != 0) {
183.403 + symbolTable.error("name '" + name + "' is local and global", true, node);
183.404 + }
183.405 + if ((prev & GLOBAL) != 0) {
183.406 + continue;
183.407 + }
183.408 + String what;
183.409 + if ((prev & BOUND) != 0) {
183.410 + what = "assignment";
183.411 + } else {
183.412 + what = "use";
183.413 + }
183.414 + symbolTable.error("name '" + name + "' declared global after " + what, false, node);
183.415 + }
183.416 + }
183.417 + return null;
183.418 + }
183.419 +
183.420 + @Override
183.421 + public Object visitExec(Exec node) throws Exception {
183.422 + cur.exec = true;
183.423 + if (node.getInternalGlobals() == null && node.getInternalLocals() == null) {
183.424 + cur.unqual_exec = true;
183.425 + }
183.426 + traverse(node);
183.427 + return null;
183.428 + }
183.429 +
183.430 + @Override
183.431 + public Object visitClassDef(ClassDef node) throws Exception {
183.432 + String name = node.getInternalName();
183.433 + def(name, CLASS, node);
183.434 + List<expr> bases = node.getInternalBases();
183.435 + if (bases != null) {
183.436 + for (expr expr : bases) {
183.437 + visit(expr);
183.438 + }
183.439 + }
183.440 + ScopeInfo parentScope = cur;
183.441 + beginScope(name, CLASSSCOPE, node, null);
183.442 + cur.nested = parentScope;
183.443 + PythonTree oldParent = parent;
183.444 + parent = node;
183.445 + suite(node.getInternalBody());
183.446 + parent = oldParent;
183.447 + endScope();
183.448 + return null;
183.449 + }
183.450 +
183.451 + @Override
183.452 + public Object visitName(Name node) throws Exception {
183.453 + // Jython's parser doesn't always initialize the parent references correctly;
183.454 + // try to correct that here.
183.455 + node.setParent(parent);
183.456 +
183.457 + String name = node.getInternalId();
183.458 + if (node.getInternalCtx() != expr_contextType.Load) {
183.459 + if (name.equals("__debug__")) {
183.460 + symbolTable.error("can not assign to __debug__", true, node);
183.461 + }
183.462 + cur.addBound(name, node);
183.463 + } else {
183.464 + cur.addUsed(name, node);
183.465 + }
183.466 + return null;
183.467 + }
183.468 +
183.469 + // <netbeans>
183.470 + @Override
183.471 + public Object visitCall(Call node) throws Exception {
183.472 + Object ret = super.visitCall(node);
183.473 +
183.474 + expr func = node.getInternalFunc();
183.475 + if (func instanceof Name) {
183.476 + Name name = (Name)func;
183.477 + cur.markCall(name.getInternalId());
183.478 + } else if (func instanceof Attribute) {
183.479 + Attribute attr = (Attribute)func;
183.480 + if (cur.attributes != null) {
183.481 + SymInfo funcSymbol = cur.attributes.get(attr.getInternalAttr());
183.482 + if (funcSymbol != null) {
183.483 + funcSymbol.flags |= FUNCTION | CALLED; // mark as func/method call
183.484 + }
183.485 + }
183.486 +
183.487 + }
183.488 +
183.489 + return ret;
183.490 + }
183.491 +
183.492 + @Override
183.493 + public Object visitDelete(Delete node) throws Exception {
183.494 + for (expr et : node.getInternalTargets()) {
183.495 + if (et instanceof Name) {
183.496 + String name = ((Name)et).getInternalId();
183.497 + cur.addUsed(name, node);
183.498 + }
183.499 + }
183.500 +
183.501 + return super.visitDelete(node);
183.502 + }
183.503 +
183.504 + @Override
183.505 + public Object visitAttribute(Attribute node) throws Exception {
183.506 + if (parent instanceof Call && node.getInternalValue() instanceof Name &&
183.507 + ("__all__".equals(((Name)node.getInternalValue()).getInternalId()))) {
183.508 + // If you for example call
183.509 + // __all__.extend("foo")
183.510 + // or
183.511 + // __all__.append("bar")
183.512 + // then I don't want to try to analyze __all__
183.513 + String nodeAttr = node.getInternalAttr();
183.514 + if ("extend".equals(nodeAttr) || "append".equals(nodeAttr)) { // NOI18N
183.515 + Call call = (Call)parent;
183.516 + List<expr> callArgs = call.getInternalArgs();
183.517 + if (callArgs != null) {
183.518 + for (expr expr : callArgs) {
183.519 + if (expr instanceof Str) {
183.520 + if (publicSymbols == null) {
183.521 + publicSymbols = new ArrayList<>();
183.522 + }
183.523 + publicSymbols.add((Str)expr);
183.524 + } else if (expr instanceof org.python.antlr.ast.List) {
183.525 + org.python.antlr.ast.List list = (org.python.antlr.ast.List)expr;
183.526 + if (list != null) {
183.527 + List<expr> elts = list.getInternalElts();
183.528 + if (elts != null) {
183.529 + for (expr ex : elts) {
183.530 + if (ex instanceof Str) {
183.531 + Str str = (Str)ex;
183.532 + if (publicSymbols == null) {
183.533 + publicSymbols = new ArrayList<>();
183.534 + }
183.535 + publicSymbols.add(str);
183.536 + } else {
183.537 + invalidPublicSymbols = true;
183.538 + }
183.539 + }
183.540 + }
183.541 + }
183.542 + } else {
183.543 + invalidPublicSymbols = true;
183.544 + break;
183.545 + }
183.546 + }
183.547 + }
183.548 + } else {
183.549 + invalidPublicSymbols = true;
183.550 + }
183.551 + } else {
183.552 + String nodeAttr = node.getInternalAttr();
183.553 + if (nodeAttr != null) {
183.554 + cur.addAttribute(path, nodeAttr, node);
183.555 + }
183.556 + }
183.557 + return super.visitAttribute(node);
183.558 + }
183.559 + // </netbeans>
183.560 +
183.561 + @Override
183.562 + public Object visitListComp(ListComp node) throws Exception {
183.563 + String tmp = "_[" + node.getLine() + "_" + node.getCharPositionInLine() + "]";
183.564 + cur.addBound(tmp, node);
183.565 + traverse(node);
183.566 + return null;
183.567 + }
183.568 +
183.569 + @Override
183.570 + public Object visitYield(Yield node) throws Exception {
183.571 + cur.defineAsGenerator(node);
183.572 + cur.yield_count++;
183.573 + traverse(node);
183.574 + return null;
183.575 + }
183.576 +
183.577 + @Override
183.578 + public Object visitReturn(Return node) throws Exception {
183.579 + if (node.getInternalValue() != null) {
183.580 + cur.noteReturnValue(node);
183.581 + }
183.582 + traverse(node);
183.583 + return null;
183.584 + }
183.585 +
183.586 + @Override
183.587 + public Object visitGeneratorExp(GeneratorExp node) throws Exception {
183.588 + // The first iterator is evaluated in the outer scope
183.589 + if (node.getInternalGenerators() != null && node.getInternalGenerators().size() > 0) {
183.590 + visit(node.getInternalGenerators().get(0).getInternalIter());
183.591 + }
183.592 + String bound_exp = "_(x)";
183.593 + String tmp = "_(" + node.getLine() + "_" + node.getCharPositionInLine() + ")";
183.594 + def(tmp, GENERATOR, node);
183.595 + ArgListCompiler ac = new ArgListCompiler(symbolTable);
183.596 + List<expr> args = new ArrayList<>();
183.597 + Name argsName = new Name(node.getToken(), bound_exp, expr_contextType.Param);
183.598 + args.add(argsName);
183.599 + ac.visitArgs(new arguments(node, args, null, null, new ArrayList<expr>()));
183.600 + beginScope(tmp, FUNCSCOPE, node, ac);
183.601 + cur.addParam(bound_exp, argsName);
183.602 + cur.markFromParam();
183.603 +
183.604 + cur.defineAsGenerator(node);
183.605 + cur.yield_count++;
183.606 + // The reset of the iterators are evaluated in the inner scope
183.607 + if (node.getInternalElt() != null) {
183.608 + visit(node.getInternalElt());
183.609 + }
183.610 + if (node.getInternalGenerators() != null) {
183.611 + for (int i = 0; i < node.getInternalGenerators().size(); i++) {
183.612 + if (node.getInternalGenerators().get(i) != null) {
183.613 + if (i == 0) {
183.614 + visit(node.getInternalGenerators().get(i).getInternalTarget());
183.615 + if (node.getInternalGenerators().get(i).getInternalIfs() != null) {
183.616 + for (expr cond : node.getInternalGenerators().get(i).getInternalIfs()) {
183.617 + if (cond != null) {
183.618 + visit(cond);
183.619 + }
183.620 + }
183.621 + }
183.622 + } else {
183.623 + visit(node.getInternalGenerators().get(i));
183.624 + }
183.625 + }
183.626 + }
183.627 + }
183.628 +
183.629 + endScope();
183.630 + return null;
183.631 + }
183.632 +
183.633 + @Override
183.634 + public Object visitWith(With node) throws Exception {
183.635 + cur.max_with_count++;
183.636 + traverse(node);
183.637 +
183.638 + return null;
183.639 + }
183.640 +
183.641 + public List<Str> getPublicSymbols() {
183.642 + return invalidPublicSymbols ? null : publicSymbols;
183.643 + }
183.644 +}
184.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
184.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/SymInfo.java Wed Sep 02 20:31:18 2015 +0200
184.3 @@ -0,0 +1,182 @@
184.4 +package org.netbeans.modules.python.source.scopes;
184.5 +
184.6 +import org.python.antlr.PythonTree;
184.7 +import static org.netbeans.modules.python.source.scopes.ScopeConstants.*;
184.8 +
184.9 +public class SymInfo extends Object {
184.10 + public SymInfo(int flags) {
184.11 + this.flags = flags;
184.12 + }
184.13 +
184.14 + public SymInfo(int flags, int locals_index) {
184.15 + this.flags = flags;
184.16 + this.locals_index = locals_index;
184.17 + }
184.18 + public int flags;
184.19 + public int locals_index;
184.20 + public int env_index;
184.21 + public PythonTree node;
184.22 +
184.23 + @Override
184.24 + public String toString() {
184.25 + return "SymInfo[" + flags + " " + locals_index + " " +
184.26 + env_index + "]" + dumpFlags(null);
184.27 + }
184.28 +
184.29 + public String dumpFlags(ScopeInfo info) {
184.30 + StringBuilder sb = new StringBuilder();
184.31 + if ((flags & BOUND) != 0) {
184.32 + sb.append("[bound]");
184.33 + }
184.34 + // func scope global (affect nested scopes)
184.35 + // vs. class scope global
184.36 + if ((flags & NGLOBAL) != 0) {
184.37 + sb.append("[func-global]");
184.38 + } else if ((flags & CLASS_GLOBAL) != 0) {
184.39 + sb.append("[class-global]");
184.40 + }
184.41 + if ((flags & PARAM) != 0) {
184.42 + sb.append("[param]");
184.43 + } else if ((flags & FROM_PARAM) != 0) {
184.44 + sb.append("[from-param]");
184.45 + }
184.46 + if ((flags & CELL) != 0) {
184.47 + sb.append("[cell]");
184.48 + }
184.49 + if ((flags & FREE) != 0) {
184.50 + sb.append("[free]");
184.51 + }
184.52 + if (isImported()) {
184.53 + sb.append("[imported]");
184.54 + }
184.55 + if (isPrivate()) {
184.56 + sb.append("[private]");
184.57 + }
184.58 + if (isClass()) {
184.59 + sb.append("[class]");
184.60 + }
184.61 + if (isFunction()) {
184.62 + sb.append("[function]");
184.63 + }
184.64 + if (isData()) {
184.65 + sb.append("[data]");
184.66 + }
184.67 + if (isMember()) {
184.68 + sb.append("[member]");
184.69 + }
184.70 + if (isDef()) {
184.71 + sb.append("[def]");
184.72 + }
184.73 + if (isRead()) {
184.74 + sb.append("[read]");
184.75 + }
184.76 + if (isAlias()) {
184.77 + sb.append("[alias]");
184.78 + }
184.79 + if (isGeneratorExp()) {
184.80 + sb.append("[generator]");
184.81 + }
184.82 + if (isCalled()) {
184.83 + sb.append("[called]");
184.84 + }
184.85 + if (isProtected()) {
184.86 + sb.append("[protected]");
184.87 + }
184.88 + if (isBoundInConstructor()) {
184.89 + sb.append("[bound-in-constructor]");
184.90 + }
184.91 + if (isUnused(info)) {
184.92 + sb.append("[unused]");
184.93 + }
184.94 + if (isUnresolved()) {
184.95 + sb.append("[UNRESOLVED]");
184.96 + }
184.97 + sb.append("[node=");
184.98 + if (node != null) {
184.99 + sb.append(node.getClass().getSimpleName());
184.100 + } else {
184.101 + sb.append("null");
184.102 + }
184.103 + sb.append("]");
184.104 +
184.105 + return sb.toString();
184.106 + }
184.107 +
184.108 + public boolean isUnused(ScopeInfo info) {
184.109 + return (info == null || info.kind == FUNCSCOPE) && (flags & (READ | BOUND | DEF)) == BOUND;
184.110 + }
184.111 +
184.112 + public boolean isParameter() {
184.113 + return (flags & (PARAM | FROM_PARAM)) != 0;
184.114 + }
184.115 +
184.116 + public boolean isUnresolved() {
184.117 + return (flags & (BOUND | FREE)) == 0;
184.118 + }
184.119 +
184.120 + public boolean isImported() {
184.121 + return (flags & IMPORTED) != 0;
184.122 + }
184.123 +
184.124 + public boolean isData() {
184.125 + return (flags & (BOUND | DEF | CLASS | FUNCTION)) == (BOUND);
184.126 + }
184.127 +
184.128 + public boolean isClass() {
184.129 + return (flags & CLASS) != 0;
184.130 + }
184.131 +
184.132 + public boolean isDef() {
184.133 + return (flags & DEF) != 0;
184.134 + }
184.135 +
184.136 + public boolean isFunction() {
184.137 + return (flags & FUNCTION) != 0;
184.138 + }
184.139 +
184.140 + public boolean isBound() {
184.141 + return (flags & BOUND) != 0;
184.142 + }
184.143 +
184.144 + public boolean isMember() {
184.145 + return (flags & MEMBER) != 0;
184.146 + }
184.147 +
184.148 + public boolean isCalled() {
184.149 + return (flags & CALLED) != 0;
184.150 + }
184.151 +
184.152 + public boolean isRead() {
184.153 + return (flags & READ) != 0;
184.154 + }
184.155 +
184.156 + public boolean isGeneratorExp() {
184.157 + return (flags & GENERATOR) != 0;
184.158 + }
184.159 +
184.160 + public boolean isFree() {
184.161 + return (flags & FREE) != 0;
184.162 + }
184.163 +
184.164 + public boolean isPrivate() {
184.165 + return (flags & PRIVATE) != 0;
184.166 + }
184.167 +
184.168 + public boolean isProtected() {
184.169 + return (flags & PROTECTED) != 0;
184.170 + }
184.171 +
184.172 + public boolean isBoundInConstructor() {
184.173 + return (flags & BOUND_IN_CONSTRUCTOR) != 0;
184.174 + }
184.175 +
184.176 + public boolean isAlias() {
184.177 + return (flags & ALIAS) != 0;
184.178 + }
184.179 +
184.180 + public boolean isVariable(boolean mustBeBound) {
184.181 + int mask = mustBeBound ? BOUND : 0;
184.182 + return (flags & (BOUND | CALLED | DEF | IMPORTED | CLASS | FUNCTION | MEMBER | GENERATOR)) == mask;
184.183 + }
184.184 +
184.185 +}
185.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
185.2 +++ b/python.source/src/org/netbeans/modules/python/source/scopes/SymbolTable.java Wed Sep 02 20:31:18 2015 +0200
185.3 @@ -0,0 +1,1247 @@
185.4 +/*
185.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
185.6 + *
185.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
185.8 + *
185.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
185.10 + * Other names may be trademarks of their respective owners.
185.11 + *
185.12 + * The contents of this file are subject to the terms of either the GNU
185.13 + * General Public License Version 2 only ("GPL") or the Common
185.14 + * Development and Distribution License("CDDL") (collectively, the
185.15 + * "License"). You may not use this file except in compliance with the
185.16 + * License. You can obtain a copy of the License at
185.17 + * http://www.netbeans.org/cddl-gplv2.html
185.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
185.19 + * specific language governing permissions and limitations under the
185.20 + * License. When distributing the software, include this License Header
185.21 + * Notice in each file and include the License file at
185.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
185.23 + * particular file as subject to the "Classpath" exception as provided
185.24 + * by Oracle in the GPL Version 2 section of the License file that
185.25 + * accompanied this code. If applicable, add the following below the
185.26 + * License Header, with the fields enclosed by brackets [] replaced by
185.27 + * your own identifying information:
185.28 + * "Portions Copyrighted [year] [name of copyright owner]"
185.29 + *
185.30 + * If you wish your version of this file to be governed by only the CDDL
185.31 + * or only the GPL Version 2, indicate your decision by adding
185.32 + * "[Contributor] elects to include this software in this distribution
185.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
185.34 + * single choice of license, a recipient has the option to distribute
185.35 + * your version of this file under either the CDDL, the GPL Version 2 or
185.36 + * to extend the choice of license to its licensees as provided above.
185.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
185.38 + * Version 2 license, then the option applies only if the new code is
185.39 + * made subject to such option by the copyright holder.
185.40 + *
185.41 + * Contributor(s):
185.42 + *
185.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
185.44 + */
185.45 +package org.netbeans.modules.python.source.scopes;
185.46 +
185.47 +import java.util.ArrayList;
185.48 +import java.util.Collections;
185.49 +import java.util.HashMap;
185.50 +import java.util.HashSet;
185.51 +import java.util.List;
185.52 +import java.util.Map;
185.53 +import java.util.Set;
185.54 +import org.netbeans.modules.csl.api.ElementKind;
185.55 +import org.netbeans.modules.csl.api.OffsetRange;
185.56 +import org.netbeans.modules.csl.api.Severity;
185.57 +import org.netbeans.modules.csl.api.Error;
185.58 +import org.netbeans.modules.csl.spi.DefaultError;
185.59 +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
185.60 +import org.netbeans.modules.python.source.PythonAstUtils;
185.61 +import org.netbeans.modules.python.source.PythonIndex;
185.62 +import org.netbeans.modules.python.source.PythonIndexer;
185.63 +import org.netbeans.modules.python.source.PythonParserResult;
185.64 +import org.netbeans.modules.python.source.PythonUtils;
185.65 +import org.netbeans.modules.python.source.elements.AstElement;
185.66 +import org.netbeans.modules.python.source.elements.Element;
185.67 +import org.netbeans.modules.python.source.elements.IndexedElement;
185.68 +import org.netbeans.modules.python.source.ImportEntry;
185.69 +import org.netbeans.modules.python.source.ImportManager;
185.70 +import org.openide.filesystems.FileObject;
185.71 +import org.openide.filesystems.FileUtil;
185.72 +import org.openide.util.Exceptions;
185.73 +import org.python.antlr.PythonTree;
185.74 +import org.python.antlr.Visitor;
185.75 +import org.python.antlr.ast.Attribute;
185.76 +import org.python.antlr.ast.ClassDef;
185.77 +import org.python.antlr.ast.Expression;
185.78 +import org.python.antlr.ast.FunctionDef;
185.79 +import org.python.antlr.ast.GeneratorExp;
185.80 +import org.python.antlr.ast.Import;
185.81 +import org.python.antlr.ast.ImportFrom;
185.82 +import org.python.antlr.ast.Interactive;
185.83 +import org.python.antlr.ast.Lambda;
185.84 +import org.python.antlr.ast.Name;
185.85 +import org.python.antlr.ast.Str;
185.86 +import org.python.antlr.ast.alias;
185.87 +import org.python.antlr.base.expr;
185.88 +import static org.netbeans.modules.python.source.scopes.ScopeConstants.*;
185.89 +
185.90 +/**
185.91 + * A symbol table tracks a bunch of scopes and can answer questions about defined
185.92 + * symbols.
185.93 + *
185.94 + * Based on Jython's ScopeManager.
185.95 + *
185.96 + * @author Tor Norbye
185.97 + */
185.98 +public class SymbolTable {
185.99 + private final static int YES = 1;
185.100 + private final static int NO = 0;
185.101 + private final static int CIRCULAR = -1;
185.102 + private Map<PythonTree, ScopeInfo> scopes = new HashMap<>();
185.103 + private PythonTree root;
185.104 + private FileObject fileObject;
185.105 + private List<Import> imports = new ArrayList<>();
185.106 + private List<ImportFrom> importsFrom = new ArrayList<>();
185.107 + private List<PythonTree> mainImports = new ArrayList<>();
185.108 + private Set<PythonTree> topLevelImports = new HashSet<>();
185.109 + private List<Error> errors;
185.110 + /** List of symbols registered via __all__ = [ "foo", "bar" ] or __all__.extend() or __all__.append() */
185.111 + private List<Str> publicSymbols;
185.112 + private final static HashMap<String, String> classAttributes = new HashMap<String, String>() {
185.113 + {
185.114 + put("__class__", "__class__");
185.115 + put("__bases__", "__bases__");
185.116 + put("__dict__", "__dict__");
185.117 + put("__doc__", "__doc__");
185.118 + put("__name__", "__bases");
185.119 + }
185.120 + };
185.121 + private HashMap<String, ClassDef> classes = new HashMap<>();
185.122 + // TODO - use WeakHashMap?
185.123 + static Map<String, Set<IndexedElement>> importedElements = new HashMap<>();
185.124 +
185.125 + private HashMap<String, ClassDef> buildLocalClasses() {
185.126 + HashMap<String, ClassDef> localClasses = new HashMap<>();
185.127 + for (PythonTree cur : scopes.keySet()) {
185.128 + if (cur instanceof ClassDef) {
185.129 + ClassDef curClass = (ClassDef)cur;
185.130 + localClasses.put(curClass.getInternalName(), curClass);
185.131 + }
185.132 + }
185.133 + return localClasses;
185.134 + }
185.135 +
185.136 + public SymbolTable(PythonTree root, FileObject fileObject) {
185.137 + this.root = root;
185.138 + this.fileObject = fileObject;
185.139 +
185.140 + if (root != null) {
185.141 + try {
185.142 + ScopesCompiler compiler = new ScopesCompiler(this, scopes, root, imports, importsFrom, mainImports, topLevelImports);
185.143 + compiler.parse();
185.144 + publicSymbols = compiler.getPublicSymbols();
185.145 + classes = buildLocalClasses();
185.146 + if (publicSymbols != null) {
185.147 + // Mark all other symbols private!
185.148 + Set<String> names = new HashSet<>(publicSymbols.size() + 1);
185.149 + names.add("__all__"); // __all__ itself is exported!
185.150 + for (Str str : publicSymbols) {
185.151 + String name = PythonAstUtils.getStrContent(str);
185.152 + if (name != null) {
185.153 + names.add(name);
185.154 + }
185.155 + }
185.156 +
185.157 + ScopeInfo topScope = scopes.get(root);
185.158 + if (topScope != null) {
185.159 + for (Map.Entry<String, SymInfo> entry : topScope.tbl.entrySet()) {
185.160 + String name = entry.getKey();
185.161 + if (!names.contains(name)) {
185.162 + SymInfo sym = entry.getValue();
185.163 + sym.flags |= PRIVATE;
185.164 + if (sym.isDef() && sym.node != null) {
185.165 + ScopeInfo scope = scopes.get(sym.node);
185.166 + scope.hidden = true;
185.167 + }
185.168 + }
185.169 + }
185.170 + }
185.171 +
185.172 + for (Map.Entry<PythonTree, ScopeInfo> entry : scopes.entrySet()) {
185.173 + ScopeInfo scope = entry.getValue();
185.174 + boolean isHidden = false;
185.175 + ScopeInfo curr = scope;
185.176 + while (curr != null) {
185.177 + if (curr.hidden) {
185.178 + isHidden = true;
185.179 + break;
185.180 + }
185.181 + if (curr.nested != null) {
185.182 + curr = curr.nested;
185.183 + } else {
185.184 + curr = curr.up;
185.185 + }
185.186 +
185.187 + }
185.188 + if (isHidden) {
185.189 + scope.hidden = true;
185.190 + }
185.191 + }
185.192 +
185.193 + // Mark all symbols private, unless the scope is a direct descendant
185.194 + // of a public symbol
185.195 + for (ScopeInfo scope : scopes.values()) {
185.196 + if (scope.hidden) {
185.197 + for (SymInfo sym : scope.tbl.values()) {
185.198 + sym.flags |= PRIVATE;
185.199 + }
185.200 + }
185.201 + }
185.202 + }
185.203 + } catch (Exception ex) {
185.204 + Exceptions.printStackTrace(ex);
185.205 + }
185.206 + }
185.207 + }
185.208 +
185.209 + public boolean isPrivate(PythonTree node, String name) {
185.210 + ScopeInfo scope = scopes.get(node);
185.211 + if (scope == null) {
185.212 + scope = scopes.get(root);
185.213 + }
185.214 + if (scope != null) {
185.215 + if (scope.up != null) {
185.216 + if (scope.hidden) {
185.217 + return true;
185.218 + }
185.219 + // Look in parent's scope table
185.220 + if (scope.nested != null) {
185.221 + scope = scope.nested;
185.222 + } else {
185.223 + scope = scope.up;
185.224 + }
185.225 + if (scope != null) {
185.226 + SymInfo sym = scope.tbl.get(name);
185.227 + if (sym != null) {
185.228 + return sym.isPrivate();
185.229 + }
185.230 + }
185.231 + } else {
185.232 + SymInfo sym = scope.tbl.get(name);
185.233 + if (sym != null) {
185.234 + return sym.isPrivate();
185.235 + }
185.236 + }
185.237 + }
185.238 +
185.239 + return false;
185.240 + }
185.241 +
185.242 + public SymInfo findDeclaration(PythonTree scope, String name, boolean allowFree) {
185.243 + ScopeInfo scopeInfo = getScopeInfo(scope);
185.244 + if (scopeInfo != null) {
185.245 + SymInfo sym = scopeInfo.tbl.get(name);
185.246 + SymInfo orig = sym;
185.247 + while (sym != null && sym.isFree()) {
185.248 + scopeInfo = scopeInfo.up;
185.249 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
185.250 + scopeInfo = scopeInfo.up;
185.251 + }
185.252 + sym = scopeInfo.tbl.get(name);
185.253 + }
185.254 +
185.255 + if (allowFree && sym == null && orig != null) {
185.256 + // Free variable -- might have to resolve it
185.257 + return orig;
185.258 + }
185.259 +
185.260 + // Look for attributes too
185.261 + if (sym == null) {
185.262 + sym = scopeInfo.attributes.get(name);
185.263 + orig = sym;
185.264 + while (sym != null && sym.isFree()) {
185.265 + scopeInfo = scopeInfo.up;
185.266 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
185.267 + scopeInfo = scopeInfo.up;
185.268 + }
185.269 + sym = scopeInfo.tbl.get(name);
185.270 + }
185.271 +
185.272 + if (allowFree && sym == null && orig != null) {
185.273 + // Free variable -- might have to resolve it
185.274 + return orig;
185.275 + }
185.276 + }
185.277 +
185.278 + return sym;
185.279 + }
185.280 +
185.281 + return null;
185.282 + }
185.283 +
185.284 + public ScopeInfo getScopeInfo(PythonTree node) {
185.285 + return scopes.get(node);
185.286 + }
185.287 +
185.288 + public List<Error> getErrors() {
185.289 + return errors != null ? errors : Collections.<Error>emptyList();
185.290 + }
185.291 +
185.292 + public SymInfo findBySignature(ElementKind kind, String signature) {
185.293 + PythonTree scope = root;
185.294 + String name = signature;
185.295 + int dot = signature.lastIndexOf('.');
185.296 + if (dot != -1) {
185.297 + String clz = signature.substring(0, dot);
185.298 + name = signature.substring(dot + 1);
185.299 + SymInfo sym = findDeclaration(root, clz, true);
185.300 + if (sym != null && sym.node != null) {
185.301 + scope = sym.node;
185.302 + }
185.303 + }
185.304 + SymInfo sym = findDeclaration(scope, name, true);
185.305 +
185.306 + return sym;
185.307 + }
185.308 +
185.309 + private List<String> getModulesToStarImport() {
185.310 + List<String> modules = new ArrayList<>();
185.311 +
185.312 + for (ImportFrom from : importsFrom) {
185.313 + List<alias> names = from.getInternalNames();
185.314 + if (names != null) {
185.315 + for (alias at : names) {
185.316 + if ("*".equals(at.getInternalName())) { // NOI18N
185.317 + modules.add(from.getInternalModule());
185.318 + }
185.319 + }
185.320 + }
185.321 + }
185.322 +
185.323 + modules.addAll(PythonIndex.BUILTIN_MODULES);
185.324 +
185.325 + return modules;
185.326 + }
185.327 +
185.328 + private void addSymbolsFromModule(PythonParserResult info, String module, String prefix, QuerySupport.Kind kind, Set<? super IndexedElement> result) {
185.329 + if (PythonIndex.isBuiltinModule(module)) {
185.330 + Set<IndexedElement> all = getAllSymbolsFromModule(info, module);
185.331 + for (IndexedElement e : all) {
185.332 + if (kind == QuerySupport.Kind.PREFIX) {
185.333 + if (e.getName().startsWith(prefix)) {
185.334 + result.add(e);
185.335 + }
185.336 + } else if (kind == QuerySupport.Kind.EXACT) {
185.337 + if (prefix.equals(e.getName())) {
185.338 + result.add(e);
185.339 + }
185.340 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
185.341 + if (e.getName().regionMatches(true, 0, prefix, 0, prefix.length())) {
185.342 + result.add(e);
185.343 + }
185.344 + }
185.345 + }
185.346 + } else {
185.347 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
185.348 + Set<IndexedElement> elements = index.getImportedElements(prefix, kind, Collections.singleton(module), null);
185.349 + for (IndexedElement e : elements) {
185.350 + result.add(e);
185.351 + }
185.352 + }
185.353 + }
185.354 +
185.355 + private Set<IndexedElement> getAllSymbolsFromModule(PythonParserResult info, String module) {
185.356 + Set<IndexedElement> elements = importedElements.get(module);
185.357 + if (elements == null) {
185.358 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
185.359 + Set<String> systemHolder = new HashSet<>(3);
185.360 + elements = index.getImportedElements("", QuerySupport.Kind.PREFIX, Collections.singleton(module), systemHolder);
185.361 + // Cache system modules - don't cache local modules
185.362 + if (!systemHolder.isEmpty()) {
185.363 + importedElements.put(module, elements);
185.364 + }
185.365 + }
185.366 +
185.367 + return elements;
185.368 + }
185.369 +
185.370 + public Set<Element> getDefinedElements(PythonParserResult info, PythonTree scope, String prefix, QuerySupport.Kind kind) {
185.371 + Set<Element> elements = new HashSet<>(300);
185.372 + ScopeInfo scopeInfo = scopes.get(scope);
185.373 + String module = PythonUtils.getModuleName(fileObject);
185.374 + String url = fileObject.toURL().toExternalForm();
185.375 +
185.376 + // Get builtin symbols
185.377 + for (String mod : getModulesToStarImport()) {
185.378 + addSymbolsFromModule(info, mod, prefix, kind, elements);
185.379 + }
185.380 +
185.381 + // I can't just search the scope table for all variables in scope because this
185.382 + // will only include the local -bound- variables and the -used- free variables.
185.383 + // I need to find potential free variables as well. This means I should walk up
185.384 + // the scope chain and compute all eligible names. By keep track of the ones I've
185.385 + // already added I avoid adding references to variables I have re-bound in closer
185.386 + // scopes.
185.387 +
185.388 + Set<String> added = new HashSet<>();
185.389 +
185.390 + while (scopeInfo != null) {
185.391 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
185.392 + String name = entry.getKey();
185.393 + if (added.contains(name)) {
185.394 + // Something in narrower scope already processed this one
185.395 + continue;
185.396 + }
185.397 + if (kind == QuerySupport.Kind.EXACT) {
185.398 + if (!(name.equals(prefix))) {
185.399 + continue;
185.400 + }
185.401 + } else if (kind == QuerySupport.Kind.PREFIX) {
185.402 + if (!name.startsWith(prefix)) {
185.403 + continue;
185.404 + }
185.405 + } else if (kind == QuerySupport.Kind.CASE_INSENSITIVE_PREFIX) {
185.406 + if (!name.regionMatches(true, 0, prefix, 0, prefix.length())) {
185.407 + continue;
185.408 + }
185.409 + }
185.410 + SymInfo sym = entry.getValue();
185.411 +
185.412 + ScopeInfo curr = scopeInfo;
185.413 + while (sym != null && sym.isFree()) {
185.414 + curr = curr.up;
185.415 + while (curr != null && curr.kind == CLASSSCOPE) {
185.416 + curr = curr.up;
185.417 + }
185.418 + if (curr == null) {
185.419 + sym = null;
185.420 + break;
185.421 + }
185.422 + sym = scopeInfo.tbl.get(name);
185.423 + }
185.424 + if (sym == null) {
185.425 + continue;
185.426 + }
185.427 + if (sym.isUnresolved()) {
185.428 + // Don't add completion items for stuff we're not sure about
185.429 + continue;
185.430 + }
185.431 +
185.432 + PythonTree node = sym.node;
185.433 + if (node == null) {
185.434 + continue;
185.435 + }
185.436 +
185.437 +
185.438 + if (sym.isImported()) {
185.439 + Element element = new AstElement(this, node, name, Character.isUpperCase(name.charAt(0)) ? ElementKind.CLASS : ElementKind.MODULE);
185.440 + elements.add(element);
185.441 + } else if (sym.isDef()) {
185.442 + String signature;
185.443 + if (sym.isClass() && node instanceof ClassDef) {
185.444 + signature = PythonIndexer.computeClassSig((ClassDef)node, sym);
185.445 + } else if (sym.isFunction() && node instanceof FunctionDef) {
185.446 + assert sym.isFunction() && node instanceof FunctionDef : name + ";" + sym + " in " + module;
185.447 + signature = PythonIndexer.computeFunctionSig(name, (FunctionDef)node, sym);
185.448 + } else {
185.449 + // Probably a generator expression
185.450 + continue;
185.451 + }
185.452 + //Element element = AstElement.create(null, node);
185.453 + IndexedElement element = IndexedElement.create(signature, module, url, null);
185.454 + element.setSmart(true);
185.455 + elements.add(element);
185.456 + } else {
185.457 + // TODO - class attributes?
185.458 + Element element = new AstElement(this, node, name, ElementKind.VARIABLE);
185.459 + elements.add(element);
185.460 + }
185.461 +
185.462 + added.add(name);
185.463 + }
185.464 +
185.465 + scopeInfo = scopeInfo.up;
185.466 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
185.467 + scopeInfo = scopeInfo.up;
185.468 + }
185.469 + }
185.470 +
185.471 + return elements;
185.472 + }
185.473 +
185.474 + // Return all node references to the given name
185.475 + // This will include imports, calls, definitions, etc.
185.476 + public List<PythonTree> getOccurrences(PythonTree scope, String name, boolean abortOnFree) {
185.477 + ScopeInfo scopeInfo = scopes.get(scope);
185.478 + if (scopeInfo != null) {
185.479 + SymInfo sym = scopeInfo.tbl.get(name);
185.480 + while (sym != null && sym.isFree()) {
185.481 + if (abortOnFree) {
185.482 + return null;
185.483 + }
185.484 + scopeInfo = scopeInfo.up;
185.485 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
185.486 + scopeInfo = scopeInfo.up;
185.487 + }
185.488 + sym = scopeInfo.tbl.get(name);
185.489 + }
185.490 +
185.491 + if (sym != null) {
185.492 + NameNodeFinder finder = new NameNodeFinder(name, scopeInfo.scope_node);
185.493 + finder.run();
185.494 + return finder.getNodes();
185.495 + }
185.496 + }
185.497 +
185.498 + return Collections.emptyList();
185.499 + }
185.500 +
185.501 + /** Return a list of the variables visible from a given scope */
185.502 + public Set<String> getVarNames(PythonTree scope, boolean mustBeBound) {
185.503 + ScopeInfo scopeInfo = scopes.get(scope);
185.504 + Set<String> names = new HashSet<>();
185.505 + while (scopeInfo != null) {
185.506 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
185.507 + String name = entry.getKey();
185.508 + SymInfo sym = entry.getValue();
185.509 + if (sym.isVariable(mustBeBound)) {
185.510 + names.add(name);
185.511 + }
185.512 + }
185.513 + scopeInfo = scopeInfo.up;
185.514 + while (scopeInfo != null && scopeInfo.kind == CLASSSCOPE) {
185.515 + scopeInfo = scopeInfo.up;
185.516 + }
185.517 + }
185.518 +
185.519 + return names;
185.520 + }
185.521 +
185.522 + public List<ImportEntry> getUnusedImports() {
185.523 + List<ImportEntry> unused = new ArrayList<>();
185.524 + ScopeInfo scopeInfo = scopes.get(root);
185.525 + for (Map.Entry<String, SymInfo> entry : scopeInfo.tbl.entrySet()) {
185.526 + SymInfo sym = entry.getValue();
185.527 + if (sym.isImported() && !sym.isRead()) {
185.528 + String name = entry.getKey();
185.529 + if (name.equals("*")) { // NOI18N
185.530 + // Not detecting usages of wildcard imports yet...
185.531 + continue;
185.532 + }
185.533 + PythonTree node = sym.node;
185.534 + if (node instanceof Import) {
185.535 + Import imp = (Import)node;
185.536 + int ordinal = 0;
185.537 + String module = null;
185.538 + String asName = null;
185.539 + List<alias> names = imp.getInternalNames();
185.540 + if (names != null) {
185.541 + for (alias at : names) {
185.542 + if (name.equals(at.getInternalAsname())) {
185.543 + module = at.getInternalName();
185.544 + asName = at.getInternalAsname();
185.545 + break;
185.546 + } else if (name.equals(at.getInternalName())) {
185.547 + module = at.getInternalName();
185.548 + break;
185.549 + }
185.550 + }
185.551 + if (module == null) {
185.552 + // For imports with dotted names, like wsgiref.handlers,
185.553 + // the symbol table entry is just "wsgiref", yet I have to match
185.554 + // the symbols, so try again more carefully
185.555 + for (alias at : names) {
185.556 + if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
185.557 + at.getInternalAsname().charAt(name.length()) == '.') {
185.558 + module = at.getInternalName();
185.559 + asName = at.getInternalAsname();
185.560 + break;
185.561 + } else if (at.getInternalName().startsWith(name) &&
185.562 + at.getInternalName().charAt(name.length()) == '.') {
185.563 + module = at.getInternalName();
185.564 + break;
185.565 + }
185.566 + }
185.567 + }
185.568 + }
185.569 + unused.add(new ImportEntry(module, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
185.570 + } else if (node instanceof ImportFrom) {
185.571 + ImportFrom imp = (ImportFrom)node;
185.572 + if (ImportManager.isFutureImport(imp)) {
185.573 + continue;
185.574 + }
185.575 + String module = imp.getInternalModule();
185.576 + String origName = null;
185.577 + String asName = null;
185.578 + int ordinal = 0;
185.579 + List<alias> names = imp.getInternalNames();
185.580 + if (names != null) {
185.581 + for (alias at : names) {
185.582 + if (name.equals(at.getInternalAsname())) {
185.583 + origName = at.getInternalName();
185.584 + asName = at.getInternalAsname();
185.585 + break;
185.586 + } else if (name.equals(at.getInternalName())) {
185.587 + origName = at.getInternalName();
185.588 + break;
185.589 + }
185.590 + }
185.591 + if (origName == null) {
185.592 + // For imports with dotted names, like wsgiref.handlers,
185.593 + // the symbol table entry is just "wsgiref", yet I have to match
185.594 + // the symbols, so try again more carefully
185.595 + for (alias at : names) {
185.596 + if (at.getInternalAsname() != null && at.getInternalAsname().startsWith(name) &&
185.597 + at.getInternalAsname().charAt(name.length()) == '.') {
185.598 + origName = at.getInternalName();
185.599 + asName = at.getInternalAsname();
185.600 + break;
185.601 + } else if (at.getInternalName().startsWith(name) &&
185.602 + at.getInternalName().charAt(name.length()) == '.') {
185.603 + origName = at.getInternalName();
185.604 + break;
185.605 + }
185.606 + }
185.607 + }
185.608 + }
185.609 + unused.add(new ImportEntry(module, origName, asName, true, imp, imp.getCharStartIndex() + (ordinal++)));
185.610 + }
185.611 + }
185.612 + }
185.613 +
185.614 + return unused;
185.615 + }
185.616 +
185.617 + private class NameNodeFinder extends Visitor {
185.618 + private List<PythonTree> nodes = new ArrayList<>();
185.619 + private PythonTree startScope;
185.620 + private String name;
185.621 +
185.622 + public NameNodeFinder(String name, PythonTree startScope) {
185.623 + this.name = name;
185.624 + this.startScope = startScope;
185.625 + }
185.626 +
185.627 + public void run() {
185.628 + try {
185.629 + visit(startScope);
185.630 + } catch (Exception ex) {
185.631 + Exceptions.printStackTrace(ex);
185.632 + }
185.633 + }
185.634 +
185.635 + @Override
185.636 + public Object visitImport(Import imp) throws Exception {
185.637 + List<alias> names = imp.getInternalNames();
185.638 + if (names != null && names.size() > 0) {
185.639 + boolean found = false;
185.640 + for (alias at : names) {
185.641 + String asName = at.getInternalAsname();
185.642 + if (asName != null) {
185.643 + if (name.equals(asName)) {
185.644 + found = true;
185.645 + break;
185.646 + }
185.647 + } else if (name.equals(at.getInternalName())) {
185.648 + found = true;
185.649 + break;
185.650 + }
185.651 + }
185.652 + if (found) {
185.653 + nodes.add(imp);
185.654 + }
185.655 + }
185.656 + return super.visitImport(imp);
185.657 + }
185.658 +
185.659 + @Override
185.660 + public Object visitImportFrom(ImportFrom imp) throws Exception {
185.661 + List<alias> names = imp.getInternalNames();
185.662 + if (names != null && names.size() > 0) {
185.663 + boolean found = false;
185.664 + for (alias at : names) {
185.665 + String asName = at.getInternalAsname();
185.666 + if (asName != null) {
185.667 + if (name.equals(asName)) {
185.668 + found = true;
185.669 + break;
185.670 + }
185.671 + } else if (name.equals(at.getInternalName())) {
185.672 + found = true;
185.673 + break;
185.674 + }
185.675 + }
185.676 + if (found) {
185.677 + nodes.add(imp);
185.678 + }
185.679 + }
185.680 +
185.681 + return super.visitImportFrom(imp);
185.682 + }
185.683 +
185.684 + @Override
185.685 + public Object visitName(Name node) throws Exception {
185.686 + if (node.getInternalId().equals(name)) {
185.687 + nodes.add(node);
185.688 + }
185.689 + return super.visitName(node);
185.690 + }
185.691 +
185.692 + @Override
185.693 + public Object visitFunctionDef(FunctionDef node) throws Exception {
185.694 + if (name.equals(node.getInternalName())) {
185.695 + nodes.add(node);
185.696 + }
185.697 +
185.698 + if (isIncludedScope(node)) {
185.699 + return super.visitFunctionDef(node);
185.700 + } else {
185.701 + return null;
185.702 + }
185.703 + }
185.704 +
185.705 + @Override
185.706 + public Object visitClassDef(ClassDef node) throws Exception {
185.707 + if (name.equals(node.getInternalName())) {
185.708 + nodes.add(node);
185.709 + }
185.710 +
185.711 + if (isIncludedScope(node)) {
185.712 + return super.visitClassDef(node);
185.713 + } else {
185.714 + return null;
185.715 + }
185.716 + }
185.717 +
185.718 + @Override
185.719 + public Object visitExpression(Expression node) throws Exception {
185.720 + if (isIncludedScope(node)) {
185.721 + return super.visitExpression(node);
185.722 + } else {
185.723 + return null;
185.724 + }
185.725 + }
185.726 +
185.727 + @Override
185.728 + public Object visitInteractive(Interactive node) throws Exception {
185.729 + if (isIncludedScope(node)) {
185.730 + return super.visitInteractive(node);
185.731 + } else {
185.732 + return null;
185.733 + }
185.734 + }
185.735 +
185.736 + @Override
185.737 + public Object visitLambda(Lambda node) throws Exception {
185.738 + if (isIncludedScope(node)) {
185.739 + return super.visitLambda(node);
185.740 + } else {
185.741 + return null;
185.742 + }
185.743 + }
185.744 +
185.745 + @Override
185.746 + public Object visitGeneratorExp(GeneratorExp node) throws Exception {
185.747 + if (isIncludedScope(node)) {
185.748 + return super.visitGeneratorExp(node);
185.749 + } else {
185.750 + return null;
185.751 + }
185.752 + }
185.753 +
185.754 + private boolean isIncludedScope(PythonTree node) {
185.755 + if (node == startScope) {
185.756 + return true;
185.757 + }
185.758 +
185.759 + ScopeInfo info = scopes.get(node);
185.760 + if (info == null) {
185.761 + return false;
185.762 + }
185.763 +
185.764 + SymInfo sym = info.tbl.get(name);
185.765 + // Skip scopes that redefine the variable
185.766 + if (sym != null && sym.isBound()) {
185.767 + return false;
185.768 + }
185.769 +
185.770 + return true;
185.771 + }
185.772 +
185.773 + public List<PythonTree> getNodes() {
185.774 + return nodes;
185.775 + }
185.776 + }
185.777 +
185.778 + public Map<String, SymInfo> getUnresolvedNames(PythonParserResult info) {
185.779 + Map<String, SymInfo> unresolved = new HashMap<>();
185.780 + Set<String> builtin = getBuiltin(info);
185.781 +
185.782 + for (ScopeInfo scopeInfo : scopes.values()) {
185.783 + Map<String, SymInfo> tbl = scopeInfo.tbl;
185.784 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
185.785 + SymInfo symInfo = entry.getValue();
185.786 + boolean isUnresolved = symInfo.isUnresolved();
185.787 + if (!isUnresolved && symInfo.isFree()) {
185.788 + // Peek up scope stack
185.789 + String name = entry.getKey();
185.790 + SymInfo sym = symInfo;
185.791 + ScopeInfo scope = scopeInfo;
185.792 + while (sym != null && sym.isFree()) {
185.793 + scope = scope.up;
185.794 + while (scope != null && scope.kind == CLASSSCOPE) {
185.795 + scope = scope.up;
185.796 + }
185.797 + sym = scope.tbl.get(name);
185.798 + }
185.799 + if (sym == null) {
185.800 + isUnresolved = true;
185.801 + } else {
185.802 + isUnresolved = sym.isUnresolved();
185.803 + }
185.804 + }
185.805 + if (isUnresolved) {
185.806 + String key = entry.getKey();
185.807 + if (!builtin.contains(key)) {
185.808 + unresolved.put(key, symInfo);
185.809 + }
185.810 + }
185.811 + }
185.812 + }
185.813 +
185.814 + return unresolved;
185.815 + }
185.816 +
185.817 + public List<Attribute> getNotInInitAttributes(PythonParserResult info) {
185.818 + List<Attribute> notInInitAttribs = new ArrayList<>();
185.819 + for (ScopeInfo scopeInfo : scopes.values()) {
185.820 + if (scopeInfo.scope_node instanceof ClassDef) {
185.821 + if (scopeInfo.attributes != null) {
185.822 + for (Map.Entry<String, SymInfo> entry : scopeInfo.attributes.entrySet()) {
185.823 + SymInfo symInfo = entry.getValue();
185.824 + if (!symInfo.isBoundInConstructor()) {
185.825 + notInInitAttribs.add((Attribute)symInfo.node);
185.826 + }
185.827 + }
185.828 + }
185.829 + }
185.830 + }
185.831 + return notInInitAttribs;
185.832 + }
185.833 +
185.834 + private ScopeInfo getClassScope(String className) {
185.835 + for (ScopeInfo scopeInfo : scopes.values()) {
185.836 + if (scopeInfo.scope_node instanceof ClassDef) {
185.837 + ClassDef curClass = (ClassDef)scopeInfo.scope_node;
185.838 + if (curClass.getInternalName().equals(className)) {
185.839 + return scopeInfo;
185.840 + }
185.841 + }
185.842 + }
185.843 + return null;
185.844 + }
185.845 +
185.846 + private int belongsToParents(ClassDef cls, String name, HashMap<String, String> cycling) {
185.847 + List<expr> bases = cls.getInternalBases();
185.848 + if (bases == null || bases.size() == 0) {
185.849 + return NO; // no parents
185.850 + }
185.851 + for (expr base : bases) {
185.852 + String className = null;
185.853 + if (base instanceof Name) {
185.854 + className = ((Name)base).getInternalId();
185.855 + } else {
185.856 + // should be Attribute here( module.className form )
185.857 + // which imply imported from external scope
185.858 + // So we give up on scope returning optimistaically True
185.859 + return YES;
185.860 + }
185.861 + assert (className != null);
185.862 + if (cycling.get(className) != null) {
185.863 + cycling.clear();
185.864 + // put parent child conficting back in cycling
185.865 + cycling.put(className, cls.getInternalName());
185.866 + return CIRCULAR;
185.867 + }
185.868 + cycling.put(className, className);
185.869 + ScopeInfo localClassScope = getClassScope(className);
185.870 + if (localClassScope == null) {
185.871 + // return true (success) when at least one parent is outside module scope
185.872 + // just to notify caller to be optimistic and assume that
185.873 + // name is resolved by imported classes inheritance
185.874 + // scanning imported classed from here is discouraged for
185.875 + // performances reasons
185.876 + return YES;
185.877 + } else {
185.878 + if ((name != null) &&
185.879 + (localClassScope.attributes.get(name) != null)) {
185.880 + return YES;
185.881 + }
185.882 + // try recurse parentage to resolve attribute
185.883 + ClassDef parentClass = (ClassDef)localClassScope.scope_node;
185.884 + int recResult = belongsToParents(parentClass, name, cycling);
185.885 + if (recResult != NO) // stop on FOUND(YES) or CIRCULAR error
185.886 + {
185.887 + return recResult;
185.888 + }
185.889 + }
185.890 + }
185.891 + return NO;
185.892 + }
185.893 +
185.894 + private boolean isImported(String moduleName) {
185.895 + for (Import imported : imports) {
185.896 + List<alias> names = imported.getInternalNames();
185.897 + if (names != null) {
185.898 + for (alias cur : names) {
185.899 + String name = cur.getInternalName();
185.900 + String asName = cur.getInternalAsname();
185.901 + if (((name != null) && (name.equals(moduleName))) ||
185.902 + ((asName != null) && (asName.equals(moduleName)))) {
185.903 + return true;
185.904 + }
185.905 + }
185.906 + }
185.907 + }
185.908 + return false;
185.909 + }
185.910 +
185.911 + private boolean isImportedFrom(String className) {
185.912 + for (ImportFrom importedFrom : importsFrom) {
185.913 + List<alias> names = importedFrom.getInternalNames();
185.914 + if (names != null) {
185.915 + for (alias cur : names) {
185.916 + String name = cur.getInternalName();
185.917 + String asName = cur.getInternalAsname();
185.918 + if (((name != null) && (name.equals(className))) ||
185.919 + ((asName != null) && (asName.equals(className)))) {
185.920 + return true;
185.921 + }
185.922 + }
185.923 + }
185.924 + }
185.925 + return false;
185.926 + }
185.927 +
185.928 + public List<PythonTree> getUnresolvedParents(PythonParserResult info) {
185.929 + // deal with unresolved parents in inherit trees
185.930 + List<PythonTree> unresolvedParents = new ArrayList<>();
185.931 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
185.932 +
185.933 + for (String cur : classes.keySet()) {
185.934 + ClassDef cls = classes.get(cur);
185.935 + List<expr> bases = cls.getInternalBases();
185.936 + if (bases == null || bases.size() > 0) {
185.937 + // has parents
185.938 + for (expr base : bases) {
185.939 + if (base instanceof Name) {
185.940 + String className = ((Name)base).getInternalId();
185.941 + Set<String> builtin = getBuiltin(info);
185.942 + if ((!classes.containsKey(className)) &&
185.943 + (!builtin.contains(className))) {
185.944 + // check in from imports
185.945 + if (!isImportedFrom(className)) {
185.946 + unresolvedParents.add(base);
185.947 + }
185.948 + }
185.949 + } else {
185.950 + // should be Attribute here( module.className form )
185.951 + // which imply imported from external scope
185.952 + Attribute attr = (Attribute)base;
185.953 + String clsName = attr.getInternalAttr();
185.954 + if (attr.getInternalValue() instanceof Name) {
185.955 + String moduleName = ((Name)(attr.getInternalValue())).getInternalId();
185.956 + // check that import is resolved first
185.957 + if (!isImported(moduleName)) {
185.958 + unresolvedParents.add(base);
185.959 + } else {
185.960 + Set<IndexedElement> found = index.getImportedElements(clsName, QuerySupport.Kind.EXACT, Collections.<String>singleton(moduleName), null);
185.961 + if (found.size() == 0) {
185.962 + unresolvedParents.add(base);
185.963 + }
185.964 + }
185.965 + } else {
185.966 + unresolvedParents.add(base);
185.967 + }
185.968 + }
185.969 + }
185.970 + }
185.971 + }
185.972 + return unresolvedParents;
185.973 + }
185.974 +
185.975 + public HashMap<ClassDef, String> getClassesCyclingRedundancies(PythonParserResult info) {
185.976 + HashMap<ClassDef, String> cyclingRedundancies = new HashMap<>();
185.977 + for (String cur : classes.keySet()) {
185.978 + HashMap<String, String> returned = new HashMap<>();
185.979 + ClassDef curClass = classes.get(cur);
185.980 + if (!cyclingRedundancies.containsKey(curClass)) {
185.981 + if (belongsToParents(curClass, null, returned) == CIRCULAR) {
185.982 + // store hashMap returned
185.983 + Map.Entry<String, String> cycling = returned.entrySet().iterator().next();
185.984 + cyclingRedundancies.put(curClass, cycling.getKey());
185.985 + }
185.986 + }
185.987 + }
185.988 + return cyclingRedundancies;
185.989 + }
185.990 +
185.991 + public List<PythonTree> getUnresolvedAttributes(PythonParserResult info) {
185.992 + List<PythonTree> unresolvedNodes = new ArrayList<>();
185.993 + for (ScopeInfo scopeInfo : scopes.values()) {
185.994 + Set<String> unresolved = new HashSet<>();
185.995 + Map<String, SymInfo> tbl = scopeInfo.tbl;
185.996 + // unresolved attributes in local classes
185.997 + Map<String, SymInfo> attribs = scopeInfo.attributes;
185.998 + for (Map.Entry<String, SymInfo> curAttr : attribs.entrySet()) {
185.999 + SymInfo symInfo = curAttr.getValue();
185.1000 + if (symInfo.isRead()) {
185.1001 + // check for builtin attribs first
185.1002 + if (classAttributes.get(curAttr.getKey()) == null) {
185.1003 + // not a builtin attribute
185.1004 + ScopeInfo parentScope = scopeInfo.getClassScope();
185.1005 + if (parentScope != null) {
185.1006 + // limit scope to Classes for self and inherited
185.1007 + Map<String, SymInfo> parentattribs = parentScope.attributes;
185.1008 + SymInfo classAttr = parentattribs.get(curAttr.getKey());
185.1009 + tbl = parentScope.tbl;
185.1010 + if (classAttr == null) {
185.1011 + // may be also a reference to a method
185.1012 + classAttr = tbl.get(curAttr.getKey());
185.1013 + }
185.1014 + if (classAttr == null) {
185.1015 + // do not bother with method since they are
185.1016 + // managed by completion
185.1017 + ClassDef curClass = (ClassDef)parentScope.scope_node;
185.1018 + if (belongsToParents(curClass, curAttr.getKey(), new HashMap()) == NO) {
185.1019 + if (!symInfo.isCalled()) {
185.1020 + // no corresponding attributes
185.1021 + //PythonTree tree = symInfo.node ;
185.1022 + Attribute attr = (Attribute)symInfo.node;
185.1023 + // Name name = new Name(tree.getToken(),attr.getInternalAttr(),attr.ctx) ;
185.1024 + unresolvedNodes.add(attr);
185.1025 + }
185.1026 + }
185.1027 + }
185.1028 + }
185.1029 + }
185.1030 + }
185.1031 + }
185.1032 + if (unresolved.size() > 0) {
185.1033 + NameFinder finder = new NameFinder(unresolved);
185.1034 + List<Name> nodes = finder.run(scopeInfo.scope_node);
185.1035 + unresolvedNodes.addAll(nodes);
185.1036 + }
185.1037 +
185.1038 + }
185.1039 +
185.1040 + if (unresolvedNodes.size() > 1) {
185.1041 + Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
185.1042 + //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
185.1043 + }
185.1044 +
185.1045 + return unresolvedNodes;
185.1046 + }
185.1047 +
185.1048 + public List<PythonTree> getUnresolved(PythonParserResult info) {
185.1049 + List<PythonTree> unresolvedNodes = new ArrayList<>();
185.1050 + Set<String> builtin = getBuiltin(info);
185.1051 +
185.1052 + for (ScopeInfo scopeInfo : scopes.values()) {
185.1053 + Set<String> unresolved = new HashSet<>();
185.1054 + Map<String, SymInfo> tbl = scopeInfo.tbl;
185.1055 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
185.1056 + SymInfo symInfo = entry.getValue();
185.1057 + boolean isUnresolved = symInfo.isUnresolved();
185.1058 + if (!isUnresolved && symInfo.isFree()) {
185.1059 + // Peek up scope stack
185.1060 + String name = entry.getKey();
185.1061 + SymInfo sym = symInfo;
185.1062 + ScopeInfo scope = scopeInfo;
185.1063 + while (sym != null && sym.isFree()) {
185.1064 + scope = scope.up;
185.1065 + while (scope != null && scope.kind == CLASSSCOPE) {
185.1066 + scope = scope.up;
185.1067 + }
185.1068 + sym = scope.tbl.get(name);
185.1069 + }
185.1070 + if (sym == null) {
185.1071 + isUnresolved = true;
185.1072 + } else {
185.1073 + isUnresolved = sym.isUnresolved();
185.1074 + }
185.1075 + }
185.1076 + if (isUnresolved) {
185.1077 + String key = entry.getKey();
185.1078 + if (!builtin.contains(key)) {
185.1079 + unresolved.add(key);
185.1080 + }
185.1081 + }
185.1082 + }
185.1083 +
185.1084 +
185.1085 + if (unresolved.size() > 0) {
185.1086 + // Check imports and see if it's resolved by existing imports
185.1087 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
185.1088 + // TODO - cache system libraries!
185.1089 + // TODO - make method which doesn't create elements for these guys!
185.1090 +// Set<IndexedElement> elements = index.getImportedElements("", NameKind.PREFIX, PythonIndex.ALL_SCOPE, imports, importsFrom);
185.1091 +// for (IndexedElement e : elements) {
185.1092 +// unresolved.remove(e.getName());
185.1093 +// }
185.1094 + Set<String> wildcarded = index.getImportedFromWildcards(importsFrom);
185.1095 + unresolved.removeAll(wildcarded);
185.1096 +
185.1097 + if (unresolved.size() > 0) {
185.1098 + NameFinder finder = new NameFinder(unresolved);
185.1099 + List<Name> nodes = finder.run(scopeInfo.scope_node);
185.1100 + unresolvedNodes.addAll(nodes);
185.1101 + }
185.1102 + }
185.1103 + }
185.1104 +
185.1105 + if (unresolvedNodes.size() > 1) {
185.1106 + Collections.sort(unresolvedNodes, PythonUtils.ATTRIBUTE_NAME_NODE_COMPARATOR);
185.1107 + //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
185.1108 + }
185.1109 +
185.1110 + return unresolvedNodes;
185.1111 + }
185.1112 +
185.1113 + public List<PythonTree> getUnused(boolean skipSelf, boolean skipParams) { // not used for unused imports, see separate method
185.1114 + List<PythonTree> unusedNodes = new ArrayList<>();
185.1115 +
185.1116 + for (ScopeInfo scopeInfo : scopes.values()) {
185.1117 + if (scopeInfo.kind != FUNCSCOPE) {
185.1118 + continue;
185.1119 + }
185.1120 + Set<String> unused = new HashSet<>();
185.1121 + Map<String, SymInfo> tbl = scopeInfo.tbl;
185.1122 + for (Map.Entry<String, SymInfo> entry : tbl.entrySet()) {
185.1123 + SymInfo symInfo = entry.getValue();
185.1124 + if (symInfo.isUnused(scopeInfo) && (!skipParams || !symInfo.isParameter())) {
185.1125 + String key = entry.getKey();
185.1126 + if (skipSelf && "self".equals(key)) { // NOI18N
185.1127 + continue;
185.1128 + }
185.1129 + unused.add(key);
185.1130 + }
185.1131 + }
185.1132 +
185.1133 + if (unused.size() > 0) {
185.1134 + NameFinder finder = new NameFinder(unused);
185.1135 + List<Name> nodes = finder.run(scopeInfo.scope_node);
185.1136 + unusedNodes.addAll(nodes);
185.1137 + }
185.1138 + }
185.1139 +
185.1140 + if (unusedNodes.size() > 1) {
185.1141 + Collections.sort(unusedNodes, PythonUtils.NAME_NODE_COMPARATOR);
185.1142 + //Collections.sort(unusedNodes, PythonUtils.NODE_POS_COMPARATOR);
185.1143 + }
185.1144 +
185.1145 + return unusedNodes;
185.1146 + }
185.1147 +
185.1148 + private static class NameFinder extends Visitor {
185.1149 + private Set<String> names;
185.1150 + private List<Name> nodes = new ArrayList<>();
185.1151 + private PythonTree acceptDef;
185.1152 +
185.1153 + private NameFinder(Set<String> names) {
185.1154 + this.names = names;
185.1155 + }
185.1156 +
185.1157 + @Override
185.1158 + public Object visitClassDef(ClassDef node) throws Exception {
185.1159 + // Don't look in nested scopes
185.1160 + if (node != acceptDef) {
185.1161 + return null;
185.1162 + }
185.1163 + return super.visitClassDef(node);
185.1164 + }
185.1165 +
185.1166 + @Override
185.1167 + public Object visitFunctionDef(FunctionDef node) throws Exception {
185.1168 + // Don't look in nested scopes
185.1169 + if (node != acceptDef) {
185.1170 + return null;
185.1171 + }
185.1172 + return super.visitFunctionDef(node);
185.1173 + }
185.1174 +
185.1175 + @Override
185.1176 + public Object visitName(Name node) throws Exception {
185.1177 + String name = node.getInternalId();
185.1178 + if (names.contains(name)) {
185.1179 + nodes.add(node);
185.1180 + }
185.1181 +
185.1182 + return super.visitName(node);
185.1183 + }
185.1184 +
185.1185 + public List<Name> run(PythonTree node) {
185.1186 + this.acceptDef = node;
185.1187 + try {
185.1188 + visit(node);
185.1189 + } catch (Exception ex) {
185.1190 + Exceptions.printStackTrace(ex);
185.1191 + }
185.1192 +
185.1193 + return nodes;
185.1194 + }
185.1195 + }
185.1196 + private static Set<String> builtinSymbols;
185.1197 +
185.1198 + private Set<String> getBuiltin(PythonParserResult info) {
185.1199 + if (builtinSymbols == null) {
185.1200 + PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());
185.1201 + builtinSymbols = index.getBuiltinSymbols();
185.1202 + }
185.1203 +
185.1204 + return builtinSymbols;
185.1205 + }
185.1206 +
185.1207 + public void error(String msg, boolean err, PythonTree node) throws Exception {
185.1208 + assert node != null;
185.1209 + // TODO - record and register with the hints manager?
185.1210 + OffsetRange range = PythonAstUtils.getRange(node);
185.1211 +
185.1212 + if (errors == null) {
185.1213 + errors = new ArrayList<>();
185.1214 + }
185.1215 + Error error = new DefaultError(null, msg, null, fileObject, range.getStart(), range.getEnd(), err ? Severity.ERROR : Severity.WARNING);
185.1216 + errors.add(error);
185.1217 + }
185.1218 +
185.1219 + public String getFilename() {
185.1220 + return FileUtil.getFileDisplayName(fileObject);
185.1221 + }
185.1222 +
185.1223 + public Map<PythonTree, ScopeInfo> getScopes() {
185.1224 + return scopes;
185.1225 + }
185.1226 +
185.1227 + public List<Import> getImports() {
185.1228 + return imports;
185.1229 + }
185.1230 +
185.1231 + public List<ImportFrom> getImportsFrom() {
185.1232 + return importsFrom;
185.1233 + }
185.1234 +
185.1235 + public boolean isTopLevel(PythonTree node) {
185.1236 + return topLevelImports.contains(node);
185.1237 + }
185.1238 +
185.1239 + public List<PythonTree> getMainImports() {
185.1240 + return mainImports;
185.1241 + }
185.1242 +
185.1243 + public Set<PythonTree> getTopLevelImports() {
185.1244 + return topLevelImports;
185.1245 + }
185.1246 +
185.1247 + public List<Str> getPublicSymbols() {
185.1248 + return publicSymbols;
185.1249 + }
185.1250 +}
186.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
186.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/Bundle.properties Wed Sep 02 20:31:18 2015 +0200
186.3 @@ -0,0 +1,284 @@
186.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
186.5 +#
186.6 +# Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
186.7 +#
186.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
186.9 +# Other names may be trademarks of their respective owners.
186.10 +#
186.11 +# The contents of this file are subject to the terms of either the GNU
186.12 +# General Public License Version 2 only ("GPL") or the Common
186.13 +# Development and Distribution License("CDDL") (collectively, the
186.14 +# "License"). You may not use this file except in compliance with the
186.15 +# License. You can obtain a copy of the License at
186.16 +# http://www.netbeans.org/cddl-gplv2.html
186.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
186.18 +# specific language governing permissions and limitations under the
186.19 +# License. When distributing the software, include this License Header
186.20 +# Notice in each file and include the License file at
186.21 +# nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
186.22 +# particular file as subject to the "Classpath" exception as provided
186.23 +# by Oracle in the GPL Version 2 section of the License file that
186.24 +# accompanied this code. If applicable, add the following below the
186.25 +# License Header, with the fields enclosed by brackets [] replaced by
186.26 +# your own identifying information:
186.27 +# "Portions Copyrighted [year] [name of copyright owner]"
186.28 +#
186.29 +# Contributor(s):
186.30 +#
186.31 +# The Original Software is NetBeans. The Initial Developer of the Original
186.32 +# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
186.33 +# Microsystems, Inc. All Rights Reserved.
186.34 +#
186.35 +# If you wish your version of this file to be governed by only the CDDL
186.36 +# or only the GPL Version 2, indicate your decision by adding
186.37 +# "[Contributor] elects to include this software in this distribution
186.38 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
186.39 +# single choice of license, a recipient has the option to distribute
186.40 +# your version of this file under either the CDDL, the GPL Version 2 or
186.41 +# to extend the choice of license to its licensees as provided above.
186.42 +# However, if you add GPL Version 2 code and therefore, elected the GPL
186.43 +# Version 2 license, then the option applies only if the new code is
186.44 +# made subject to such option by the copyright holder.
186.45 +
186.46 +# Formating options
186.47 +
186.48 +LBL_TabsAndIndents=Tabs and Indents
186.49 +LBL_CodeGeneration=Code Generation
186.50 +LBL_Alignment=Alignment
186.51 +LBL_Wrapping=Wrapping
186.52 +LBL_BlankLines=Blank Lines
186.53 +LBL_Spaces=Spaces
186.54 +LBL_Imports=Imports
186.55 +
186.56 +LBL_bp_SAME_LINE=Same Line
186.57 +LBL_bp_NEW_LINE=New Line
186.58 +LBL_bp_NEW_LINE_HALF_INDENTED=New Line Half Indented
186.59 +LBL_bp_NEW_LINE_INDENTED= New Line Indented
186.60 +
186.61 +LBL_bg_GENERATE=Generate
186.62 +LBL_bg_LEAVE_ALONE=Leave Alone
186.63 +LBL_bg_ELIMINATE=Eliminate
186.64 +
186.65 +LBL_wrp_WRAP_ALWAYS=Always
186.66 +LBL_wrp_WRAP_IF_LONG=If Long
186.67 +LBL_wrp_WRAP_NEVER=Never
186.68 +
186.69 +LBL_imp_COMMENT_OUT=Comment Out
186.70 +LBL_imp_LEAVE_ALONE=Leave Alone
186.71 +LBL_imp_DELETE=Delete
186.72 +
186.73 +LBL_ExpandTabToSpaces=&Expand Tab to Spaces
186.74 +LBL_TabSize=&Tab Size:
186.75 +LBL_IndentSize=&Indentation Size:
186.76 +LBL_ContinuationIndentSize=&Continuation Indentation Size:
186.77 +LBL_LabelIndent=&Label Indentation\:
186.78 +LBL_AbsoluteLabelIndent=&Absolute Label Indentation
186.79 +LBL_IndentTopLevelClassMemberts=Indent Top Level Class &Members
186.80 +LBL_AddLeadingStarInComment=Add Leading Star In Comment
186.81 +LBL_RightMargin=&Right Margin:
186.82 +
186.83 +LBL_Naming=Naming\:
186.84 +LBL_PreferLongerNames=Prefer Longer Names
186.85 +LBL_Prefix=Prefix
186.86 +LBL_Suffix=Suffix
186.87 +LBL_Field=Field\:
186.88 +LBL_StaticField=Static Field\:
186.89 +LBL_Parameter=Parameter\:
186.90 +LBL_LocalVariable=Local Variable\:
186.91 +LBL_Misc=Misc\:
186.92 +LBL_QualifyFieldAccess=Qualify Field Access
186.93 +LBL_UseIsForBooleanGetters=Use Is For Boolean Getters
186.94 +LBL_AddOverrideAnnotation=Add Override Annotation
186.95 +LBL_FinalMofier=Final Modifier\:
186.96 +LBL_ParametersFinal=Make Generated Parameters Final
186.97 +LBL_LocalVariablesFinal=Make Generated Local variables Final
186.98 +LBL_ImportOredering=Import Ordering\:
186.99 +LBL_ImportUp=Move Up
186.100 +LBL_ImportDown=Move Down
186.101 +LBL_blBeforePackage=Before &Package\:
186.102 +LBL_blAfterPackage=After P&ackage\:
186.103 +LBL_blBeforeImports=Before &Imports\:
186.104 +LBL_blAfterImports=After I&mports\:
186.105 +LBL_blBeforeClass=Before &Class\:
186.106 +LBL_blAfterClass=After C&lass\:
186.107 +LBL_blAfterClassHeader=After Class &Header\:
186.108 +LBL_blBeforeFields=Before &Field\:
186.109 +LBL_blAfterFields=After Fi&eld\:
186.110 +LBL_blBeforeMethods=Before &Method\:
186.111 +LBL_blAfterMethods=After Me&thod\:
186.112 +
186.113 +LBL_BeforeKeywords=Before Keywords
186.114 +LBL_spaceBeforeWhile="while"
186.115 +LBL_spaceBeforeElse="else"
186.116 +LBL_spaceBeforeCatch="catch"
186.117 +LBL_spaceBeforeFinally="finally"
186.118 +
186.119 +LBL_BeforeParentheses=Before Parentheses
186.120 +LBL_spaceBeforeMethodDeclParen=Method Declaration
186.121 +LBL_spaceBeforeMethodCallParen=Method Call
186.122 +LBL_spaceBeforeIfParen="if"
186.123 +LBL_spaceBeforeForParen="for"
186.124 +LBL_spaceBeforeWhileParen="while"
186.125 +LBL_spaceBeforeCatchParen="catch"
186.126 +LBL_spaceBeforeSwitchParen="switch"
186.127 +LBL_spaceBeforeSynchronizedParen="synchronized"
186.128 +LBL_spaceBeforeAnnotationParen=Annotation Parameters
186.129 +
186.130 +LBL_AroundOperators=Around Operators
186.131 +LBL_spaceAroundUnaryOps=Unary Operators
186.132 +LBL_spaceAroundBinaryOps=Binary Operators
186.133 +LBL_spaceAroundTernaryOps=Ternary Operators
186.134 +LBL_spaceAroundAssignOps=Assignment Operators
186.135 +
186.136 +LBL_BeforeLeftBraces=Before Left Braces
186.137 +LBL_spaceBeforeClassDeclLeftBrace=Class Declaration
186.138 +LBL_spaceBeforeMethodDeclLeftBrace=Method Declaration
186.139 +LBL_spaceBeforeIfLeftBrace="if"
186.140 +LBL_spaceBeforeElseLeftBrace="else"
186.141 +LBL_spaceBeforeWhileLeftBrace="while"
186.142 +LBL_spaceBeforeForLeftBrace="for"
186.143 +LBL_spaceBeforeDoLeftBrace="do"
186.144 +LBL_spaceBeforeSwitchLeftBrace="switch"
186.145 +LBL_spaceBeforeTryLeftBrace="try"
186.146 +LBL_spaceBeforeCatchLeftBrace="catch"
186.147 +LBL_spaceBeforeFinallyLeftBrace="finally"
186.148 +LBL_spaceBeforeSynchronizedLeftBrace="synchronized"
186.149 +LBL_spaceBeforeStaticInitLeftBrace=Static Initializer
186.150 +LBL_spaceBeforeArrayInitLeftBrace=Array Initializer
186.151 +
186.152 +LBL_WithinParentheses=Within Parentheses
186.153 +LBL_spaceWithinParens=Parentheses
186.154 +LBL_spaceWithinMethodDeclParens=Method Declaration
186.155 +LBL_spaceWithinMethodCallParens=Method Call
186.156 +LBL_spaceWithinIfParens="if"
186.157 +LBL_spaceWithinForParens="for"
186.158 +LBL_spaceWithinWhileParens="while"
186.159 +LBL_spaceWithinSwitchParens="switch"
186.160 +LBL_spaceWithinCatchParens="catch"
186.161 +LBL_spaceWithinSynchronizedParens="synchronized"
186.162 +LBL_spaceWithinTypeCastParens=Type Cast
186.163 +LBL_spaceWithinAnnotationParens=Annotation
186.164 +LBL_spaceWithinBraces=Braces
186.165 +LBL_spaceWithinArrayInitBrackets=Array Initializer Brackets
186.166 +
186.167 +LBL_Other=Other
186.168 +LBL_spaceBeforeComma=Before Comma
186.169 +LBL_spaceAfterComma=After Comma
186.170 +LBL_spaceBeforeSemi=Before Semicolon
186.171 +LBL_spaceAfterSemi=After Semicolon
186.172 +LBL_spaceBeforeColon=Before Colon
186.173 +LBL_spaceAfterColon=After Colon
186.174 +LBL_spaceAfterTypeCast=After Type Cast
186.175 +LBL_wrp_extendsImplementsKeyword=&Extends/Implements Keyword\:
186.176 +LBL_wrp_extendsImplementsList=E&xtends/Implements List\:
186.177 +LBL_wrp_methodParameters=Method &Parameters\:
186.178 +LBL_wrp_throwsKeyword=&Throws Keyword\:
186.179 +LBL_wrp_throwsList=Th&rows List\:
186.180 +LBL_wrp_methodCallArgs=Method Call &Arguments\:
186.181 +LBL_wrp_annotationArgs=Annotation Arg&uments\:
186.182 +LBL_wrp_chainedMethodCalls=C&hained Method Calls\:
186.183 +LBL_wrp_arrayInit=Array Initiali&zer\:
186.184 +LBL_wrp_for=&For\:
186.185 +LBL_wrp_forStatement=F&or Statement\:
186.186 +LBL_wrp_ifStatement=&If Statement\:
186.187 +LBL_wrp_whileStatement=&While Statement\:
186.188 +LBL_wrp_doWhileStatement=&Do ... While Statement
186.189 +LBL_wrp_assert=&Assert\:
186.190 +LBL_wrp_enumConstants=Enum &Constants\:
186.191 +LBL_wrp_annotations=A&nnotations\:
186.192 +LBL_wrp_binaryOps=&Binary Operators\:
186.193 +LBL_wrp_ternaryOps=Ternar&y Operators\:
186.194 +LBL_wrp_assignOps=Assi&gnment Operators\:
186.195 +
186.196 +LBL_br_bracesPlacement=Braces Placement
186.197 +LBL_br_bracesGeneration=Braces Generation
186.198 +LBL_al_newLines=New Lines
186.199 +LBL_al_multilineAlignment=Multiline Alignment
186.200 +LBL_nl_Else="&else"
186.201 +LBL_nl_While="w&hile"
186.202 +LBL_nl_Catch="c&atch"
186.203 +LBL_nl_Finally="finall&y"
186.204 +LBL_nl_Modifiers=after modifie&rs
186.205 +LBL_am_MethodParams=Method &Parameters
186.206 +LBL_am_CallArgs=Method Call Arg&uments
186.207 +LBL_am_AnnotationArgs=&Annotation Arguments
186.208 +LBL_an_Implements=I&mplements List
186.209 +LBL_am_Throws=&Throws List
186.210 +LBL_am_Paren=Parenthesize&d
186.211 +LBL_am_BinaryOp=&Binary Operators
186.212 +LBL_am_TernaryOp=Ter&nary Operators
186.213 +LBL_am_Assign=Assi&gnment
186.214 +LBL_am_For=&For
186.215 +LBL_am_ArrayInit=Array Initiali&zer
186.216 +
186.217 +LBL_IndentCasesFromSwitch=Indent Case Statements In &Switch
186.218 +
186.219 +# Following entries (marked) as samples are used as examples in the formating
186.220 +# options. It is highly discourage to localize them unless absolutely necessary.
186.221 +
186.222 +SAMPLE_Default=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC
186.223 +SAMPLE_TabsIndents=public class ClassA extends Object implements InterfaceA, InterfaceB, InterfaceC {
186.224 +SAMPLE_AlignBraces=@Anno(paramA="a Value", paramB="bValue")\n
186.225 +SAMPLE_Wrapping=@Anno(paramA="a Value", paramB="bValue")
186.226 +SAMPLE_BlankLines=package org.netbeans.samples;
186.227 +
186.228 +SAMPLE_Imports=\
186.229 +# Copyright 2008\n\
186.230 +"""My Module"""\n\
186.231 +\n\
186.232 +import sys\n\
186.233 +import wsgiref.handlers\n\
186.234 +from google.appengine.ext.webapp.util import run_wsgi_app\n\
186.235 +from google.appengine.ext import webapp\n\
186.236 +from google.appengine.ext import db\n\
186.237 +import os\n\
186.238 +\n\
186.239 +\n\
186.240 +from google.appengine.api import users\n\
186.241 +import google.appengine.api.test\n\
186.242 +from google.appengine.api import users\n\
186.243 +\n\
186.244 +from google.appengine.api import users\n\
186.245 +from google.appengine.api import users\n\
186.246 +import string\n\
186.247 +from google.appengine.ext.webapp import template as FooBar\n\
186.248 +from google.appengine.ext.webapp.util import login_required\n\
186.249 +import random\n\
186.250 +import datetime\n
186.251 +
186.252 +#\n\
186.253 +#new_str = swapcase("foo")
186.254 +
186.255 +
186.256 +# Newlines on the following line since space prefixes are ignored by the .properties loader
186.257 +SAMPLE_Spaces=\
186.258 +def func( arg1 ,arg2 ,\
186.259 +\n arg3 = 3, arg = 4):\
186.260 +\n\
186.261 +\n if pos!=-1 and optval[ pos-1 ].isspace():\
186.262 +\n x=5+2\
186.263 +\n\
186.264 +\nmodeDict = { 'r':'rb','w':'wb', \\\
186.265 +\n 'a' : 'r+b' }\
186.266 +\nx = 2; y=3 ; z = 5\n
186.267 +
186.268 +
186.269 +nlFinallyCheckBox1.text="finall&y"
186.270 +
186.271 +
186.272 +AN_Preview=Preview
186.273 +AD_Preview=Preview
186.274 +FmtImports.formatImportsCb.text=Organize Imports during formatting
186.275 +FmtImports.removeDuplicateCb.text=Remove Duplicate Imports
186.276 +FmtImports.systemLibsCb.text=Separate out system libraries
186.277 +FmtImports.onePerLineCb.text=Prefer one import per line
186.278 +FmtImports.cleanupLabel.text=Unused imports:
186.279 +FmtImports.preferSymbols.text=Prefer symbol imports
186.280 +FmtImports.sortImportsCb.text=Sort Alphabetically
186.281 +FmtSpaces.addAroundOp.text=Add spaces around operators
186.282 +FmtSpaces.removeInParam.text=But remove in parameter assignments
186.283 +FmtSpaces.removeInParen.text=Remove spaces inside ( ), { }, and [ ]
186.284 +FmtSpaces.addAfterComma.text=Add spaces after commas
186.285 +FmtSpaces.removeBeforeSep.text=Remove spaces before separators ( : , ; )
186.286 +FmtSpaces.collapseSpacesCb.text=Collapse multiple spaces
186.287 +FmtImports.sepFromImpCb.text=Separate "from" and "import" statements
187.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
187.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtAlignment.form Wed Sep 02 20:31:18 2015 +0200
187.3 @@ -0,0 +1,350 @@
187.4 +<?xml version="1.0" encoding="UTF-8" ?>
187.5 +
187.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
187.7 + <Properties>
187.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Alignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.10 + </Property>
187.11 + <Property name="opaque" type="boolean" value="false"/>
187.12 + </Properties>
187.13 + <AuxValues>
187.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
187.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
187.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
187.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
187.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
187.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
187.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
187.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
187.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
187.23 + </AuxValues>
187.24 +
187.25 + <Layout>
187.26 + <DimensionLayout dim="0">
187.27 + <Group type="103" groupAlignment="0" attributes="0">
187.28 + <Group type="102" attributes="0">
187.29 + <Group type="103" groupAlignment="0" attributes="0">
187.30 + <Group type="102" alignment="0" attributes="0">
187.31 + <EmptySpace min="-2" max="-2" attributes="0"/>
187.32 + <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
187.33 + </Group>
187.34 + <Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
187.35 + <Group type="102" alignment="0" attributes="1">
187.36 + <Component id="newLinesLabel" min="-2" max="-2" attributes="0"/>
187.37 + <EmptySpace max="-2" attributes="0"/>
187.38 + <Component id="jSeparator1" max="32767" attributes="0"/>
187.39 + </Group>
187.40 + <Group type="102" alignment="0" attributes="1">
187.41 + <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
187.42 + <EmptySpace max="-2" attributes="0"/>
187.43 + <Component id="jSeparator2" max="32767" attributes="1"/>
187.44 + </Group>
187.45 + <Group type="102" alignment="0" attributes="0">
187.46 + <EmptySpace max="-2" attributes="0"/>
187.47 + <Group type="103" groupAlignment="0" attributes="0">
187.48 + <Component id="amThrowsCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
187.49 + <Component id="amBinaryOpCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
187.50 + <Component id="amAssignCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
187.51 + <Component id="amAnnotationArgsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
187.52 + <Component id="nlElseCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
187.53 + <Component id="nlWhileCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
187.54 + <Component id="nlCatchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
187.55 + <Component id="amMethodParamsCheckBox" alignment="0" min="-2" max="-2" attributes="1"/>
187.56 + </Group>
187.57 + <EmptySpace min="-2" max="-2" attributes="0"/>
187.58 + <Group type="103" groupAlignment="0" attributes="0">
187.59 + <Component id="amCallArgsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
187.60 + <Component id="nlModifiersCheckBox" min="-2" max="-2" attributes="0"/>
187.61 + <Component id="nlFinallyCheckBox" min="-2" max="-2" attributes="0"/>
187.62 + <Component id="amImplementsCheckBox1" min="-2" max="-2" attributes="0"/>
187.63 + <Component id="amArrayInitCheckBox1" min="-2" max="-2" attributes="0"/>
187.64 + <Component id="amTernaryOpCheckBox1" min="-2" max="-2" attributes="0"/>
187.65 + <Component id="amForCheckBox1" min="-2" max="-2" attributes="0"/>
187.66 + </Group>
187.67 + </Group>
187.68 + </Group>
187.69 + </Group>
187.70 + <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
187.71 + </Group>
187.72 + </Group>
187.73 + </DimensionLayout>
187.74 + <DimensionLayout dim="1">
187.75 + <Group type="103" groupAlignment="0" attributes="0">
187.76 + <Group type="102" alignment="0" attributes="0">
187.77 + <Group type="103" groupAlignment="0" attributes="0">
187.78 + <Group type="102" attributes="0">
187.79 + <EmptySpace max="-2" attributes="0"/>
187.80 + <Component id="newLinesLabel" min="-2" max="-2" attributes="1"/>
187.81 + </Group>
187.82 + <Group type="102" attributes="0">
187.83 + <EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
187.84 + <Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
187.85 + </Group>
187.86 + </Group>
187.87 + <EmptySpace max="-2" attributes="0"/>
187.88 + <Group type="103" groupAlignment="3" attributes="0">
187.89 + <Component id="nlElseCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.90 + <Component id="nlFinallyCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.91 + </Group>
187.92 + <EmptySpace max="-2" attributes="0"/>
187.93 + <Group type="103" groupAlignment="3" attributes="0">
187.94 + <Component id="nlWhileCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.95 + <Component id="nlModifiersCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.96 + </Group>
187.97 + <Group type="103" groupAlignment="0" attributes="0">
187.98 + <Group type="102" attributes="0">
187.99 + <EmptySpace max="-2" attributes="0"/>
187.100 + <Component id="nlCatchCheckBox" min="-2" max="-2" attributes="0"/>
187.101 + <EmptySpace type="separate" max="-2" attributes="0"/>
187.102 + <Component id="multilineAlignmentLabel" min="-2" max="-2" attributes="0"/>
187.103 + </Group>
187.104 + <Group type="102" attributes="0">
187.105 + <EmptySpace min="-2" pref="44" max="-2" attributes="0"/>
187.106 + <Component id="jSeparator2" min="-2" pref="10" max="-2" attributes="0"/>
187.107 + </Group>
187.108 + </Group>
187.109 + <EmptySpace min="-2" max="-2" attributes="0"/>
187.110 + <Group type="103" groupAlignment="3" attributes="0">
187.111 + <Component id="amMethodParamsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.112 + <Component id="amCallArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.113 + </Group>
187.114 + <EmptySpace min="-2" max="-2" attributes="0"/>
187.115 + <Group type="103" groupAlignment="3" attributes="0">
187.116 + <Component id="amAnnotationArgsCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
187.117 + <Component id="amImplementsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.118 + </Group>
187.119 + <EmptySpace max="-2" attributes="0"/>
187.120 + <Group type="103" groupAlignment="3" attributes="0">
187.121 + <Component id="amThrowsCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.122 + <Component id="amArrayInitCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.123 + </Group>
187.124 + <EmptySpace max="-2" attributes="0"/>
187.125 + <Group type="103" groupAlignment="3" attributes="0">
187.126 + <Component id="amBinaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.127 + <Component id="amTernaryOpCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.128 + </Group>
187.129 + <EmptySpace max="-2" attributes="0"/>
187.130 + <Group type="103" groupAlignment="3" attributes="0">
187.131 + <Component id="amAssignCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.132 + <Component id="amForCheckBox1" alignment="3" min="-2" max="-2" attributes="0"/>
187.133 + </Group>
187.134 + <EmptySpace min="-2" max="-2" attributes="0"/>
187.135 + <Component id="amParenthesizedCheckBox1" min="-2" max="-2" attributes="0"/>
187.136 + <EmptySpace max="32767" attributes="0"/>
187.137 + </Group>
187.138 + </Group>
187.139 + </DimensionLayout>
187.140 + </Layout>
187.141 + <SubComponents>
187.142 + <Component class="javax.swing.JLabel" name="newLinesLabel">
187.143 + <Properties>
187.144 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.145 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_newLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.146 + </Property>
187.147 + </Properties>
187.148 + </Component>
187.149 + <Component class="javax.swing.JCheckBox" name="nlElseCheckBox">
187.150 + <Properties>
187.151 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.152 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Else" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.153 + </Property>
187.154 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.155 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.156 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.157 + </Border>
187.158 + </Property>
187.159 + </Properties>
187.160 + </Component>
187.161 + <Component class="javax.swing.JCheckBox" name="nlWhileCheckBox">
187.162 + <Properties>
187.163 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.164 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_While" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.165 + </Property>
187.166 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.167 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.168 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.169 + </Border>
187.170 + </Property>
187.171 + </Properties>
187.172 + </Component>
187.173 + <Component class="javax.swing.JCheckBox" name="nlCatchCheckBox">
187.174 + <Properties>
187.175 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.176 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Catch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.177 + </Property>
187.178 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.179 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.180 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.181 + </Border>
187.182 + </Property>
187.183 + </Properties>
187.184 + </Component>
187.185 + <Component class="javax.swing.JCheckBox" name="nlFinallyCheckBox">
187.186 + <Properties>
187.187 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.188 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Finally" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.189 + </Property>
187.190 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.191 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.192 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.193 + </Border>
187.194 + </Property>
187.195 + </Properties>
187.196 + </Component>
187.197 + <Component class="javax.swing.JCheckBox" name="nlModifiersCheckBox">
187.198 + <Properties>
187.199 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.200 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_nl_Modifiers" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.201 + </Property>
187.202 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.203 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.204 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.205 + </Border>
187.206 + </Property>
187.207 + </Properties>
187.208 + </Component>
187.209 + <Component class="javax.swing.JLabel" name="multilineAlignmentLabel">
187.210 + <Properties>
187.211 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.212 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_al_multilineAlignment" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.213 + </Property>
187.214 + </Properties>
187.215 + </Component>
187.216 + <Component class="javax.swing.JCheckBox" name="amMethodParamsCheckBox">
187.217 + <Properties>
187.218 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.219 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_MethodParams" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.220 + </Property>
187.221 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.222 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.223 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.224 + </Border>
187.225 + </Property>
187.226 + </Properties>
187.227 + </Component>
187.228 + <Component class="javax.swing.JCheckBox" name="amCallArgsCheckBox">
187.229 + <Properties>
187.230 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.231 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_CallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.232 + </Property>
187.233 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.234 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.235 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.236 + </Border>
187.237 + </Property>
187.238 + </Properties>
187.239 + </Component>
187.240 + <Component class="javax.swing.JCheckBox" name="amAnnotationArgsCheckBox">
187.241 + <Properties>
187.242 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.243 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_AnnotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.244 + </Property>
187.245 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.246 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.247 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.248 + </Border>
187.249 + </Property>
187.250 + </Properties>
187.251 + </Component>
187.252 + <Component class="javax.swing.JCheckBox" name="amImplementsCheckBox1">
187.253 + <Properties>
187.254 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.255 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_an_Implements" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.256 + </Property>
187.257 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.258 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.259 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.260 + </Border>
187.261 + </Property>
187.262 + </Properties>
187.263 + </Component>
187.264 + <Component class="javax.swing.JCheckBox" name="amThrowsCheckBox1">
187.265 + <Properties>
187.266 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.267 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Throws" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.268 + </Property>
187.269 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.270 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.271 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.272 + </Border>
187.273 + </Property>
187.274 + </Properties>
187.275 + </Component>
187.276 + <Component class="javax.swing.JCheckBox" name="amArrayInitCheckBox1">
187.277 + <Properties>
187.278 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.279 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_ArrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.280 + </Property>
187.281 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.282 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.283 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.284 + </Border>
187.285 + </Property>
187.286 + </Properties>
187.287 + </Component>
187.288 + <Component class="javax.swing.JCheckBox" name="amBinaryOpCheckBox1">
187.289 + <Properties>
187.290 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.291 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_BinaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.292 + </Property>
187.293 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.294 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.295 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.296 + </Border>
187.297 + </Property>
187.298 + </Properties>
187.299 + </Component>
187.300 + <Component class="javax.swing.JCheckBox" name="amTernaryOpCheckBox1">
187.301 + <Properties>
187.302 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.303 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_TernaryOp" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.304 + </Property>
187.305 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.306 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.307 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.308 + </Border>
187.309 + </Property>
187.310 + </Properties>
187.311 + </Component>
187.312 + <Component class="javax.swing.JCheckBox" name="amAssignCheckBox1">
187.313 + <Properties>
187.314 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.315 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Assign" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.316 + </Property>
187.317 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.318 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.319 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.320 + </Border>
187.321 + </Property>
187.322 + </Properties>
187.323 + </Component>
187.324 + <Component class="javax.swing.JCheckBox" name="amForCheckBox1">
187.325 + <Properties>
187.326 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.327 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_For" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.328 + </Property>
187.329 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.330 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.331 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.332 + </Border>
187.333 + </Property>
187.334 + </Properties>
187.335 + </Component>
187.336 + <Component class="javax.swing.JCheckBox" name="amParenthesizedCheckBox1">
187.337 + <Properties>
187.338 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
187.339 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_am_Paren" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
187.340 + </Property>
187.341 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
187.342 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
187.343 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
187.344 + </Border>
187.345 + </Property>
187.346 + </Properties>
187.347 + </Component>
187.348 + <Component class="javax.swing.JSeparator" name="jSeparator1">
187.349 + </Component>
187.350 + <Component class="javax.swing.JSeparator" name="jSeparator2">
187.351 + </Component>
187.352 + </SubComponents>
187.353 +</Form>
188.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
188.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtAlignment.java Wed Sep 02 20:31:18 2015 +0200
188.3 @@ -0,0 +1,309 @@
188.4 +/*
188.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
188.6 + *
188.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
188.8 + *
188.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
188.10 + * Other names may be trademarks of their respective owners.
188.11 + *
188.12 + * The contents of this file are subject to the terms of either the GNU
188.13 + * General Public License Version 2 only ("GPL") or the Common
188.14 + * Development and Distribution License("CDDL") (collectively, the
188.15 + * "License"). You may not use this file except in compliance with the
188.16 + * License. You can obtain a copy of the License at
188.17 + * http://www.netbeans.org/cddl-gplv2.html
188.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
188.19 + * specific language governing permissions and limitations under the
188.20 + * License. When distributing the software, include this License Header
188.21 + * Notice in each file and include the License file at
188.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
188.23 + * particular file as subject to the "Classpath" exception as provided
188.24 + * by Oracle in the GPL Version 2 section of the License file that
188.25 + * accompanied this code. If applicable, add the following below the
188.26 + * License Header, with the fields enclosed by brackets [] replaced by
188.27 + * your own identifying information:
188.28 + * "Portions Copyrighted [year] [name of copyright owner]"
188.29 + *
188.30 + * Contributor(s):
188.31 + *
188.32 + * The Original Software is NetBeans. The Initial Developer of the Original
188.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
188.34 + * Microsystems, Inc. All Rights Reserved.
188.35 + *
188.36 + * If you wish your version of this file to be governed by only the CDDL
188.37 + * or only the GPL Version 2, indicate your decision by adding
188.38 + * "[Contributor] elects to include this software in this distribution
188.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
188.40 + * single choice of license, a recipient has the option to distribute
188.41 + * your version of this file under either the CDDL, the GPL Version 2 or
188.42 + * to extend the choice of license to its licensees as provided above.
188.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
188.44 + * Version 2 license, then the option applies only if the new code is
188.45 + * made subject to such option by the copyright holder.
188.46 + */
188.47 +
188.48 +package org.netbeans.modules.python.source.ui;
188.49 +
188.50 +//import org.netbeans.modules.python.editor.options.CodeStyle.WrapStyle;
188.51 +//import static org.netbeans.modules.python.editor.options.FmtOptions.*;
188.52 +//import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
188.53 +//import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
188.54 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
188.55 +
188.56 +
188.57 +/**
188.58 + *
188.59 + * @author phrebejk
188.60 + */
188.61 +public class FmtAlignment extends javax.swing.JPanel {
188.62 +
188.63 + /** Creates new form FmtAlignment */
188.64 + public FmtAlignment() {
188.65 + initComponents();
188.66 +/*
188.67 + nlElseCheckBox.putClientProperty(OPTION_ID, placeElseOnNewLine);
188.68 + nlWhileCheckBox.putClientProperty(OPTION_ID, placeWhileOnNewLine);
188.69 + nlCatchCheckBox.putClientProperty(OPTION_ID, placeCatchOnNewLine);
188.70 + nlFinallyCheckBox.putClientProperty(OPTION_ID, placeFinallyOnNewLine);
188.71 + nlModifiersCheckBox.putClientProperty(OPTION_ID, placeNewLineAfterModifiers);
188.72 + amMethodParamsCheckBox.putClientProperty(OPTION_ID, alignMultilineMethodParams);
188.73 + amCallArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineCallArgs);
188.74 + amAnnotationArgsCheckBox.putClientProperty(OPTION_ID, alignMultilineAnnotationArgs);
188.75 + amArrayInitCheckBox1.putClientProperty(OPTION_ID, alignMultilineArrayInit);
188.76 + amAssignCheckBox1.putClientProperty(OPTION_ID, alignMultilineAssignment);
188.77 + amBinaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineBinaryOp);
188.78 + amForCheckBox1.putClientProperty(OPTION_ID, alignMultilineFor);
188.79 + amImplementsCheckBox1.putClientProperty(OPTION_ID, alignMultilineImplements);
188.80 + amParenthesizedCheckBox1.putClientProperty(OPTION_ID, alignMultilineParenthesized);
188.81 + amTernaryOpCheckBox1.putClientProperty(OPTION_ID, alignMultilineTernaryOp);
188.82 + amThrowsCheckBox1.putClientProperty(OPTION_ID, alignMultilineThrows);
188.83 + }
188.84 +
188.85 + public static PreferencesCustomizer.Factory getController() {
188.86 + return new CategorySupport.Factory("alignment", FmtAlignment.class, //NOI18N
188.87 + org.openide.util.NbBundle.getMessage(FmtAlignment.class, "SAMPLE_AlignBraces"), // NOI18N
188.88 + new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
188.89 + new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
188.90 + new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
188.91 + new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
188.92 + new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
188.93 + new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
188.94 + new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
188.95 + new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
188.96 + new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
188.97 + new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
188.98 + new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
188.99 + new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
188.100 + new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
188.101 + new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
188.102 + new String[] { FmtOptions.wrapAnnotationArgs, WrapStyle.WRAP_ALWAYS.name() },
188.103 + new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
188.104 + new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
188.105 + new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
188.106 + new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
188.107 + new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() } );
188.108 + */
188.109 + }
188.110 +
188.111 + /** This method is called from within the constructor to
188.112 + * initialize the form.
188.113 + * WARNING: Do NOT modify this code. The content of this method is
188.114 + * always regenerated by the Form Editor.
188.115 + */
188.116 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
188.117 + private void initComponents() {
188.118 +
188.119 + newLinesLabel = new javax.swing.JLabel();
188.120 + nlElseCheckBox = new javax.swing.JCheckBox();
188.121 + nlWhileCheckBox = new javax.swing.JCheckBox();
188.122 + nlCatchCheckBox = new javax.swing.JCheckBox();
188.123 + nlFinallyCheckBox = new javax.swing.JCheckBox();
188.124 + nlModifiersCheckBox = new javax.swing.JCheckBox();
188.125 + multilineAlignmentLabel = new javax.swing.JLabel();
188.126 + amMethodParamsCheckBox = new javax.swing.JCheckBox();
188.127 + amCallArgsCheckBox = new javax.swing.JCheckBox();
188.128 + amAnnotationArgsCheckBox = new javax.swing.JCheckBox();
188.129 + amImplementsCheckBox1 = new javax.swing.JCheckBox();
188.130 + amThrowsCheckBox1 = new javax.swing.JCheckBox();
188.131 + amArrayInitCheckBox1 = new javax.swing.JCheckBox();
188.132 + amBinaryOpCheckBox1 = new javax.swing.JCheckBox();
188.133 + amTernaryOpCheckBox1 = new javax.swing.JCheckBox();
188.134 + amAssignCheckBox1 = new javax.swing.JCheckBox();
188.135 + amForCheckBox1 = new javax.swing.JCheckBox();
188.136 + amParenthesizedCheckBox1 = new javax.swing.JCheckBox();
188.137 + jSeparator1 = new javax.swing.JSeparator();
188.138 + jSeparator2 = new javax.swing.JSeparator();
188.139 +
188.140 + setName(org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_Alignment")); // NOI18N
188.141 + setOpaque(false);
188.142 +
188.143 + org.openide.awt.Mnemonics.setLocalizedText(newLinesLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_newLines")); // NOI18N
188.144 +
188.145 + org.openide.awt.Mnemonics.setLocalizedText(nlElseCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Else")); // NOI18N
188.146 + nlElseCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.147 +
188.148 + org.openide.awt.Mnemonics.setLocalizedText(nlWhileCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_While")); // NOI18N
188.149 + nlWhileCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.150 +
188.151 + org.openide.awt.Mnemonics.setLocalizedText(nlCatchCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Catch")); // NOI18N
188.152 + nlCatchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.153 +
188.154 + org.openide.awt.Mnemonics.setLocalizedText(nlFinallyCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Finally")); // NOI18N
188.155 + nlFinallyCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.156 +
188.157 + org.openide.awt.Mnemonics.setLocalizedText(nlModifiersCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_nl_Modifiers")); // NOI18N
188.158 + nlModifiersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.159 +
188.160 + org.openide.awt.Mnemonics.setLocalizedText(multilineAlignmentLabel, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_al_multilineAlignment")); // NOI18N
188.161 +
188.162 + org.openide.awt.Mnemonics.setLocalizedText(amMethodParamsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_MethodParams")); // NOI18N
188.163 + amMethodParamsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.164 +
188.165 + org.openide.awt.Mnemonics.setLocalizedText(amCallArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_CallArgs")); // NOI18N
188.166 + amCallArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.167 +
188.168 + org.openide.awt.Mnemonics.setLocalizedText(amAnnotationArgsCheckBox, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_AnnotationArgs")); // NOI18N
188.169 + amAnnotationArgsCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.170 +
188.171 + org.openide.awt.Mnemonics.setLocalizedText(amImplementsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_an_Implements")); // NOI18N
188.172 + amImplementsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.173 +
188.174 + org.openide.awt.Mnemonics.setLocalizedText(amThrowsCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Throws")); // NOI18N
188.175 + amThrowsCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.176 +
188.177 + org.openide.awt.Mnemonics.setLocalizedText(amArrayInitCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_ArrayInit")); // NOI18N
188.178 + amArrayInitCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.179 +
188.180 + org.openide.awt.Mnemonics.setLocalizedText(amBinaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_BinaryOp")); // NOI18N
188.181 + amBinaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.182 +
188.183 + org.openide.awt.Mnemonics.setLocalizedText(amTernaryOpCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_TernaryOp")); // NOI18N
188.184 + amTernaryOpCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.185 +
188.186 + org.openide.awt.Mnemonics.setLocalizedText(amAssignCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Assign")); // NOI18N
188.187 + amAssignCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.188 +
188.189 + org.openide.awt.Mnemonics.setLocalizedText(amForCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_For")); // NOI18N
188.190 + amForCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.191 +
188.192 + org.openide.awt.Mnemonics.setLocalizedText(amParenthesizedCheckBox1, org.openide.util.NbBundle.getMessage(FmtAlignment.class, "LBL_am_Paren")); // NOI18N
188.193 + amParenthesizedCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
188.194 +
188.195 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
188.196 + this.setLayout(layout);
188.197 + layout.setHorizontalGroup(
188.198 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.199 + .addGroup(layout.createSequentialGroup()
188.200 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.201 + .addGroup(layout.createSequentialGroup()
188.202 + .addContainerGap()
188.203 + .addComponent(amParenthesizedCheckBox1))
188.204 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
188.205 + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
188.206 + .addComponent(newLinesLabel)
188.207 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.208 + .addComponent(jSeparator1))
188.209 + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
188.210 + .addComponent(multilineAlignmentLabel)
188.211 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.212 + .addComponent(jSeparator2))
188.213 + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
188.214 + .addContainerGap()
188.215 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.216 + .addComponent(amThrowsCheckBox1)
188.217 + .addComponent(amBinaryOpCheckBox1)
188.218 + .addComponent(amAssignCheckBox1)
188.219 + .addComponent(amAnnotationArgsCheckBox)
188.220 + .addComponent(nlElseCheckBox)
188.221 + .addComponent(nlWhileCheckBox)
188.222 + .addComponent(nlCatchCheckBox)
188.223 + .addComponent(amMethodParamsCheckBox))
188.224 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.225 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.226 + .addComponent(amCallArgsCheckBox)
188.227 + .addComponent(nlModifiersCheckBox)
188.228 + .addComponent(nlFinallyCheckBox)
188.229 + .addComponent(amImplementsCheckBox1)
188.230 + .addComponent(amArrayInitCheckBox1)
188.231 + .addComponent(amTernaryOpCheckBox1)
188.232 + .addComponent(amForCheckBox1)))))
188.233 + .addGap(0, 0, 0))
188.234 + );
188.235 + layout.setVerticalGroup(
188.236 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.237 + .addGroup(layout.createSequentialGroup()
188.238 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.239 + .addGroup(layout.createSequentialGroup()
188.240 + .addContainerGap()
188.241 + .addComponent(newLinesLabel))
188.242 + .addGroup(layout.createSequentialGroup()
188.243 + .addGap(17, 17, 17)
188.244 + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
188.245 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.246 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.247 + .addComponent(nlElseCheckBox)
188.248 + .addComponent(nlFinallyCheckBox))
188.249 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.250 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.251 + .addComponent(nlWhileCheckBox)
188.252 + .addComponent(nlModifiersCheckBox))
188.253 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188.254 + .addGroup(layout.createSequentialGroup()
188.255 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.256 + .addComponent(nlCatchCheckBox)
188.257 + .addGap(18, 18, 18)
188.258 + .addComponent(multilineAlignmentLabel))
188.259 + .addGroup(layout.createSequentialGroup()
188.260 + .addGap(44, 44, 44)
188.261 + .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)))
188.262 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.263 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.264 + .addComponent(amMethodParamsCheckBox)
188.265 + .addComponent(amCallArgsCheckBox))
188.266 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.267 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.268 + .addComponent(amAnnotationArgsCheckBox)
188.269 + .addComponent(amImplementsCheckBox1))
188.270 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.271 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.272 + .addComponent(amThrowsCheckBox1)
188.273 + .addComponent(amArrayInitCheckBox1))
188.274 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.275 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.276 + .addComponent(amBinaryOpCheckBox1)
188.277 + .addComponent(amTernaryOpCheckBox1))
188.278 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.279 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
188.280 + .addComponent(amAssignCheckBox1)
188.281 + .addComponent(amForCheckBox1))
188.282 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
188.283 + .addComponent(amParenthesizedCheckBox1)
188.284 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
188.285 + );
188.286 + }// </editor-fold>//GEN-END:initComponents
188.287 +
188.288 +
188.289 + // Variables declaration - do not modify//GEN-BEGIN:variables
188.290 + private javax.swing.JCheckBox amAnnotationArgsCheckBox;
188.291 + private javax.swing.JCheckBox amArrayInitCheckBox1;
188.292 + private javax.swing.JCheckBox amAssignCheckBox1;
188.293 + private javax.swing.JCheckBox amBinaryOpCheckBox1;
188.294 + private javax.swing.JCheckBox amCallArgsCheckBox;
188.295 + private javax.swing.JCheckBox amForCheckBox1;
188.296 + private javax.swing.JCheckBox amImplementsCheckBox1;
188.297 + private javax.swing.JCheckBox amMethodParamsCheckBox;
188.298 + private javax.swing.JCheckBox amParenthesizedCheckBox1;
188.299 + private javax.swing.JCheckBox amTernaryOpCheckBox1;
188.300 + private javax.swing.JCheckBox amThrowsCheckBox1;
188.301 + private javax.swing.JSeparator jSeparator1;
188.302 + private javax.swing.JSeparator jSeparator2;
188.303 + private javax.swing.JLabel multilineAlignmentLabel;
188.304 + private javax.swing.JLabel newLinesLabel;
188.305 + private javax.swing.JCheckBox nlCatchCheckBox;
188.306 + private javax.swing.JCheckBox nlElseCheckBox;
188.307 + private javax.swing.JCheckBox nlFinallyCheckBox;
188.308 + private javax.swing.JCheckBox nlModifiersCheckBox;
188.309 + private javax.swing.JCheckBox nlWhileCheckBox;
188.310 + // End of variables declaration//GEN-END:variables
188.311 +
188.312 +}
189.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
189.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtBlankLines.form Wed Sep 02 20:31:18 2015 +0200
189.3 @@ -0,0 +1,284 @@
189.4 +<?xml version="1.0" encoding="UTF-8" ?>
189.5 +
189.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
189.7 + <Properties>
189.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_BlankLines" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.10 + </Property>
189.11 + <Property name="opaque" type="boolean" value="false"/>
189.12 + </Properties>
189.13 + <AuxValues>
189.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
189.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
189.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
189.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
189.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
189.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
189.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
189.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
189.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
189.23 + </AuxValues>
189.24 +
189.25 + <Layout>
189.26 + <DimensionLayout dim="0">
189.27 + <Group type="103" groupAlignment="0" attributes="0">
189.28 + <Group type="102" attributes="0">
189.29 + <Group type="103" groupAlignment="0" attributes="0">
189.30 + <Component id="bPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.31 + <Component id="aPackageLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.32 + <Component id="bImportsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.33 + <Component id="aImports" alignment="0" min="-2" max="-2" attributes="0"/>
189.34 + <Component id="bClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.35 + <Component id="aClassLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.36 + <Component id="aClassHeaderLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.37 + <Component id="bFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.38 + <Component id="aFieldsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.39 + <Component id="bMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.40 + <Component id="aMethodsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
189.41 + </Group>
189.42 + <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
189.43 + <Group type="103" groupAlignment="0" attributes="0">
189.44 + <Component id="aMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.45 + <Component id="bMethodsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.46 + <Component id="aFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.47 + <Component id="bFieldsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.48 + <Component id="aClassHeaderField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.49 + <Component id="aClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.50 + <Component id="bClassField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.51 + <Component id="aImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.52 + <Component id="bImportsField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.53 + <Component id="aPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.54 + <Component id="bPackageField" linkSize="1" alignment="0" min="-2" max="-2" attributes="0"/>
189.55 + </Group>
189.56 + </Group>
189.57 + </Group>
189.58 + </DimensionLayout>
189.59 + <DimensionLayout dim="1">
189.60 + <Group type="103" groupAlignment="0" attributes="0">
189.61 + <Group type="102" attributes="0">
189.62 + <Group type="103" groupAlignment="3" attributes="0">
189.63 + <Component id="bPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.64 + <Component id="bPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.65 + </Group>
189.66 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.67 + <Group type="103" groupAlignment="3" attributes="0">
189.68 + <Component id="aPackageField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.69 + <Component id="aPackageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.70 + </Group>
189.71 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.72 + <Group type="103" groupAlignment="3" attributes="0">
189.73 + <Component id="bImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.74 + <Component id="bImportsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.75 + </Group>
189.76 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.77 + <Group type="103" groupAlignment="3" attributes="0">
189.78 + <Component id="aImportsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.79 + <Component id="aImports" alignment="3" min="-2" max="-2" attributes="0"/>
189.80 + </Group>
189.81 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.82 + <Group type="103" groupAlignment="3" attributes="0">
189.83 + <Component id="bClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.84 + <Component id="bClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.85 + </Group>
189.86 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.87 + <Group type="103" groupAlignment="3" attributes="0">
189.88 + <Component id="aClassField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.89 + <Component id="aClassLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.90 + </Group>
189.91 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.92 + <Group type="103" groupAlignment="3" attributes="0">
189.93 + <Component id="aClassHeaderField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.94 + <Component id="aClassHeaderLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.95 + </Group>
189.96 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.97 + <Group type="103" groupAlignment="3" attributes="0">
189.98 + <Component id="bFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.99 + <Component id="bFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.100 + </Group>
189.101 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.102 + <Group type="103" groupAlignment="3" attributes="0">
189.103 + <Component id="aFieldsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.104 + <Component id="aFieldsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.105 + </Group>
189.106 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.107 + <Group type="103" groupAlignment="3" attributes="0">
189.108 + <Component id="bMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.109 + <Component id="bMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.110 + </Group>
189.111 + <EmptySpace min="4" pref="4" max="4" attributes="0"/>
189.112 + <Group type="103" groupAlignment="3" attributes="0">
189.113 + <Component id="aMethodsField" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
189.114 + <Component id="aMethodsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
189.115 + </Group>
189.116 + </Group>
189.117 + </Group>
189.118 + </DimensionLayout>
189.119 + </Layout>
189.120 + <SubComponents>
189.121 + <Component class="javax.swing.JLabel" name="bPackageLabel">
189.122 + <Properties>
189.123 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.124 + <ComponentRef name="bPackageField"/>
189.125 + </Property>
189.126 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.127 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforePackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.128 + </Property>
189.129 + </Properties>
189.130 + </Component>
189.131 + <Component class="javax.swing.JTextField" name="bPackageField">
189.132 + <Properties>
189.133 + <Property name="columns" type="int" value="5"/>
189.134 + </Properties>
189.135 + </Component>
189.136 + <Component class="javax.swing.JLabel" name="aPackageLabel">
189.137 + <Properties>
189.138 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.139 + <ComponentRef name="aPackageField"/>
189.140 + </Property>
189.141 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.142 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterPackage" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.143 + </Property>
189.144 + </Properties>
189.145 + </Component>
189.146 + <Component class="javax.swing.JTextField" name="aPackageField">
189.147 + <Properties>
189.148 + <Property name="columns" type="int" value="5"/>
189.149 + </Properties>
189.150 + </Component>
189.151 + <Component class="javax.swing.JLabel" name="bImportsLabel">
189.152 + <Properties>
189.153 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.154 + <ComponentRef name="bImportsField"/>
189.155 + </Property>
189.156 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.157 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.158 + </Property>
189.159 + </Properties>
189.160 + </Component>
189.161 + <Component class="javax.swing.JTextField" name="bImportsField">
189.162 + <Properties>
189.163 + <Property name="columns" type="int" value="5"/>
189.164 + </Properties>
189.165 + </Component>
189.166 + <Component class="javax.swing.JLabel" name="aImports">
189.167 + <Properties>
189.168 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.169 + <ComponentRef name="aImportsField"/>
189.170 + </Property>
189.171 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.172 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterImports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.173 + </Property>
189.174 + </Properties>
189.175 + </Component>
189.176 + <Component class="javax.swing.JTextField" name="aImportsField">
189.177 + <Properties>
189.178 + <Property name="columns" type="int" value="5"/>
189.179 + </Properties>
189.180 + </Component>
189.181 + <Component class="javax.swing.JLabel" name="bClassLabel">
189.182 + <Properties>
189.183 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.184 + <ComponentRef name="bClassField"/>
189.185 + </Property>
189.186 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.187 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.188 + </Property>
189.189 + </Properties>
189.190 + </Component>
189.191 + <Component class="javax.swing.JTextField" name="bClassField">
189.192 + <Properties>
189.193 + <Property name="columns" type="int" value="5"/>
189.194 + </Properties>
189.195 + </Component>
189.196 + <Component class="javax.swing.JLabel" name="aClassLabel">
189.197 + <Properties>
189.198 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.199 + <ComponentRef name="aClassField"/>
189.200 + </Property>
189.201 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.202 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClass" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.203 + </Property>
189.204 + </Properties>
189.205 + </Component>
189.206 + <Component class="javax.swing.JTextField" name="aClassField">
189.207 + <Properties>
189.208 + <Property name="columns" type="int" value="5"/>
189.209 + </Properties>
189.210 + </Component>
189.211 + <Component class="javax.swing.JLabel" name="aClassHeaderLabel">
189.212 + <Properties>
189.213 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.214 + <ComponentRef name="aClassHeaderField"/>
189.215 + </Property>
189.216 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.217 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterClassHeader" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.218 + </Property>
189.219 + </Properties>
189.220 + </Component>
189.221 + <Component class="javax.swing.JTextField" name="aClassHeaderField">
189.222 + <Properties>
189.223 + <Property name="columns" type="int" value="5"/>
189.224 + </Properties>
189.225 + </Component>
189.226 + <Component class="javax.swing.JLabel" name="bFieldsLabel">
189.227 + <Properties>
189.228 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.229 + <ComponentRef name="bFieldsField"/>
189.230 + </Property>
189.231 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.232 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.233 + </Property>
189.234 + </Properties>
189.235 + </Component>
189.236 + <Component class="javax.swing.JTextField" name="bFieldsField">
189.237 + <Properties>
189.238 + <Property name="columns" type="int" value="5"/>
189.239 + </Properties>
189.240 + </Component>
189.241 + <Component class="javax.swing.JLabel" name="aFieldsLabel">
189.242 + <Properties>
189.243 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.244 + <ComponentRef name="aFieldsField"/>
189.245 + </Property>
189.246 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.247 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterFields" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.248 + </Property>
189.249 + </Properties>
189.250 + </Component>
189.251 + <Component class="javax.swing.JTextField" name="aFieldsField">
189.252 + <Properties>
189.253 + <Property name="columns" type="int" value="5"/>
189.254 + </Properties>
189.255 + </Component>
189.256 + <Component class="javax.swing.JLabel" name="bMethodsLabel">
189.257 + <Properties>
189.258 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.259 + <ComponentRef name="bMethodsField"/>
189.260 + </Property>
189.261 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.262 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blBeforeMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.263 + </Property>
189.264 + </Properties>
189.265 + </Component>
189.266 + <Component class="javax.swing.JTextField" name="bMethodsField">
189.267 + <Properties>
189.268 + <Property name="columns" type="int" value="5"/>
189.269 + </Properties>
189.270 + </Component>
189.271 + <Component class="javax.swing.JLabel" name="aMethodsLabel">
189.272 + <Properties>
189.273 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
189.274 + <ComponentRef name="aMethodsField"/>
189.275 + </Property>
189.276 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
189.277 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_blAfterMethods" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
189.278 + </Property>
189.279 + </Properties>
189.280 + </Component>
189.281 + <Component class="javax.swing.JTextField" name="aMethodsField">
189.282 + <Properties>
189.283 + <Property name="columns" type="int" value="5"/>
189.284 + </Properties>
189.285 + </Component>
189.286 + </SubComponents>
189.287 +</Form>
190.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
190.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtBlankLines.java Wed Sep 02 20:31:18 2015 +0200
190.3 @@ -0,0 +1,295 @@
190.4 +/*
190.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
190.6 + *
190.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
190.8 + *
190.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
190.10 + * Other names may be trademarks of their respective owners.
190.11 + *
190.12 + * The contents of this file are subject to the terms of either the GNU
190.13 + * General Public License Version 2 only ("GPL") or the Common
190.14 + * Development and Distribution License("CDDL") (collectively, the
190.15 + * "License"). You may not use this file except in compliance with the
190.16 + * License. You can obtain a copy of the License at
190.17 + * http://www.netbeans.org/cddl-gplv2.html
190.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
190.19 + * specific language governing permissions and limitations under the
190.20 + * License. When distributing the software, include this License Header
190.21 + * Notice in each file and include the License file at
190.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
190.23 + * particular file as subject to the "Classpath" exception as provided
190.24 + * by Oracle in the GPL Version 2 section of the License file that
190.25 + * accompanied this code. If applicable, add the following below the
190.26 + * License Header, with the fields enclosed by brackets [] replaced by
190.27 + * your own identifying information:
190.28 + * "Portions Copyrighted [year] [name of copyright owner]"
190.29 + *
190.30 + * Contributor(s):
190.31 + *
190.32 + * The Original Software is NetBeans. The Initial Developer of the Original
190.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
190.34 + * Microsystems, Inc. All Rights Reserved.
190.35 + *
190.36 + * If you wish your version of this file to be governed by only the CDDL
190.37 + * or only the GPL Version 2, indicate your decision by adding
190.38 + * "[Contributor] elects to include this software in this distribution
190.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
190.40 + * single choice of license, a recipient has the option to distribute
190.41 + * your version of this file under either the CDDL, the GPL Version 2 or
190.42 + * to extend the choice of license to its licensees as provided above.
190.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
190.44 + * Version 2 license, then the option applies only if the new code is
190.45 + * made subject to such option by the copyright holder.
190.46 + */
190.47 +
190.48 +package org.netbeans.modules.python.source.ui;
190.49 +
190.50 +//import static org.netbeans.modules.python.editor.options.FmtOptions.*;
190.51 +//import static org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport.OPTION_ID;
190.52 +//import org.netbeans.modules.python.editor.options.FmtOptions.CategorySupport;
190.53 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
190.54 +
190.55 +/**
190.56 + *
190.57 + * @author phrebejk
190.58 + */
190.59 +public class FmtBlankLines extends javax.swing.JPanel {
190.60 +
190.61 + /** Creates new form FmtBlankLines */
190.62 + public FmtBlankLines() {
190.63 + initComponents();
190.64 +/*
190.65 + bPackageField.putClientProperty(OPTION_ID, blankLinesBeforePackage );
190.66 + aPackageField.putClientProperty(OPTION_ID, blankLinesAfterPackage);
190.67 + bImportsField.putClientProperty(OPTION_ID, blankLinesBeforeImports);
190.68 + aImportsField.putClientProperty(OPTION_ID, blankLinesAfterImports);
190.69 + bClassField.putClientProperty(OPTION_ID, blankLinesBeforeClass);
190.70 + aClassField.putClientProperty(OPTION_ID, blankLinesAfterClass);
190.71 + aClassHeaderField.putClientProperty(OPTION_ID, blankLinesAfterClassHeader);
190.72 + bFieldsField.putClientProperty(OPTION_ID, blankLinesBeforeFields);
190.73 + aFieldsField.putClientProperty(OPTION_ID, blankLinesAfterFields);
190.74 + bMethodsField.putClientProperty(OPTION_ID, blankLinesBeforeMethods );
190.75 + aMethodsField.putClientProperty(OPTION_ID, blankLinesAfterMethods);
190.76 +
190.77 + bPackageField.addKeyListener(new NumericKeyListener());
190.78 + aPackageField.addKeyListener(new NumericKeyListener());
190.79 + bImportsField.addKeyListener(new NumericKeyListener());
190.80 + aImportsField.addKeyListener(new NumericKeyListener());
190.81 + bClassField.addKeyListener(new NumericKeyListener());
190.82 + aClassField.addKeyListener(new NumericKeyListener());
190.83 + aClassHeaderField.addKeyListener(new NumericKeyListener());
190.84 + bFieldsField.addKeyListener(new NumericKeyListener());
190.85 + aFieldsField.addKeyListener(new NumericKeyListener());
190.86 + bMethodsField.addKeyListener(new NumericKeyListener());
190.87 + aMethodsField.addKeyListener(new NumericKeyListener());
190.88 +
190.89 + }
190.90 +
190.91 + public static PreferencesCustomizer.Factory getController() {
190.92 + return new CategorySupport.Factory("blank-lines", FmtBlankLines.class, //NOI18N
190.93 + org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "SAMPLE_BlankLines")); // NOI18N
190.94 + */
190.95 + }
190.96 +
190.97 + /** This method is called from within the constructor to
190.98 + * initialize the form.
190.99 + * WARNING: Do NOT modify this code. The content of this method is
190.100 + * always regenerated by the Form Editor.
190.101 + */
190.102 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
190.103 + private void initComponents() {
190.104 +
190.105 + bPackageLabel = new javax.swing.JLabel();
190.106 + bPackageField = new javax.swing.JTextField();
190.107 + aPackageLabel = new javax.swing.JLabel();
190.108 + aPackageField = new javax.swing.JTextField();
190.109 + bImportsLabel = new javax.swing.JLabel();
190.110 + bImportsField = new javax.swing.JTextField();
190.111 + aImports = new javax.swing.JLabel();
190.112 + aImportsField = new javax.swing.JTextField();
190.113 + bClassLabel = new javax.swing.JLabel();
190.114 + bClassField = new javax.swing.JTextField();
190.115 + aClassLabel = new javax.swing.JLabel();
190.116 + aClassField = new javax.swing.JTextField();
190.117 + aClassHeaderLabel = new javax.swing.JLabel();
190.118 + aClassHeaderField = new javax.swing.JTextField();
190.119 + bFieldsLabel = new javax.swing.JLabel();
190.120 + bFieldsField = new javax.swing.JTextField();
190.121 + aFieldsLabel = new javax.swing.JLabel();
190.122 + aFieldsField = new javax.swing.JTextField();
190.123 + bMethodsLabel = new javax.swing.JLabel();
190.124 + bMethodsField = new javax.swing.JTextField();
190.125 + aMethodsLabel = new javax.swing.JLabel();
190.126 + aMethodsField = new javax.swing.JTextField();
190.127 +
190.128 + setName(org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_BlankLines")); // NOI18N
190.129 + setOpaque(false);
190.130 +
190.131 + bPackageLabel.setLabelFor(bPackageField);
190.132 + org.openide.awt.Mnemonics.setLocalizedText(bPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforePackage")); // NOI18N
190.133 +
190.134 + bPackageField.setColumns(5);
190.135 +
190.136 + aPackageLabel.setLabelFor(aPackageField);
190.137 + org.openide.awt.Mnemonics.setLocalizedText(aPackageLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterPackage")); // NOI18N
190.138 +
190.139 + aPackageField.setColumns(5);
190.140 +
190.141 + bImportsLabel.setLabelFor(bImportsField);
190.142 + org.openide.awt.Mnemonics.setLocalizedText(bImportsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeImports")); // NOI18N
190.143 +
190.144 + bImportsField.setColumns(5);
190.145 +
190.146 + aImports.setLabelFor(aImportsField);
190.147 + org.openide.awt.Mnemonics.setLocalizedText(aImports, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterImports")); // NOI18N
190.148 +
190.149 + aImportsField.setColumns(5);
190.150 +
190.151 + bClassLabel.setLabelFor(bClassField);
190.152 + org.openide.awt.Mnemonics.setLocalizedText(bClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeClass")); // NOI18N
190.153 +
190.154 + bClassField.setColumns(5);
190.155 +
190.156 + aClassLabel.setLabelFor(aClassField);
190.157 + org.openide.awt.Mnemonics.setLocalizedText(aClassLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClass")); // NOI18N
190.158 +
190.159 + aClassField.setColumns(5);
190.160 +
190.161 + aClassHeaderLabel.setLabelFor(aClassHeaderField);
190.162 + org.openide.awt.Mnemonics.setLocalizedText(aClassHeaderLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterClassHeader")); // NOI18N
190.163 +
190.164 + aClassHeaderField.setColumns(5);
190.165 +
190.166 + bFieldsLabel.setLabelFor(bFieldsField);
190.167 + org.openide.awt.Mnemonics.setLocalizedText(bFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeFields")); // NOI18N
190.168 +
190.169 + bFieldsField.setColumns(5);
190.170 +
190.171 + aFieldsLabel.setLabelFor(aFieldsField);
190.172 + org.openide.awt.Mnemonics.setLocalizedText(aFieldsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterFields")); // NOI18N
190.173 +
190.174 + aFieldsField.setColumns(5);
190.175 +
190.176 + bMethodsLabel.setLabelFor(bMethodsField);
190.177 + org.openide.awt.Mnemonics.setLocalizedText(bMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blBeforeMethods")); // NOI18N
190.178 +
190.179 + bMethodsField.setColumns(5);
190.180 +
190.181 + aMethodsLabel.setLabelFor(aMethodsField);
190.182 + org.openide.awt.Mnemonics.setLocalizedText(aMethodsLabel, org.openide.util.NbBundle.getMessage(FmtBlankLines.class, "LBL_blAfterMethods")); // NOI18N
190.183 +
190.184 + aMethodsField.setColumns(5);
190.185 +
190.186 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
190.187 + this.setLayout(layout);
190.188 + layout.setHorizontalGroup(
190.189 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
190.190 + .addGroup(layout.createSequentialGroup()
190.191 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
190.192 + .addComponent(bPackageLabel)
190.193 + .addComponent(aPackageLabel)
190.194 + .addComponent(bImportsLabel)
190.195 + .addComponent(aImports)
190.196 + .addComponent(bClassLabel)
190.197 + .addComponent(aClassLabel)
190.198 + .addComponent(aClassHeaderLabel)
190.199 + .addComponent(bFieldsLabel)
190.200 + .addComponent(aFieldsLabel)
190.201 + .addComponent(bMethodsLabel)
190.202 + .addComponent(aMethodsLabel))
190.203 + .addGap(6, 6, 6)
190.204 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
190.205 + .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.206 + .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.207 + .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.208 + .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.209 + .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.210 + .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.211 + .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.212 + .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.213 + .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.214 + .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.215 + .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
190.216 + );
190.217 +
190.218 + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
190.219 +
190.220 + layout.setVerticalGroup(
190.221 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
190.222 + .addGroup(layout.createSequentialGroup()
190.223 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.224 + .addComponent(bPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.225 + .addComponent(bPackageLabel))
190.226 + .addGap(4, 4, 4)
190.227 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.228 + .addComponent(aPackageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.229 + .addComponent(aPackageLabel))
190.230 + .addGap(4, 4, 4)
190.231 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.232 + .addComponent(bImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.233 + .addComponent(bImportsLabel))
190.234 + .addGap(4, 4, 4)
190.235 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.236 + .addComponent(aImportsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.237 + .addComponent(aImports))
190.238 + .addGap(4, 4, 4)
190.239 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.240 + .addComponent(bClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.241 + .addComponent(bClassLabel))
190.242 + .addGap(4, 4, 4)
190.243 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.244 + .addComponent(aClassField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.245 + .addComponent(aClassLabel))
190.246 + .addGap(4, 4, 4)
190.247 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.248 + .addComponent(aClassHeaderField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.249 + .addComponent(aClassHeaderLabel))
190.250 + .addGap(4, 4, 4)
190.251 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.252 + .addComponent(bFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.253 + .addComponent(bFieldsLabel))
190.254 + .addGap(4, 4, 4)
190.255 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.256 + .addComponent(aFieldsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.257 + .addComponent(aFieldsLabel))
190.258 + .addGap(4, 4, 4)
190.259 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.260 + .addComponent(bMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.261 + .addComponent(bMethodsLabel))
190.262 + .addGap(4, 4, 4)
190.263 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
190.264 + .addComponent(aMethodsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
190.265 + .addComponent(aMethodsLabel)))
190.266 + );
190.267 +
190.268 + layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {aClassField, aClassHeaderField, aFieldsField, aImportsField, aMethodsField, aPackageField, bClassField, bFieldsField, bImportsField, bMethodsField, bPackageField});
190.269 +
190.270 + }// </editor-fold>//GEN-END:initComponents
190.271 +
190.272 +
190.273 + // Variables declaration - do not modify//GEN-BEGIN:variables
190.274 + private javax.swing.JTextField aClassField;
190.275 + private javax.swing.JTextField aClassHeaderField;
190.276 + private javax.swing.JLabel aClassHeaderLabel;
190.277 + private javax.swing.JLabel aClassLabel;
190.278 + private javax.swing.JTextField aFieldsField;
190.279 + private javax.swing.JLabel aFieldsLabel;
190.280 + private javax.swing.JLabel aImports;
190.281 + private javax.swing.JTextField aImportsField;
190.282 + private javax.swing.JTextField aMethodsField;
190.283 + private javax.swing.JLabel aMethodsLabel;
190.284 + private javax.swing.JTextField aPackageField;
190.285 + private javax.swing.JLabel aPackageLabel;
190.286 + private javax.swing.JTextField bClassField;
190.287 + private javax.swing.JLabel bClassLabel;
190.288 + private javax.swing.JTextField bFieldsField;
190.289 + private javax.swing.JLabel bFieldsLabel;
190.290 + private javax.swing.JTextField bImportsField;
190.291 + private javax.swing.JLabel bImportsLabel;
190.292 + private javax.swing.JTextField bMethodsField;
190.293 + private javax.swing.JLabel bMethodsLabel;
190.294 + private javax.swing.JTextField bPackageField;
190.295 + private javax.swing.JLabel bPackageLabel;
190.296 + // End of variables declaration//GEN-END:variables
190.297 +
190.298 +}
191.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
191.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtImports.form Wed Sep 02 20:31:18 2015 +0200
191.3 @@ -0,0 +1,129 @@
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_Imports" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.10 + </Property>
191.11 + </Properties>
191.12 + <AuxValues>
191.13 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
191.14 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
191.15 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
191.16 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
191.17 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
191.18 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
191.19 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
191.20 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
191.21 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
191.22 + </AuxValues>
191.23 +
191.24 + <Layout>
191.25 + <DimensionLayout dim="0">
191.26 + <Group type="103" groupAlignment="0" attributes="0">
191.27 + <Group type="102" attributes="0">
191.28 + <Group type="103" groupAlignment="0" attributes="0">
191.29 + <Component id="formatImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
191.30 + <Component id="onePerLineCb" alignment="0" min="-2" max="-2" attributes="0"/>
191.31 + <Component id="systemLibsCb" alignment="0" min="-2" max="-2" attributes="0"/>
191.32 + <Component id="sortImportsCb" alignment="0" min="-2" max="-2" attributes="0"/>
191.33 + <Component id="sepFromImpCb" alignment="0" min="-2" max="-2" attributes="0"/>
191.34 + <Component id="removeDuplicateCb" alignment="0" min="-2" max="-2" attributes="0"/>
191.35 + <Component id="preferSymbols" alignment="0" min="-2" max="-2" attributes="0"/>
191.36 + <Group type="102" alignment="0" attributes="0">
191.37 + <Component id="cleanupLabel" min="-2" max="-2" attributes="0"/>
191.38 + <EmptySpace max="-2" attributes="0"/>
191.39 + <Component id="cleanupCombo" min="-2" max="-2" attributes="0"/>
191.40 + </Group>
191.41 + </Group>
191.42 + <EmptySpace max="32767" attributes="0"/>
191.43 + </Group>
191.44 + </Group>
191.45 + </DimensionLayout>
191.46 + <DimensionLayout dim="1">
191.47 + <Group type="103" groupAlignment="0" attributes="0">
191.48 + <Group type="102" alignment="0" attributes="0">
191.49 + <Component id="formatImportsCb" min="-2" max="-2" attributes="0"/>
191.50 + <EmptySpace type="separate" max="-2" attributes="0"/>
191.51 + <Component id="onePerLineCb" min="-2" max="-2" attributes="0"/>
191.52 + <EmptySpace max="-2" attributes="0"/>
191.53 + <Component id="systemLibsCb" min="-2" max="-2" attributes="0"/>
191.54 + <EmptySpace max="-2" attributes="0"/>
191.55 + <Component id="sortImportsCb" min="-2" max="-2" attributes="0"/>
191.56 + <EmptySpace max="-2" attributes="0"/>
191.57 + <Component id="sepFromImpCb" min="-2" max="-2" attributes="0"/>
191.58 + <EmptySpace max="-2" attributes="0"/>
191.59 + <Component id="removeDuplicateCb" min="-2" max="-2" attributes="0"/>
191.60 + <EmptySpace max="-2" attributes="0"/>
191.61 + <Component id="preferSymbols" min="-2" max="-2" attributes="0"/>
191.62 + <EmptySpace type="separate" max="-2" attributes="0"/>
191.63 + <Group type="103" groupAlignment="3" attributes="0">
191.64 + <Component id="cleanupLabel" alignment="3" min="-2" max="-2" attributes="0"/>
191.65 + <Component id="cleanupCombo" alignment="3" min="-2" max="-2" attributes="0"/>
191.66 + </Group>
191.67 + <EmptySpace max="32767" attributes="0"/>
191.68 + </Group>
191.69 + </Group>
191.70 + </DimensionLayout>
191.71 + </Layout>
191.72 + <SubComponents>
191.73 + <Component class="javax.swing.JCheckBox" name="formatImportsCb">
191.74 + <Properties>
191.75 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.76 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.formatImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.77 + </Property>
191.78 + </Properties>
191.79 + </Component>
191.80 + <Component class="javax.swing.JCheckBox" name="onePerLineCb">
191.81 + <Properties>
191.82 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.83 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.onePerLineCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.84 + </Property>
191.85 + </Properties>
191.86 + </Component>
191.87 + <Component class="javax.swing.JCheckBox" name="systemLibsCb">
191.88 + <Properties>
191.89 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.90 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.systemLibsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.91 + </Property>
191.92 + </Properties>
191.93 + </Component>
191.94 + <Component class="javax.swing.JCheckBox" name="removeDuplicateCb">
191.95 + <Properties>
191.96 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.97 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.removeDuplicateCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.98 + </Property>
191.99 + </Properties>
191.100 + </Component>
191.101 + <Component class="javax.swing.JLabel" name="cleanupLabel">
191.102 + <Properties>
191.103 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.104 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.cleanupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.105 + </Property>
191.106 + </Properties>
191.107 + </Component>
191.108 + <Component class="javax.swing.JComboBox" name="cleanupCombo">
191.109 + </Component>
191.110 + <Component class="javax.swing.JCheckBox" name="preferSymbols">
191.111 + <Properties>
191.112 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.113 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.preferSymbols.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.114 + </Property>
191.115 + </Properties>
191.116 + </Component>
191.117 + <Component class="javax.swing.JCheckBox" name="sortImportsCb">
191.118 + <Properties>
191.119 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.120 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sortImportsCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.121 + </Property>
191.122 + </Properties>
191.123 + </Component>
191.124 + <Component class="javax.swing.JCheckBox" name="sepFromImpCb">
191.125 + <Properties>
191.126 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
191.127 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtImports.sepFromImpCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
191.128 + </Property>
191.129 + </Properties>
191.130 + </Component>
191.131 + </SubComponents>
191.132 +</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/FmtImports.java Wed Sep 02 20:31:18 2015 +0200
192.3 @@ -0,0 +1,169 @@
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.options.editor.spi.PreferencesCustomizer;
192.51 +import static org.netbeans.modules.python.source.ui.FmtOptions.*;
192.52 +import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
192.53 +
192.54 +/**
192.55 + * Options related to imports
192.56 + *
192.57 + * @author Tor Norbye
192.58 + */
192.59 +public class FmtImports extends javax.swing.JPanel {
192.60 +
192.61 + /** Creates new form FmtImports */
192.62 + public FmtImports() {
192.63 + initComponents();
192.64 +
192.65 + formatImportsCb.putClientProperty(OPTION_ID, formatImports);
192.66 + onePerLineCb.putClientProperty(OPTION_ID, oneImportPerLine);
192.67 + removeDuplicateCb.putClientProperty(OPTION_ID, removeDuplicates);
192.68 + systemLibsCb.putClientProperty(OPTION_ID, systemLibsFirst);
192.69 + cleanupCombo.putClientProperty(OPTION_ID, cleanupUnusedImports);
192.70 + preferSymbols.putClientProperty(OPTION_ID, preferSymbolImports);
192.71 + sortImportsCb.putClientProperty(OPTION_ID, sortImports);
192.72 + sepFromImpCb.putClientProperty(OPTION_ID, separateFromImps);
192.73 + }
192.74 +
192.75 + public static PreferencesCustomizer.Factory getController() {
192.76 + return new CategorySupport.Factory("imports", FmtImports.class,
192.77 + org.openide.util.NbBundle.getMessage(FmtImports.class, "SAMPLE_Imports"));
192.78 + }
192.79 +
192.80 + /** This method is called from within the constructor to
192.81 + * initialize the form.
192.82 + * WARNING: Do NOT modify this code. The content of this method is
192.83 + * always regenerated by the Form Editor.
192.84 + */
192.85 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
192.86 + private void initComponents() {
192.87 +
192.88 + formatImportsCb = new javax.swing.JCheckBox();
192.89 + onePerLineCb = new javax.swing.JCheckBox();
192.90 + systemLibsCb = new javax.swing.JCheckBox();
192.91 + removeDuplicateCb = new javax.swing.JCheckBox();
192.92 + cleanupLabel = new javax.swing.JLabel();
192.93 + cleanupCombo = new javax.swing.JComboBox();
192.94 + preferSymbols = new javax.swing.JCheckBox();
192.95 + sortImportsCb = new javax.swing.JCheckBox();
192.96 + sepFromImpCb = new javax.swing.JCheckBox();
192.97 +
192.98 + setName(org.openide.util.NbBundle.getMessage(FmtImports.class, "LBL_Imports")); // NOI18N
192.99 +
192.100 + org.openide.awt.Mnemonics.setLocalizedText(formatImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.formatImportsCb.text")); // NOI18N
192.101 +
192.102 + org.openide.awt.Mnemonics.setLocalizedText(onePerLineCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.onePerLineCb.text")); // NOI18N
192.103 +
192.104 + org.openide.awt.Mnemonics.setLocalizedText(systemLibsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.systemLibsCb.text")); // NOI18N
192.105 +
192.106 + org.openide.awt.Mnemonics.setLocalizedText(removeDuplicateCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.removeDuplicateCb.text")); // NOI18N
192.107 +
192.108 + org.openide.awt.Mnemonics.setLocalizedText(cleanupLabel, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.cleanupLabel.text")); // NOI18N
192.109 +
192.110 + org.openide.awt.Mnemonics.setLocalizedText(preferSymbols, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.preferSymbols.text")); // NOI18N
192.111 +
192.112 + org.openide.awt.Mnemonics.setLocalizedText(sortImportsCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sortImportsCb.text")); // NOI18N
192.113 +
192.114 + org.openide.awt.Mnemonics.setLocalizedText(sepFromImpCb, org.openide.util.NbBundle.getMessage(FmtImports.class, "FmtImports.sepFromImpCb.text")); // NOI18N
192.115 +
192.116 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
192.117 + this.setLayout(layout);
192.118 + layout.setHorizontalGroup(
192.119 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.120 + .addGroup(layout.createSequentialGroup()
192.121 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.122 + .addComponent(formatImportsCb)
192.123 + .addComponent(onePerLineCb)
192.124 + .addComponent(systemLibsCb)
192.125 + .addComponent(sortImportsCb)
192.126 + .addComponent(sepFromImpCb)
192.127 + .addComponent(removeDuplicateCb)
192.128 + .addComponent(preferSymbols)
192.129 + .addGroup(layout.createSequentialGroup()
192.130 + .addComponent(cleanupLabel)
192.131 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.132 + .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
192.133 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
192.134 + );
192.135 + layout.setVerticalGroup(
192.136 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
192.137 + .addGroup(layout.createSequentialGroup()
192.138 + .addComponent(formatImportsCb)
192.139 + .addGap(18, 18, 18)
192.140 + .addComponent(onePerLineCb)
192.141 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.142 + .addComponent(systemLibsCb)
192.143 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.144 + .addComponent(sortImportsCb)
192.145 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.146 + .addComponent(sepFromImpCb)
192.147 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.148 + .addComponent(removeDuplicateCb)
192.149 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192.150 + .addComponent(preferSymbols)
192.151 + .addGap(18, 18, 18)
192.152 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
192.153 + .addComponent(cleanupLabel)
192.154 + .addComponent(cleanupCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
192.155 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
192.156 + );
192.157 + }// </editor-fold>//GEN-END:initComponents
192.158 +
192.159 +
192.160 + // Variables declaration - do not modify//GEN-BEGIN:variables
192.161 + private javax.swing.JComboBox cleanupCombo;
192.162 + private javax.swing.JLabel cleanupLabel;
192.163 + private javax.swing.JCheckBox formatImportsCb;
192.164 + private javax.swing.JCheckBox onePerLineCb;
192.165 + private javax.swing.JCheckBox preferSymbols;
192.166 + private javax.swing.JCheckBox removeDuplicateCb;
192.167 + private javax.swing.JCheckBox sepFromImpCb;
192.168 + private javax.swing.JCheckBox sortImportsCb;
192.169 + private javax.swing.JCheckBox systemLibsCb;
192.170 + // End of variables declaration//GEN-END:variables
192.171 +
192.172 +}
193.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
193.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtOptions.java Wed Sep 02 20:31:18 2015 +0200
193.3 @@ -0,0 +1,1036 @@
193.4 +/*
193.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
193.6 + *
193.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
193.8 + *
193.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
193.10 + * Other names may be trademarks of their respective owners.
193.11 + *
193.12 + * The contents of this file are subject to the terms of either the GNU
193.13 + * General Public License Version 2 only ("GPL") or the Common
193.14 + * Development and Distribution License("CDDL") (collectively, the
193.15 + * "License"). You may not use this file except in compliance with the
193.16 + * License. You can obtain a copy of the License at
193.17 + * http://www.netbeans.org/cddl-gplv2.html
193.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
193.19 + * specific language governing permissions and limitations under the
193.20 + * License. When distributing the software, include this License Header
193.21 + * Notice in each file and include the License file at
193.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
193.23 + * particular file as subject to the "Classpath" exception as provided
193.24 + * by Oracle in the GPL Version 2 section of the License file that
193.25 + * accompanied this code. If applicable, add the following below the
193.26 + * License Header, with the fields enclosed by brackets [] replaced by
193.27 + * your own identifying information:
193.28 + * "Portions Copyrighted [year] [name of copyright owner]"
193.29 + *
193.30 + * Contributor(s):
193.31 + *
193.32 + * The Original Software is NetBeans. The Initial Developer of the Original
193.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
193.34 + * Microsystems, Inc. All Rights Reserved.
193.35 + *
193.36 + * If you wish your version of this file to be governed by only the CDDL
193.37 + * or only the GPL Version 2, indicate your decision by adding
193.38 + * "[Contributor] elects to include this software in this distribution
193.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
193.40 + * single choice of license, a recipient has the option to distribute
193.41 + * your version of this file under either the CDDL, the GPL Version 2 or
193.42 + * to extend the choice of license to its licensees as provided above.
193.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
193.44 + * Version 2 license, then the option applies only if the new code is
193.45 + * made subject to such option by the copyright holder.
193.46 + */
193.47 +package org.netbeans.modules.python.source.ui;
193.48 +
193.49 +import org.netbeans.modules.python.source.CodeStyle;
193.50 +import java.awt.Component;
193.51 +import java.awt.Container;
193.52 +import java.awt.Rectangle;
193.53 +import java.awt.event.ActionEvent;
193.54 +import java.awt.event.ActionListener;
193.55 +import java.io.BufferedWriter;
193.56 +import java.io.File;
193.57 +import java.io.FileWriter;
193.58 +import java.io.IOException;
193.59 +import java.util.Arrays;
193.60 +import java.util.HashMap;
193.61 +import java.util.HashSet;
193.62 +import java.util.LinkedList;
193.63 +import java.util.List;
193.64 +import java.util.Map;
193.65 +import java.util.Set;
193.66 +import java.util.prefs.AbstractPreferences;
193.67 +import java.util.prefs.BackingStoreException;
193.68 +import java.util.prefs.Preferences;
193.69 +import javax.swing.ComboBoxModel;
193.70 +import javax.swing.DefaultComboBoxModel;
193.71 +import javax.swing.JCheckBox;
193.72 +import javax.swing.JComboBox;
193.73 +import javax.swing.JComponent;
193.74 +import javax.swing.JEditorPane;
193.75 +import javax.swing.JPanel;
193.76 +import javax.swing.JTextField;
193.77 +import javax.swing.event.DocumentEvent;
193.78 +import javax.swing.event.DocumentListener;
193.79 +import javax.swing.text.BadLocationException;
193.80 +import javax.swing.text.Document;
193.81 +import org.netbeans.api.editor.settings.SimpleValueNames;
193.82 +import static org.netbeans.modules.python.source.CodeStyle.*;
193.83 +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
193.84 +import org.netbeans.modules.options.editor.spi.PreviewProvider;
193.85 +import org.netbeans.modules.python.api.PythonMIMEResolver;
193.86 +import org.netbeans.modules.python.source.PythonFormatter;
193.87 +import org.netbeans.modules.python.source.PythonParserResult;
193.88 +import org.openide.cookies.SaveCookie;
193.89 +import org.openide.filesystems.FileObject;
193.90 +import org.openide.filesystems.FileUtil;
193.91 +import org.openide.loaders.DataObject;
193.92 +import org.openide.loaders.DataObjectNotFoundException;
193.93 +import org.openide.text.CloneableEditorSupport;
193.94 +import org.openide.util.Exceptions;
193.95 +import org.openide.util.HelpCtx;
193.96 +import org.openide.util.NbBundle;
193.97 +
193.98 +/**
193.99 + *
193.100 + * @author phrebejk
193.101 + */
193.102 +public class FmtOptions {
193.103 + public static final String expandTabToSpaces = SimpleValueNames.EXPAND_TABS;
193.104 + public static final String tabSize = SimpleValueNames.TAB_SIZE;
193.105 + public static final String spacesPerTab = SimpleValueNames.SPACES_PER_TAB;
193.106 + public static final String indentSize = SimpleValueNames.INDENT_SHIFT_WIDTH;
193.107 + public static final String continuationIndentSize = "continuationIndentSize"; //NOI18N
193.108 + public static final String labelIndent = "labelIndent"; //NOI18N
193.109 + public static final String absoluteLabelIndent = "absoluteLabelIndent"; //NOI18N
193.110 + public static final String indentTopLevelClassMembers = "indentTopLevelClassMembers"; //NOI18N
193.111 + public static final String indentCasesFromSwitch = "indentCasesFromSwitch"; //NOI18N
193.112 + public static final String rightMargin = SimpleValueNames.TEXT_LIMIT_WIDTH;
193.113 +
193.114 + /*
193.115 + public static final String addLeadingStarInComment = "addLeadingStarInComment"; //NOI18N
193.116 +
193.117 + public static final String preferLongerNames = "preferLongerNames"; //NOI18N
193.118 + public static final String fieldNamePrefix = "fieldNamePrefix"; //NOI18N
193.119 + public static final String fieldNameSuffix = "fieldNameSuffix"; //NOI18N
193.120 + public static final String staticFieldNamePrefix = "staticFieldNamePrefix"; //NOI18N
193.121 + public static final String staticFieldNameSuffix = "staticFieldNameSuffix"; //NOI18N
193.122 + public static final String parameterNamePrefix = "parameterNamePrefix"; //NOI18N
193.123 + public static final String parameterNameSuffix = "parameterNameSuffix"; //NOI18N
193.124 + public static final String localVarNamePrefix = "localVarNamePrefix"; //NOI18N
193.125 + public static final String localVarNameSuffix = "localVarNameSuffix"; //NOI18N
193.126 + public static final String qualifyFieldAccess = "qualifyFieldAccess"; //NOI18N
193.127 + public static final String useIsForBooleanGetters = "useIsForBooleanGetters"; //NOI18N
193.128 + public static final String addOverrideAnnotation = "addOverrideAnnotation"; //NOI18N
193.129 + public static final String makeLocalVarsFinal = "makeLocalVarsFinal"; //NOI18N
193.130 + public static final String makeParametersFinal = "makeParametersFinal"; //NOI18N
193.131 + public static final String classMembersOrder = "classMembersOrder"; //NOI18N
193.132 +
193.133 + public static final String alignMultilineMethodParams = "alignMultilineMethodParams"; //NOI18N
193.134 + public static final String alignMultilineCallArgs = "alignMultilineCallArgs"; //NOI18N
193.135 + public static final String alignMultilineAnnotationArgs = "alignMultilineAnnotationArgs"; //NOI18N
193.136 + public static final String alignMultilineImplements = "alignMultilineImplements"; //NOI18N
193.137 + public static final String alignMultilineThrows = "alignMultilineThrows"; //NOI18N
193.138 + public static final String alignMultilineParenthesized = "alignMultilineParenthesized"; //NOI18N
193.139 + public static final String alignMultilineBinaryOp = "alignMultilineBinaryOp"; //NOI18N
193.140 + public static final String alignMultilineTernaryOp = "alignMultilineTernaryOp"; //NOI18N
193.141 + public static final String alignMultilineAssignment = "alignMultilineAssignment"; //NOI18N
193.142 + public static final String alignMultilineFor = "alignMultilineFor"; //NOI18N
193.143 + public static final String alignMultilineArrayInit = "alignMultilineArrayInit"; //NOI18N
193.144 + public static final String placeElseOnNewLine = "placeElseOnNewLine"; //NOI18N
193.145 + public static final String placeWhileOnNewLine = "placeWhileOnNewLine"; //NOI18N
193.146 + public static final String placeCatchOnNewLine = "placeCatchOnNewLine"; //NOI18N
193.147 + public static final String placeFinallyOnNewLine = "placeFinallyOnNewLine"; //NOI18N
193.148 + public static final String placeNewLineAfterModifiers = "placeNewLineAfterModifiers"; //NOI18N
193.149 +
193.150 + public static final String wrapExtendsImplementsKeyword = "wrapExtendsImplementsKeyword"; //NOI18N
193.151 + public static final String wrapExtendsImplementsList = "wrapExtendsImplementsList"; //NOI18N
193.152 + public static final String wrapMethodParams = "wrapMethodParams"; //NOI18N
193.153 + public static final String wrapThrowsKeyword = "wrapThrowsKeyword"; //NOI18N
193.154 + public static final String wrapThrowsList = "wrapThrowsList"; //NOI18N
193.155 + public static final String wrapMethodCallArgs = "wrapMethodCallArgs"; //NOI18N
193.156 + public static final String wrapAnnotationArgs = "wrapAnnotationArgs"; //NOI18N
193.157 + public static final String wrapChainedMethodCalls = "wrapChainedMethodCalls"; //NOI18N
193.158 + public static final String wrapArrayInit = "wrapArrayInit"; //NOI18N
193.159 + public static final String wrapFor = "wrapFor"; //NOI18N
193.160 + public static final String wrapForStatement = "wrapForStatement"; //NOI18N
193.161 + public static final String wrapIfStatement = "wrapIfStatement"; //NOI18N
193.162 + public static final String wrapWhileStatement = "wrapWhileStatement"; //NOI18N
193.163 + public static final String wrapDoWhileStatement = "wrapDoWhileStatement"; //NOI18N
193.164 + public static final String wrapAssert = "wrapAssert"; //NOI18N
193.165 + public static final String wrapEnumConstants = "wrapEnumConstants"; //NOI18N
193.166 + public static final String wrapAnnotations = "wrapAnnotations"; //NOI18N
193.167 + public static final String wrapBinaryOps = "wrapBinaryOps"; //NOI18N
193.168 + public static final String wrapTernaryOps = "wrapTernaryOps"; //NOI18N
193.169 + public static final String wrapAssignOps = "wrapAssignOps"; //NOI18N
193.170 +
193.171 + public static final String blankLinesBeforePackage = "blankLinesBeforePackage"; //NOI18N
193.172 + public static final String blankLinesAfterPackage = "blankLinesAfterPackage"; //NOI18N
193.173 + public static final String blankLinesBeforeImports = "blankLinesBeforeImports"; //NOI18N
193.174 + public static final String blankLinesAfterImports = "blankLinesAfterImports"; //NOI18N
193.175 + public static final String blankLinesBeforeClass = "blankLinesBeforeClass"; //NOI18N
193.176 + public static final String blankLinesAfterClass = "blankLinesAfterClass"; //NOI18N
193.177 + public static final String blankLinesAfterClassHeader = "blankLinesAfterClassHeader"; //NOI18N
193.178 + public static final String blankLinesBeforeFields = "blankLinesBeforeFields"; //NOI18N
193.179 + public static final String blankLinesAfterFields = "blankLinesAfterFields"; //NOI18N
193.180 + public static final String blankLinesBeforeMethods = "blankLinesBeforeMethods"; //NOI18N
193.181 + public static final String blankLinesAfterMethods = "blankLinesAfterMethods"; //NOI18N
193.182 +
193.183 + public static final String spaceBeforeWhile = "spaceBeforeWhile"; //NOI18N
193.184 + public static final String spaceBeforeElse = "spaceBeforeElse"; //NOI18N
193.185 + public static final String spaceBeforeCatch = "spaceBeforeCatch"; //NOI18N
193.186 + public static final String spaceBeforeFinally = "spaceBeforeFinally"; //NOI18N
193.187 + public static final String spaceBeforeMethodDeclParen = "spaceBeforeMethodDeclParen"; //NOI18N
193.188 + public static final String spaceBeforeMethodCallParen = "spaceBeforeMethodCallParen"; //NOI18N
193.189 + public static final String spaceBeforeIfParen = "spaceBeforeIfParen"; //NOI18N
193.190 + public static final String spaceBeforeForParen = "spaceBeforeForParen"; //NOI18N
193.191 + public static final String spaceBeforeWhileParen = "spaceBeforeWhileParen"; //NOI18N
193.192 + public static final String spaceBeforeCatchParen = "spaceBeforeCatchParen"; //NOI18N
193.193 + public static final String spaceBeforeSwitchParen = "spaceBeforeSwitchParen"; //NOI18N
193.194 + public static final String spaceBeforeSynchronizedParen = "spaceBeforeSynchronizedParen"; //NOI18N
193.195 + public static final String spaceBeforeAnnotationParen = "spaceBeforeAnnotationParen"; //NOI18N
193.196 + public static final String spaceAroundUnaryOps = "spaceAroundUnaryOps"; //NOI18N
193.197 + public static final String spaceAroundBinaryOps = "spaceAroundBinaryOps"; //NOI18N
193.198 + public static final String spaceAroundTernaryOps = "spaceAroundTernaryOps"; //NOI18N
193.199 + public static final String spaceAroundAssignOps = "spaceAroundAssignOps"; //NOI18N
193.200 + public static final String spaceBeforeClassDeclLeftBrace = "spaceBeforeClassDeclLeftBrace"; //NOI18N
193.201 + public static final String spaceBeforeMethodDeclLeftBrace = "spaceBeforeMethodDeclLeftBrace"; //NOI18N
193.202 + public static final String spaceBeforeIfLeftBrace = "spaceBeforeIfLeftBrace"; //NOI18N
193.203 + public static final String spaceBeforeElseLeftBrace = "spaceBeforeElseLeftBrace"; //NOI18N
193.204 + public static final String spaceBeforeWhileLeftBrace = "spaceBeforeWhileLeftBrace"; //NOI18N
193.205 + public static final String spaceBeforeForLeftBrace = "spaceBeforeForLeftBrace"; //NOI18N
193.206 + public static final String spaceBeforeDoLeftBrace = "spaceBeforeDoLeftBrace"; //NOI18N
193.207 + public static final String spaceBeforeSwitchLeftBrace = "spaceBeforeSwitchLeftBrace"; //NOI18N
193.208 + public static final String spaceBeforeTryLeftBrace = "spaceBeforeTryLeftBrace"; //NOI18N
193.209 + public static final String spaceBeforeCatchLeftBrace = "spaceBeforeCatchLeftBrace"; //NOI18N
193.210 + public static final String spaceBeforeFinallyLeftBrace = "spaceBeforeFinallyLeftBrace"; //NOI18N
193.211 + public static final String spaceBeforeSynchronizedLeftBrace = "spaceBeforeSynchronizedLeftBrace"; //NOI18N
193.212 + public static final String spaceBeforeStaticInitLeftBrace = "spaceBeforeStaticInitLeftBrace"; //NOI18N
193.213 + public static final String spaceBeforeArrayInitLeftBrace = "spaceBeforeArrayInitLeftBrace"; //NOI18N
193.214 + public static final String spaceWithinParens = "spaceWithinParens"; //NOI18N
193.215 + public static final String spaceWithinMethodDeclParens = "spaceWithinMethodDeclParens"; //NOI18N
193.216 + public static final String spaceWithinMethodCallParens = "spaceWithinMethodCallParens"; //NOI18N
193.217 + public static final String spaceWithinIfParens = "spaceWithinIfParens"; //NOI18N
193.218 + public static final String spaceWithinForParens = "spaceWithinForParens"; //NOI18N
193.219 + public static final String spaceWithinWhileParens = "spaceWithinWhileParens"; //NOI18N
193.220 + public static final String spaceWithinSwitchParens = "spaceWithinSwitchParens"; //NOI18N
193.221 + public static final String spaceWithinCatchParens = "spaceWithinCatchParens"; //NOI18N
193.222 + public static final String spaceWithinSynchronizedParens = "spaceWithinSynchronizedParens"; //NOI18N
193.223 + public static final String spaceWithinTypeCastParens = "spaceWithinTypeCastParens"; //NOI18N
193.224 + public static final String spaceWithinAnnotationParens = "spaceWithinAnnotationParens"; //NOI18N
193.225 + public static final String spaceWithinBraces = "spaceWithinBraces"; //NOI18N
193.226 + public static final String spaceWithinArrayInitBrackets = "spaceWithinArrayInitBrackets"; //NOI18N
193.227 + public static final String spaceBeforeComma = "spaceBeforeComma"; //NOI18N
193.228 + public static final String spaceAfterComma = "spaceAfterComma"; //NOI18N
193.229 + public static final String spaceBeforeSemi = "spaceBeforeSemi"; //NOI18N
193.230 + public static final String spaceAfterSemi = "spaceAfterSemi"; //NOI18N
193.231 + public static final String spaceBeforeColon = "spaceBeforeColon"; //NOI18N
193.232 + public static final String spaceAfterColon = "spaceAfterColon"; //NOI18N
193.233 + public static final String spaceAfterTypeCast = "spaceAfterTypeCast"; //NOI18N
193.234 + */
193.235 +
193.236 + // Spaces
193.237 + public static final String addSpaceAroundOperators = "spaceAroundOperators"; //NOI18N
193.238 + public static final String removeSpaceInParens = "spaceInsideParens"; //NOI18N
193.239 + public static final String addSpaceAfterComma = "spaceAfterComma"; //NOI18N
193.240 + public static final String removeSpaceBeforeSep = "spaceBeforeSeparator"; //NOI18N
193.241 + public static final String removeSpaceInParamAssign = "spaceInKeywordAssign"; //NOI18N
193.242 + public static final String collapseSpaces = "collapseSpaces"; //NOI18N
193.243 + // Imports
193.244 + public static final String formatImports = "formatImports"; //NOI18N
193.245 + public static final String oneImportPerLine = "oneImportPerLine"; //NOI18N
193.246 + public static final String removeDuplicates = "removeDuplicates"; //NOI18N
193.247 + public static final String systemLibsFirst = "systemLibsFirst"; //NOI18N
193.248 + public static final String cleanupUnusedImports = "cleanupUnusedImports"; //NOI18N
193.249 + public static final String preferSymbolImports = "preferSymbolImports"; //NOI18N
193.250 + public static final String sortImports = "sortImports"; //NOI18N
193.251 + public static final String separateFromImps = "separateFromImps"; //NOI18N
193.252 + public static CodeStyleProducer codeStyleProducer;
193.253 + static final String CODE_STYLE_PROFILE = "CodeStyle"; // NOI18N
193.254 + static final String DEFAULT_PROFILE = "default"; // NOI18N
193.255 + static final String PROJECT_PROFILE = "project"; // NOI18N
193.256 + static final String usedProfile = "usedProfile"; // NOI18N
193.257 +
193.258 + private FmtOptions() {
193.259 + }
193.260 +
193.261 + public static int getDefaultAsInt(String key) {
193.262 + return Integer.parseInt(defaults.get(key));
193.263 + }
193.264 +
193.265 + public static boolean getDefaultAsBoolean(String key) {
193.266 + return Boolean.parseBoolean(defaults.get(key));
193.267 + }
193.268 +
193.269 + public static String getDefaultAsString(String key) {
193.270 + return defaults.get(key);
193.271 + }
193.272 +
193.273 + public static boolean isInteger(String optionID) {
193.274 + String value = defaults.get(optionID);
193.275 +
193.276 + try {
193.277 + Integer.parseInt(value);
193.278 + return true;
193.279 + } catch (NumberFormatException numberFormatException) {
193.280 + return false;
193.281 + }
193.282 + }
193.283 + // Private section ---------------------------------------------------------
193.284 + private static final String TRUE = "true"; // NOI18N
193.285 + private static final String FALSE = "false"; // NOI18N
193.286 + private static final String WRAP_ALWAYS = WrapStyle.WRAP_ALWAYS.name();
193.287 + //private static final String WRAP_IF_LONG = WrapStyle.WRAP_IF_LONG.name();
193.288 + private static final String WRAP_NEVER = WrapStyle.WRAP_NEVER.name();
193.289 +
193.290 + //private static final String CLEANUP_COMMENT = ImportCleanupStyle.COMMENT_OUT.name();
193.291 + private static final String IMP_LEAVE_ALONE = ImportCleanupStyle.LEAVE_ALONE.name();
193.292 + private static Map<String, String> defaults;
193.293 +
193.294 +
193.295 + static {
193.296 + createDefaults();
193.297 + }
193.298 +
193.299 + private static void createDefaults() {
193.300 + String defaultValues[][] = {
193.301 + {expandTabToSpaces, TRUE}, //NOI18N
193.302 + {tabSize, "4"}, //NOI18N
193.303 + {spacesPerTab, "4"}, //NOI18N
193.304 + {indentSize, "4"}, //NOI18N
193.305 + {continuationIndentSize, "8"}, //NOI18N
193.306 + {labelIndent, "0"}, //NOI18N
193.307 + {absoluteLabelIndent, FALSE}, //NOI18N
193.308 + {indentTopLevelClassMembers, TRUE}, //NOI18N
193.309 + {indentCasesFromSwitch, TRUE}, //NOI18N
193.310 + {rightMargin, "80"}, //NOI18N
193.311 +
193.312 + /*
193.313 + { addLeadingStarInComment, TRUE}, //NOI18N
193.314 +
193.315 + { preferLongerNames, TRUE}, //NOI18N
193.316 + { fieldNamePrefix, ""}, //NOI18N // XXX null
193.317 + { fieldNameSuffix, ""}, //NOI18N // XXX null
193.318 + { staticFieldNamePrefix, ""}, //NOI18N // XXX null
193.319 + { staticFieldNameSuffix, ""}, //NOI18N // XXX null
193.320 + { parameterNamePrefix, ""}, //NOI18N // XXX null
193.321 + { parameterNameSuffix, ""}, //NOI18N // XXX null
193.322 + { localVarNamePrefix, ""}, //NOI18N // XXX null
193.323 + { localVarNameSuffix, ""}, //NOI18N // XXX null
193.324 + { qualifyFieldAccess, FALSE}, //NOI18N // XXX
193.325 + { useIsForBooleanGetters, TRUE}, //NOI18N
193.326 + { addOverrideAnnotation, TRUE}, //NOI18N
193.327 + { makeLocalVarsFinal, FALSE}, //NOI18N
193.328 + { makeParametersFinal, FALSE}, //NOI18N
193.329 + { classMembersOrder, ""}, //NOI18N // XXX
193.330 +
193.331 + { alignMultilineMethodParams, FALSE}, //NOI18N
193.332 + { alignMultilineCallArgs, FALSE}, //NOI18N
193.333 + { alignMultilineAnnotationArgs, FALSE}, //NOI18N
193.334 + { alignMultilineImplements, FALSE}, //NOI18N
193.335 + { alignMultilineThrows, FALSE}, //NOI18N
193.336 + { alignMultilineParenthesized, FALSE}, //NOI18N
193.337 + { alignMultilineBinaryOp, FALSE}, //NOI18N
193.338 + { alignMultilineTernaryOp, FALSE}, //NOI18N
193.339 + { alignMultilineAssignment, FALSE}, //NOI18N
193.340 + { alignMultilineFor, FALSE}, //NOI18N
193.341 + { alignMultilineArrayInit, FALSE}, //NOI18N
193.342 + { placeElseOnNewLine, FALSE}, //NOI18N
193.343 + { placeWhileOnNewLine, FALSE}, //NOI18N
193.344 + { placeCatchOnNewLine, FALSE}, //NOI18N
193.345 + { placeFinallyOnNewLine, FALSE}, //NOI18N
193.346 + { placeNewLineAfterModifiers, FALSE}, //NOI18N
193.347 +
193.348 + { wrapExtendsImplementsKeyword, WRAP_NEVER}, //NOI18N
193.349 + { wrapExtendsImplementsList, WRAP_NEVER}, //NOI18N
193.350 + { wrapMethodParams, WRAP_NEVER}, //NOI18N
193.351 + { wrapThrowsKeyword, WRAP_NEVER}, //NOI18N
193.352 + { wrapThrowsList, WRAP_NEVER}, //NOI18N
193.353 + { wrapMethodCallArgs, WRAP_NEVER}, //NOI18N
193.354 + { wrapAnnotationArgs, WRAP_NEVER}, //NOI18N
193.355 + { wrapChainedMethodCalls, WRAP_NEVER}, //NOI18N
193.356 + { wrapArrayInit, WRAP_NEVER}, //NOI18N
193.357 + { wrapFor, WRAP_NEVER}, //NOI18N
193.358 + { wrapForStatement, WRAP_ALWAYS}, //NOI18N
193.359 + { wrapIfStatement, WRAP_ALWAYS}, //NOI18N
193.360 + { wrapWhileStatement, WRAP_ALWAYS}, //NOI18N
193.361 + { wrapDoWhileStatement, WRAP_ALWAYS}, //NOI18N
193.362 + { wrapAssert, WRAP_NEVER}, //NOI18N
193.363 + { wrapEnumConstants, WRAP_NEVER}, //NOI18N
193.364 + { wrapAnnotations, WRAP_ALWAYS}, //NOI18N
193.365 + { wrapBinaryOps, WRAP_NEVER}, //NOI18N
193.366 + { wrapTernaryOps, WRAP_NEVER}, //NOI18N
193.367 + { wrapAssignOps, WRAP_NEVER}, //NOI18N
193.368 +
193.369 + { blankLinesBeforePackage, "0"}, //NOI18N
193.370 + { blankLinesAfterPackage, "1"}, //NOI18N
193.371 + { blankLinesBeforeImports, "1"}, //NOI18N
193.372 + { blankLinesAfterImports, "1"}, //NOI18N
193.373 + { blankLinesBeforeClass, "1"}, //NOI18N
193.374 + { blankLinesAfterClass, "0"}, //NOI18N
193.375 + { blankLinesAfterClassHeader, "1"}, //NOI18N
193.376 + { blankLinesBeforeFields, "0"}, //NOI18N
193.377 + { blankLinesAfterFields, "0"}, //NOI18N
193.378 + { blankLinesBeforeMethods, "1"}, //NOI18N
193.379 + { blankLinesAfterMethods, "0"}, //NOI18N
193.380 +
193.381 + { spaceBeforeWhile, TRUE}, //NOI18N // XXX
193.382 + { spaceBeforeElse, TRUE}, //NOI18N // XXX
193.383 + { spaceBeforeCatch, TRUE}, //NOI18N // XXX
193.384 + { spaceBeforeFinally, TRUE}, //NOI18N // XXX
193.385 + { spaceBeforeMethodDeclParen, FALSE}, //NOI18N
193.386 + { spaceBeforeMethodCallParen, FALSE}, //NOI18N
193.387 + { spaceBeforeIfParen, TRUE}, //NOI18N
193.388 + { spaceBeforeForParen, TRUE}, //NOI18N
193.389 + { spaceBeforeWhileParen, TRUE}, //NOI18N
193.390 + { spaceBeforeCatchParen, TRUE}, //NOI18N
193.391 + { spaceBeforeSwitchParen, TRUE}, //NOI18N
193.392 + { spaceBeforeSynchronizedParen, TRUE}, //NOI18N
193.393 + { spaceBeforeAnnotationParen, FALSE}, //NOI18N
193.394 + { spaceAroundUnaryOps, FALSE}, //NOI18N
193.395 + { spaceAroundBinaryOps, TRUE}, //NOI18N
193.396 + { spaceAroundTernaryOps, TRUE}, //NOI18N
193.397 + { spaceAroundAssignOps, TRUE}, //NOI18N
193.398 + { spaceBeforeClassDeclLeftBrace, TRUE}, //NOI18N
193.399 + { spaceBeforeMethodDeclLeftBrace, TRUE}, //NOI18N
193.400 + { spaceBeforeIfLeftBrace, TRUE}, //NOI18N
193.401 + { spaceBeforeElseLeftBrace, TRUE}, //NOI18N
193.402 + { spaceBeforeWhileLeftBrace, TRUE}, //NOI18N
193.403 + { spaceBeforeForLeftBrace, TRUE}, //NOI18N
193.404 + { spaceBeforeDoLeftBrace, TRUE}, //NOI18N
193.405 + { spaceBeforeSwitchLeftBrace, TRUE}, //NOI18N
193.406 + { spaceBeforeTryLeftBrace, TRUE}, //NOI18N
193.407 + { spaceBeforeCatchLeftBrace, TRUE}, //NOI18N
193.408 + { spaceBeforeFinallyLeftBrace, TRUE}, //NOI18N
193.409 + { spaceBeforeSynchronizedLeftBrace, TRUE}, //NOI18N
193.410 + { spaceBeforeStaticInitLeftBrace, TRUE}, //NOI18N
193.411 + { spaceBeforeArrayInitLeftBrace, FALSE}, //NOI18N
193.412 + { spaceWithinParens, FALSE}, //NOI18N
193.413 + { spaceWithinMethodDeclParens, FALSE}, //NOI18N
193.414 + { spaceWithinMethodCallParens, FALSE}, //NOI18N
193.415 + { spaceWithinIfParens, FALSE}, //NOI18N
193.416 + { spaceWithinForParens, FALSE}, //NOI18N
193.417 + { spaceWithinWhileParens, FALSE}, //NOI18N
193.418 + { spaceWithinSwitchParens, FALSE}, //NOI18N
193.419 + { spaceWithinCatchParens, FALSE}, //NOI18N
193.420 + { spaceWithinSynchronizedParens, FALSE}, //NOI18N
193.421 + { spaceWithinTypeCastParens, FALSE}, //NOI18N
193.422 + { spaceWithinAnnotationParens, FALSE}, //NOI18N
193.423 + { spaceWithinBraces, FALSE}, //NOI18N
193.424 + { spaceWithinArrayInitBrackets, FALSE}, //NOI18N
193.425 + { spaceBeforeComma, FALSE}, //NOI18N
193.426 + { spaceAfterComma, TRUE}, //NOI18N
193.427 + { spaceBeforeSemi, FALSE}, //NOI18N
193.428 + { spaceAfterSemi, TRUE}, //NOI18N
193.429 + { spaceBeforeColon, TRUE}, //NOI18N
193.430 + { spaceAfterColon, TRUE}, //NOI18N
193.431 + { spaceAfterTypeCast, TRUE}, //NOI18N
193.432 + */
193.433 + // Spaces
193.434 + {addSpaceAroundOperators, TRUE},
193.435 + {removeSpaceInParens, TRUE},
193.436 + {addSpaceAfterComma, TRUE},
193.437 + {removeSpaceBeforeSep, TRUE},
193.438 + {removeSpaceInParamAssign, TRUE},
193.439 + {collapseSpaces, TRUE},
193.440 + // Imports
193.441 + {formatImports, TRUE},
193.442 + {oneImportPerLine, TRUE},
193.443 + {removeDuplicates, TRUE},
193.444 + {systemLibsFirst, TRUE},
193.445 + {preferSymbolImports, TRUE},
193.446 + {sortImports, TRUE},
193.447 + {cleanupUnusedImports, IMP_LEAVE_ALONE},
193.448 + {separateFromImps, FALSE},};
193.449 +
193.450 + defaults = new HashMap<>();
193.451 +
193.452 + for (java.lang.String[] strings : defaultValues) {
193.453 + defaults.put(strings[0], strings[1]);
193.454 + }
193.455 +
193.456 + }
193.457 +
193.458 + // Support section ---------------------------------------------------------
193.459 + public static class CategorySupport implements ActionListener, DocumentListener, PreviewProvider, PreferencesCustomizer {
193.460 + public static final String OPTION_ID = "org.netbeans.modules.python.editor.options.FormatingOptions.ID";
193.461 + private static final int LOAD = 0;
193.462 + private static final int STORE = 1;
193.463 + private static final int ADD_LISTENERS = 2;
193.464 + private static final ComboItem wrap[] = new ComboItem[]{
193.465 + new ComboItem(WrapStyle.WRAP_ALWAYS.name(), "LBL_wrp_WRAP_ALWAYS"), // NOI18N
193.466 + new ComboItem(WrapStyle.WRAP_IF_LONG.name(), "LBL_wrp_WRAP_IF_LONG"), // NOI18N
193.467 + new ComboItem(WrapStyle.WRAP_NEVER.name(), "LBL_wrp_WRAP_NEVER") // NOI18N
193.468 + };
193.469 + private static final ComboItem cleanupImports[] = new ComboItem[]{
193.470 + new ComboItem(ImportCleanupStyle.LEAVE_ALONE.name(), "LBL_imp_LEAVE_ALONE"), // NOI18N
193.471 + new ComboItem(ImportCleanupStyle.COMMENT_OUT.name(), "LBL_imp_COMMENT_OUT"), // NOI18N
193.472 + new ComboItem(ImportCleanupStyle.DELETE.name(), "LBL_imp_DELETE") // NOI18N
193.473 + };
193.474 + private final String previewText;
193.475 + private final String id;
193.476 + protected final JPanel panel;
193.477 + private final List<JComponent> components = new LinkedList<>();
193.478 + private JEditorPane previewPane;
193.479 + private final Preferences preferences;
193.480 + private final Preferences previewPrefs;
193.481 +
193.482 + protected CategorySupport(Preferences preferences, String id, JPanel panel, String previewText, String[]... forcedOptions) {
193.483 + this.preferences = preferences;
193.484 + this.id = id;
193.485 + this.panel = panel;
193.486 + this.previewText = previewText != null ? previewText : NbBundle.getMessage(FmtOptions.class, "SAMPLE_Default"); //NOI18N
193.487 +
193.488 + // Scan the panel for its components
193.489 + scan(panel, components);
193.490 +
193.491 + // Initialize the preview preferences
193.492 + Preferences forcedPrefs = new PreviewPreferences();
193.493 + for (String[] option : forcedOptions) {
193.494 + forcedPrefs.put(option[0], option[1]);
193.495 + }
193.496 + this.previewPrefs = new ProxyPreferences(preferences, forcedPrefs);
193.497 +
193.498 + // Load and hook up all the components
193.499 + loadFrom(preferences);
193.500 + addListeners();
193.501 + }
193.502 +
193.503 + protected void addListeners() {
193.504 + scan(ADD_LISTENERS, null);
193.505 + }
193.506 +
193.507 + protected void loadFrom(Preferences preferences) {
193.508 +// loaded = true;
193.509 + scan(LOAD, preferences);
193.510 +// loaded = false;
193.511 + }
193.512 +//
193.513 +// public void applyChanges() {
193.514 +// storeTo(preferences);
193.515 +// }
193.516 +//
193.517 +
193.518 + protected void storeTo(Preferences p) {
193.519 + scan(STORE, p);
193.520 + }
193.521 +
193.522 + protected void notifyChanged() {
193.523 +// if (loaded)
193.524 +// return;
193.525 + storeTo(preferences);
193.526 + refreshPreview();
193.527 + }
193.528 +
193.529 + // ActionListener implementation ---------------------------------------
193.530 + @Override
193.531 + public void actionPerformed(ActionEvent e) {
193.532 + notifyChanged();
193.533 + }
193.534 +
193.535 + // DocumentListener implementation -------------------------------------
193.536 + @Override
193.537 + public void insertUpdate(DocumentEvent e) {
193.538 + notifyChanged();
193.539 + }
193.540 +
193.541 + @Override
193.542 + public void removeUpdate(DocumentEvent e) {
193.543 + notifyChanged();
193.544 + }
193.545 +
193.546 + @Override
193.547 + public void changedUpdate(DocumentEvent e) {
193.548 + notifyChanged();
193.549 + }
193.550 +
193.551 + // PreviewProvider methods -----------------------------------------------------
193.552 + @Override
193.553 + public JComponent getPreviewComponent() {
193.554 + if (previewPane == null) {
193.555 + previewPane = new JEditorPane();
193.556 + previewPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtOptions.class, "AN_Preview")); //NOI18N
193.557 + previewPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtOptions.class, "AD_Preview")); //NOI18N
193.558 + previewPane.putClientProperty("HighlightsLayerIncludes", "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.SyntaxHighlighting$"); //NOI18N
193.559 + previewPane.setEditorKit(CloneableEditorSupport.getEditorKit(PythonMIMEResolver.PYTHON_MIME_TYPE));
193.560 + previewPane.setEditable(false);
193.561 + }
193.562 + return previewPane;
193.563 + }
193.564 +
193.565 + @Override
193.566 + public void refreshPreview() {
193.567 + JEditorPane jep = (JEditorPane)getPreviewComponent();
193.568 + try {
193.569 + int rm = previewPrefs.getInt(rightMargin, getDefaultAsInt(rightMargin));
193.570 + jep.putClientProperty("TextLimitLine", rm); //NOI18N
193.571 + } catch (NumberFormatException e) {
193.572 + // Ignore it
193.573 + }
193.574 + try {
193.575 + Class.forName(CodeStyle.class.getName(), true, CodeStyle.class.getClassLoader());
193.576 + } catch (ClassNotFoundException cnfe) {
193.577 + // ignore
193.578 + }
193.579 +
193.580 + CodeStyle codeStyle = codeStyleProducer.create(previewPrefs);
193.581 + jep.setIgnoreRepaint(true);
193.582 +
193.583 +// if (jep.getDocument() instanceof BaseDocument) {
193.584 +// BaseDocument document = (BaseDocument) jep.getDocument();
193.585 +// final org.netbeans.editor.Formatter f = document.getFormatter();
193.586 +// try {
193.587 +// f.reformatLock();
193.588 +// try {
193.589 +// int reformattedLen = f.reformat(document, 0, document.getLength());
193.590 +// } catch (BadLocationException ex) {
193.591 +// Exceptions.printStackTrace(ex);
193.592 +// }
193.593 +// } finally {
193.594 +// f.reformatUnlock();
193.595 +// }
193.596 +// }
193.597 +
193.598 + // Hacky code to do preview: We want to preview blank text without
193.599 + // a data object... this doesn't work very well so requires some hacks
193.600 + // to create a temp file, format it, then save it and delete it
193.601 + // (to avoid save confirmation dialogs on the modified file etc)
193.602 + PythonFormatter formatter = new PythonFormatter(codeStyle);
193.603 + PythonParserResult info = null;
193.604 + File tmp = null;
193.605 + FileObject tmpFo = null;
193.606 + if (formatter.needsParserResult()) {
193.607 + try {
193.608 + tmp = File.createTempFile("preview", ".py"); // NOI18N
193.609 + BufferedWriter writer = new BufferedWriter(new FileWriter(tmp));
193.610 + writer.write(previewText);
193.611 + writer.close();
193.612 + final FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(tmp));
193.613 + tmpFo = fo;
193.614 + // TODO - I need to get the classpath involved here such that it can
193.615 + // find used/unused libraries
193.616 +// if (!SourceUtils.isScanInProgress()) {
193.617 +// // I'm using custom GSF code here because I want to set up an explicit
193.618 +// // source path for the fake file object which includes the Python
193.619 +// // libraries (since we need them for the isSystemModule lookup
193.620 +// //SourceModel model = SourceModelFactory.getInstance().getModel(fo);
193.621 +// //if (model != null && !model.isScanInProgress()) {
193.622 +// List<FileObject> roots = new ArrayList<FileObject>(new PythonLanguage().getCoreLibraries());
193.623 +//
193.624 +// final PythonPlatformManager manager = PythonPlatformManager.getInstance();
193.625 +// final String platformName = manager.getDefaultPlatform();
193.626 +// PythonPlatform activePlatform = manager.getPlatform(platformName);
193.627 +// if (activePlatform != null) {
193.628 +// roots.addAll(activePlatform.getUniqueLibraryRoots());
193.629 +// ClassPath boot = ClassPathSupport.createClassPath(roots.toArray(new FileObject[roots.size()]));
193.630 +// ClassPath source = ClassPathSupport.createClassPath(new FileObject[]{fo.getParent()});
193.631 +// ClassPath compile = source;
193.632 +//
193.633 +// ClasspathInfo cpInfo = ClasspathInfo.create(boot, compile, source);
193.634 +// Source model = Source.create(cpInfo, fo);
193.635 +// if (model != null) {
193.636 +// final CompilationInfo[] infoHolder = new CompilationInfo[1];
193.637 +// //model.runUserActionTask(new CancellableTask<CompilationInfo>() {
193.638 +// model.runUserActionTask(new CancellableTask<CompilationController>() {
193.639 +// public void cancel() {
193.640 +// }
193.641 +//
193.642 +// //public void run(CompilationInfo info) throws Exception {
193.643 +// public void run(CompilationController info) throws Exception {
193.644 +// info.toPhase(Phase.RESOLVED);
193.645 +// infoHolder[0] = info;
193.646 +// // Force open so info.getFileObject will succeed
193.647 +// GsfUtilities.getDocument(fo, true);
193.648 +// }
193.649 +// }, false);
193.650 +// info = infoHolder[0];
193.651 +// }
193.652 +// }
193.653 +// }
193.654 + } catch (IOException ex) {
193.655 + Exceptions.printStackTrace(ex);
193.656 + }
193.657 + }
193.658 + try {
193.659 + if (info != null && info.getSnapshot().getSource().getDocument(false) != null) {
193.660 + Document doc = info.getSnapshot().getSource().getDocument(false);
193.661 + formatter.reformat(null, doc, 0, doc.getLength(), info);
193.662 + jep.setText(doc.getText(0, doc.getLength()));
193.663 + // Save file to avoid warning on exit
193.664 + DataObject dobj = DataObject.find(info.getSnapshot().getSource().getFileObject());
193.665 + SaveCookie cookie = dobj.getCookie(SaveCookie.class);
193.666 + if (cookie != null) {
193.667 + cookie.save();
193.668 + }
193.669 + } else {
193.670 + Document doc = jep.getDocument();
193.671 + if (doc.getLength() > 0) {
193.672 + doc.remove(0, doc.getLength());
193.673 + }
193.674 + doc.insertString(0, previewText, null);
193.675 + formatter.reformat(null, doc, 0, doc.getLength(), null);
193.676 + jep.setText(doc.getText(0, doc.getLength()));
193.677 + }
193.678 + } catch (DataObjectNotFoundException dof) {
193.679 + Exceptions.printStackTrace(dof);
193.680 + } catch (IOException | BadLocationException ioe) {
193.681 + Exceptions.printStackTrace(ioe);
193.682 + }
193.683 +
193.684 + if (tmpFo != null) {
193.685 + try {
193.686 + tmpFo.delete();
193.687 + } catch (IOException ex) {
193.688 + Exceptions.printStackTrace(ex);
193.689 + }
193.690 + } else if (tmp != null) {
193.691 + tmp.delete();
193.692 + }
193.693 +
193.694 +
193.695 + jep.setIgnoreRepaint(false);
193.696 + jep.scrollRectToVisible(new Rectangle(0, 0, 10, 10));
193.697 + jep.repaint(100);
193.698 + }
193.699 +
193.700 + // PreferencesCustomizer implementation --------------------------------
193.701 + @Override
193.702 + public JComponent getComponent() {
193.703 + return panel;
193.704 + }
193.705 +
193.706 + @Override
193.707 + public String getDisplayName() {
193.708 + return panel.getName();
193.709 + }
193.710 +
193.711 + @Override
193.712 + public String getId() {
193.713 + return id;
193.714 + }
193.715 +
193.716 + @Override
193.717 + public HelpCtx getHelpCtx() {
193.718 + return null;
193.719 + }
193.720 +
193.721 + // PreferencesCustomizer.Factory implementation ------------------------
193.722 + public static final class Factory implements PreferencesCustomizer.Factory {
193.723 + private final String id;
193.724 + private final Class<? extends JPanel> panelClass;
193.725 + private final String previewText;
193.726 + private final String[][] forcedOptions;
193.727 +
193.728 + public Factory(String id, Class<? extends JPanel> panelClass, String previewText, String[]... forcedOptions) {
193.729 + this.id = id;
193.730 + this.panelClass = panelClass;
193.731 + this.previewText = previewText;
193.732 + this.forcedOptions = forcedOptions;
193.733 + }
193.734 +
193.735 + @Override
193.736 + public PreferencesCustomizer create(Preferences preferences) {
193.737 + try {
193.738 + return new CategorySupport(preferences, id, panelClass.newInstance(), previewText, forcedOptions);
193.739 + } catch (IllegalAccessException | InstantiationException e) {
193.740 + return null;
193.741 + }
193.742 + }
193.743 + } // End of CategorySupport.Factory class
193.744 +
193.745 + // Private methods -----------------------------------------------------
193.746 + private void performOperation(int operation, JComponent jc, String optionID, Preferences p) {
193.747 + switch (operation) {
193.748 + case LOAD:
193.749 + loadData(jc, optionID, p);
193.750 + break;
193.751 + case STORE:
193.752 + storeData(jc, optionID, p);
193.753 + break;
193.754 + case ADD_LISTENERS:
193.755 + addListener(jc);
193.756 + break;
193.757 + }
193.758 + }
193.759 +
193.760 + private void scan(int what, Preferences p) {
193.761 + for (JComponent jc : components) {
193.762 + Object o = jc.getClientProperty(OPTION_ID);
193.763 + if (o instanceof String) {
193.764 + performOperation(what, jc, (String)o, p);
193.765 + } else if (o instanceof String[]) {
193.766 + for (String oid : (String[])o) {
193.767 + performOperation(what, jc, oid, p);
193.768 + }
193.769 + }
193.770 + }
193.771 + }
193.772 +
193.773 + private void scan(Container container, List<JComponent> components) {
193.774 + for (Component c : container.getComponents()) {
193.775 + if (c instanceof JComponent) {
193.776 + JComponent jc = (JComponent)c;
193.777 + Object o = jc.getClientProperty(OPTION_ID);
193.778 + if (o instanceof String || o instanceof String[]) {
193.779 + components.add(jc);
193.780 + }
193.781 + }
193.782 + if (c instanceof Container) {
193.783 + scan((Container)c, components);
193.784 + }
193.785 + }
193.786 + }
193.787 +
193.788 + /** Very smart method which tries to set the values in the components correctly
193.789 + */
193.790 + private void loadData(JComponent jc, String optionID, Preferences node) {
193.791 +
193.792 + if (jc instanceof JTextField) {
193.793 + JTextField field = (JTextField)jc;
193.794 + field.setText(node.get(optionID, getDefaultAsString(optionID)));
193.795 + } else if (jc instanceof JCheckBox) {
193.796 + JCheckBox checkBox = (JCheckBox)jc;
193.797 + boolean df = getDefaultAsBoolean(optionID);
193.798 + checkBox.setSelected(node.getBoolean(optionID, df));
193.799 + } else if (jc instanceof JComboBox) {
193.800 + JComboBox cb = (JComboBox)jc;
193.801 + String value = node.get(optionID, getDefaultAsString(optionID));
193.802 + ComboBoxModel model = createModel(value);
193.803 + cb.setModel(model);
193.804 + ComboItem item = whichItem(value, model);
193.805 + cb.setSelectedItem(item);
193.806 + }
193.807 +
193.808 + }
193.809 +
193.810 + private void storeData(JComponent jc, String optionID, Preferences node) {
193.811 +
193.812 + if (jc instanceof JTextField) {
193.813 + JTextField field = (JTextField)jc;
193.814 +
193.815 + String text = field.getText();
193.816 +
193.817 + // XXX test for numbers
193.818 + if (isInteger(optionID)) {
193.819 + try {
193.820 + int i = Integer.parseInt(text);
193.821 + } catch (NumberFormatException e) {
193.822 + return;
193.823 + }
193.824 + }
193.825 +
193.826 + // XXX: watch out, tabSize, spacesPerTab, indentSize and expandTabToSpaces
193.827 + // fall back on getGlopalXXX() values and not getDefaultAsXXX value,
193.828 + // which is why we must not remove them. Proper solution would be to
193.829 + // store formatting preferences to MimeLookup and not use NbPreferences.
193.830 + // The problem currently is that MimeLookup based Preferences do not support subnodes.
193.831 + if (!optionID.equals(tabSize) &&
193.832 + !optionID.equals(spacesPerTab) && !optionID.equals(indentSize) &&
193.833 + getDefaultAsString(optionID).equals(text)) {
193.834 + node.remove(optionID);
193.835 + } else {
193.836 + node.put(optionID, text);
193.837 + }
193.838 + } else if (jc instanceof JCheckBox) {
193.839 + JCheckBox checkBox = (JCheckBox)jc;
193.840 + if (!optionID.equals(expandTabToSpaces) && getDefaultAsBoolean(optionID) == checkBox.isSelected()) {
193.841 + node.remove(optionID);
193.842 + } else {
193.843 + node.putBoolean(optionID, checkBox.isSelected());
193.844 + }
193.845 + } else if (jc instanceof JComboBox) {
193.846 + JComboBox cb = (JComboBox)jc;
193.847 + // Logger.global.info( cb.getSelectedItem() + " " + optionID);
193.848 + String value = ((ComboItem)cb.getSelectedItem()).value;
193.849 + if (getDefaultAsString(optionID).equals(value)) {
193.850 + node.remove(optionID);
193.851 + } else {
193.852 + node.put(optionID, value);
193.853 + }
193.854 + }
193.855 + }
193.856 +
193.857 + private void addListener(JComponent jc) {
193.858 + if (jc instanceof JTextField) {
193.859 + JTextField field = (JTextField)jc;
193.860 + field.addActionListener(this);
193.861 + field.getDocument().addDocumentListener(this);
193.862 + } else if (jc instanceof JCheckBox) {
193.863 + JCheckBox checkBox = (JCheckBox)jc;
193.864 + checkBox.addActionListener(this);
193.865 + } else if (jc instanceof JComboBox) {
193.866 + JComboBox cb = (JComboBox)jc;
193.867 + cb.addActionListener(this);
193.868 + }
193.869 + }
193.870 +
193.871 + private ComboBoxModel createModel(String value) {
193.872 +
193.873 + // is it imports?
193.874 + for (ComboItem comboItem : cleanupImports) {
193.875 + if (value.equals(comboItem.value)) {
193.876 + return new DefaultComboBoxModel(cleanupImports);
193.877 + }
193.878 + }
193.879 +
193.880 + // is it wrap
193.881 + for (ComboItem comboItem : wrap) {
193.882 + if (value.equals(comboItem.value)) {
193.883 + return new DefaultComboBoxModel(wrap);
193.884 + }
193.885 + }
193.886 +
193.887 + return null;
193.888 + }
193.889 +
193.890 + private static ComboItem whichItem(String value, ComboBoxModel model) {
193.891 +
193.892 + for (int i = 0; i < model.getSize(); i++) {
193.893 + ComboItem item = (ComboItem)model.getElementAt(i);
193.894 + if (value.equals(item.value)) {
193.895 + return item;
193.896 + }
193.897 + }
193.898 + return null;
193.899 + }
193.900 +
193.901 + private static class ComboItem {
193.902 + String value;
193.903 + String displayName;
193.904 +
193.905 + public ComboItem(String value, String key) {
193.906 + this.value = value;
193.907 + this.displayName = NbBundle.getMessage(FmtOptions.class, key);
193.908 + }
193.909 +
193.910 + @Override
193.911 + public String toString() {
193.912 + return displayName;
193.913 + }
193.914 + }
193.915 + }
193.916 +
193.917 + public static class PreviewPreferences extends AbstractPreferences {
193.918 + private Map<String, Object> map = new HashMap<>();
193.919 +
193.920 + public PreviewPreferences() {
193.921 + super(null, ""); // NOI18N
193.922 + }
193.923 +
193.924 + @Override
193.925 + protected void putSpi(String key, String value) {
193.926 + map.put(key, value);
193.927 + }
193.928 +
193.929 + @Override
193.930 + protected String getSpi(String key) {
193.931 + return (String)map.get(key);
193.932 + }
193.933 +
193.934 + @Override
193.935 + protected void removeSpi(String key) {
193.936 + map.remove(key);
193.937 + }
193.938 +
193.939 + @Override
193.940 + protected void removeNodeSpi() throws BackingStoreException {
193.941 + throw new UnsupportedOperationException("Not supported yet.");
193.942 + }
193.943 +
193.944 + @Override
193.945 + protected String[] keysSpi() throws BackingStoreException {
193.946 + String array[] = new String[map.keySet().size()];
193.947 + return map.keySet().toArray(array);
193.948 + }
193.949 +
193.950 + @Override
193.951 + protected String[] childrenNamesSpi() throws BackingStoreException {
193.952 + throw new UnsupportedOperationException("Not supported yet.");
193.953 + }
193.954 +
193.955 + @Override
193.956 + protected AbstractPreferences childSpi(String name) {
193.957 + throw new UnsupportedOperationException("Not supported yet.");
193.958 + }
193.959 +
193.960 + @Override
193.961 + protected void syncSpi() throws BackingStoreException {
193.962 + throw new UnsupportedOperationException("Not supported yet.");
193.963 + }
193.964 +
193.965 + @Override
193.966 + protected void flushSpi() throws BackingStoreException {
193.967 + throw new UnsupportedOperationException("Not supported yet.");
193.968 + }
193.969 + }
193.970 +
193.971 + // read-only, no subnodes
193.972 + public static final class ProxyPreferences extends AbstractPreferences {
193.973 + private final Preferences[] delegates;
193.974 +
193.975 + public ProxyPreferences(Preferences... delegates) {
193.976 + super(null, ""); // NOI18N
193.977 + this.delegates = delegates;
193.978 + }
193.979 +
193.980 + @Override
193.981 + protected void putSpi(String key, String value) {
193.982 + throw new UnsupportedOperationException("Not supported yet.");
193.983 + }
193.984 +
193.985 + @Override
193.986 + protected String getSpi(String key) {
193.987 + for (Preferences p : delegates) {
193.988 + String value = p.get(key, null);
193.989 + if (value != null) {
193.990 + return value;
193.991 + }
193.992 + }
193.993 + return null;
193.994 + }
193.995 +
193.996 + @Override
193.997 + protected void removeSpi(String key) {
193.998 + throw new UnsupportedOperationException("Not supported yet.");
193.999 + }
193.1000 +
193.1001 + @Override
193.1002 + protected void removeNodeSpi() throws BackingStoreException {
193.1003 + throw new UnsupportedOperationException("Not supported yet.");
193.1004 + }
193.1005 +
193.1006 + @Override
193.1007 + protected String[] keysSpi() throws BackingStoreException {
193.1008 + Set<String> keys = new HashSet<>();
193.1009 + for (Preferences p : delegates) {
193.1010 + keys.addAll(Arrays.asList(p.keys()));
193.1011 + }
193.1012 + return keys.toArray(new String[keys.size()]);
193.1013 + }
193.1014 +
193.1015 + @Override
193.1016 + protected String[] childrenNamesSpi() throws BackingStoreException {
193.1017 + throw new UnsupportedOperationException("Not supported yet.");
193.1018 + }
193.1019 +
193.1020 + @Override
193.1021 + protected AbstractPreferences childSpi(String name) {
193.1022 + throw new UnsupportedOperationException("Not supported yet.");
193.1023 + }
193.1024 +
193.1025 + @Override
193.1026 + protected void syncSpi() throws BackingStoreException {
193.1027 + throw new UnsupportedOperationException("Not supported yet.");
193.1028 + }
193.1029 +
193.1030 + @Override
193.1031 + protected void flushSpi() throws BackingStoreException {
193.1032 + throw new UnsupportedOperationException("Not supported yet.");
193.1033 + }
193.1034 + } // End of ProxyPreferences class
193.1035 +
193.1036 + public static interface CodeStyleProducer {
193.1037 + public CodeStyle create(Preferences preferences);
193.1038 + }
193.1039 +}
194.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
194.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtSpaces.form Wed Sep 02 20:31:18 2015 +0200
194.3 @@ -0,0 +1,104 @@
194.4 +<?xml version="1.0" encoding="UTF-8" ?>
194.5 +
194.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
194.7 + <Properties>
194.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_Spaces" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.10 + </Property>
194.11 + <Property name="opaque" type="boolean" value="false"/>
194.12 + </Properties>
194.13 + <AuxValues>
194.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
194.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
194.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
194.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
194.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
194.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
194.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
194.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
194.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
194.23 + </AuxValues>
194.24 +
194.25 + <Layout>
194.26 + <DimensionLayout dim="0">
194.27 + <Group type="103" groupAlignment="0" attributes="0">
194.28 + <Group type="102" attributes="0">
194.29 + <Group type="103" groupAlignment="0" attributes="0">
194.30 + <Component id="addAroundOp" alignment="0" min="-2" max="-2" attributes="0"/>
194.31 + <Group type="102" alignment="0" attributes="0">
194.32 + <EmptySpace min="27" pref="27" max="27" attributes="0"/>
194.33 + <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
194.34 + </Group>
194.35 + <Component id="removeInParen" alignment="0" min="-2" max="-2" attributes="0"/>
194.36 + <Component id="addAfterComma" alignment="0" min="-2" max="-2" attributes="0"/>
194.37 + <Component id="removeBeforeSep" alignment="0" min="-2" max="-2" attributes="0"/>
194.38 + <Component id="collapseSpacesCb" alignment="0" min="-2" max="-2" attributes="0"/>
194.39 + </Group>
194.40 + <EmptySpace max="32767" attributes="0"/>
194.41 + </Group>
194.42 + </Group>
194.43 + </DimensionLayout>
194.44 + <DimensionLayout dim="1">
194.45 + <Group type="103" groupAlignment="0" attributes="0">
194.46 + <Group type="102" alignment="0" attributes="0">
194.47 + <Component id="addAroundOp" min="-2" max="-2" attributes="0"/>
194.48 + <EmptySpace max="-2" attributes="0"/>
194.49 + <Component id="removeInParam" min="-2" max="-2" attributes="0"/>
194.50 + <EmptySpace max="-2" attributes="0"/>
194.51 + <Component id="removeInParen" min="-2" max="-2" attributes="0"/>
194.52 + <EmptySpace max="-2" attributes="0"/>
194.53 + <Component id="addAfterComma" min="-2" max="-2" attributes="0"/>
194.54 + <EmptySpace max="-2" attributes="0"/>
194.55 + <Component id="removeBeforeSep" min="-2" max="-2" attributes="0"/>
194.56 + <EmptySpace max="-2" attributes="0"/>
194.57 + <Component id="collapseSpacesCb" min="-2" max="-2" attributes="0"/>
194.58 + <EmptySpace max="32767" attributes="0"/>
194.59 + </Group>
194.60 + </Group>
194.61 + </DimensionLayout>
194.62 + </Layout>
194.63 + <SubComponents>
194.64 + <Component class="javax.swing.JCheckBox" name="addAroundOp">
194.65 + <Properties>
194.66 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.67 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAroundOp.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.68 + </Property>
194.69 + </Properties>
194.70 + </Component>
194.71 + <Component class="javax.swing.JCheckBox" name="removeInParam">
194.72 + <Properties>
194.73 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.74 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParam.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.75 + </Property>
194.76 + </Properties>
194.77 + </Component>
194.78 + <Component class="javax.swing.JCheckBox" name="removeInParen">
194.79 + <Properties>
194.80 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.81 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeInParen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.82 + </Property>
194.83 + </Properties>
194.84 + </Component>
194.85 + <Component class="javax.swing.JCheckBox" name="addAfterComma">
194.86 + <Properties>
194.87 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.88 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.addAfterComma.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.89 + </Property>
194.90 + </Properties>
194.91 + </Component>
194.92 + <Component class="javax.swing.JCheckBox" name="removeBeforeSep">
194.93 + <Properties>
194.94 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.95 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.removeBeforeSep.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.96 + </Property>
194.97 + </Properties>
194.98 + </Component>
194.99 + <Component class="javax.swing.JCheckBox" name="collapseSpacesCb">
194.100 + <Properties>
194.101 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
194.102 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="FmtSpaces.collapseSpacesCb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
194.103 + </Property>
194.104 + </Properties>
194.105 + </Component>
194.106 + </SubComponents>
194.107 +</Form>
195.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
195.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtSpaces.java Wed Sep 02 20:31:18 2015 +0200
195.3 @@ -0,0 +1,143 @@
195.4 +/*
195.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
195.6 + *
195.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
195.8 + *
195.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
195.10 + * Other names may be trademarks of their respective owners.
195.11 + *
195.12 + * The contents of this file are subject to the terms of either the GNU
195.13 + * General Public License Version 2 only ("GPL") or the Common
195.14 + * Development and Distribution License("CDDL") (collectively, the
195.15 + * "License"). You may not use this file except in compliance with the
195.16 + * License. You can obtain a copy of the License at
195.17 + * http://www.netbeans.org/cddl-gplv2.html
195.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
195.19 + * specific language governing permissions and limitations under the
195.20 + * License. When distributing the software, include this License Header
195.21 + * Notice in each file and include the License file at
195.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
195.23 + * particular file as subject to the "Classpath" exception as provided
195.24 + * by Oracle in the GPL Version 2 section of the License file that
195.25 + * accompanied this code. If applicable, add the following below the
195.26 + * License Header, with the fields enclosed by brackets [] replaced by
195.27 + * your own identifying information:
195.28 + * "Portions Copyrighted [year] [name of copyright owner]"
195.29 + *
195.30 + * Contributor(s):
195.31 + *
195.32 + * The Original Software is NetBeans. The Initial Developer of the Original
195.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
195.34 + * Microsystems, Inc. All Rights Reserved.
195.35 + *
195.36 + * If you wish your version of this file to be governed by only the CDDL
195.37 + * or only the GPL Version 2, indicate your decision by adding
195.38 + * "[Contributor] elects to include this software in this distribution
195.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
195.40 + * single choice of license, a recipient has the option to distribute
195.41 + * your version of this file under either the CDDL, the GPL Version 2 or
195.42 + * to extend the choice of license to its licensees as provided above.
195.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
195.44 + * Version 2 license, then the option applies only if the new code is
195.45 + * made subject to such option by the copyright holder.
195.46 + */
195.47 +
195.48 +package org.netbeans.modules.python.source.ui;
195.49 +
195.50 +import javax.swing.JPanel;
195.51 +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
195.52 +import static org.netbeans.modules.python.source.ui.FmtOptions.*;
195.53 +import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
195.54 +
195.55 +/**
195.56 + * Preferences for formatting related to spaces
195.57 + *
195.58 + * @author Tor Norbye
195.59 + */
195.60 +public class FmtSpaces extends JPanel {
195.61 + public FmtSpaces() {
195.62 + initComponents();
195.63 +
195.64 + addAroundOp.putClientProperty(OPTION_ID, addSpaceAroundOperators);
195.65 + addAfterComma.putClientProperty(OPTION_ID, addSpaceAfterComma);
195.66 + removeBeforeSep.putClientProperty(OPTION_ID, removeSpaceBeforeSep);
195.67 + removeInParam.putClientProperty(OPTION_ID, removeSpaceInParamAssign);
195.68 + removeInParen.putClientProperty(OPTION_ID, removeSpaceInParens);
195.69 + collapseSpacesCb.putClientProperty(OPTION_ID, collapseSpaces);
195.70 + }
195.71 +
195.72 + public static PreferencesCustomizer.Factory getController() {
195.73 + return new CategorySupport.Factory("spaces", FmtSpaces.class, // NOI18N
195.74 + org.openide.util.NbBundle.getMessage(FmtSpaces.class, "SAMPLE_Spaces"));
195.75 + }
195.76 +
195.77 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
195.78 + private void initComponents() {
195.79 +
195.80 + addAroundOp = new javax.swing.JCheckBox();
195.81 + removeInParam = new javax.swing.JCheckBox();
195.82 + removeInParen = new javax.swing.JCheckBox();
195.83 + addAfterComma = new javax.swing.JCheckBox();
195.84 + removeBeforeSep = new javax.swing.JCheckBox();
195.85 + collapseSpacesCb = new javax.swing.JCheckBox();
195.86 +
195.87 + setName(org.openide.util.NbBundle.getMessage(FmtSpaces.class, "LBL_Spaces")); // NOI18N
195.88 + setOpaque(false);
195.89 +
195.90 + org.openide.awt.Mnemonics.setLocalizedText(addAroundOp, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAroundOp.text")); // NOI18N
195.91 +
195.92 + org.openide.awt.Mnemonics.setLocalizedText(removeInParam, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParam.text")); // NOI18N
195.93 +
195.94 + org.openide.awt.Mnemonics.setLocalizedText(removeInParen, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeInParen.text")); // NOI18N
195.95 +
195.96 + org.openide.awt.Mnemonics.setLocalizedText(addAfterComma, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.addAfterComma.text")); // NOI18N
195.97 +
195.98 + org.openide.awt.Mnemonics.setLocalizedText(removeBeforeSep, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.removeBeforeSep.text")); // NOI18N
195.99 +
195.100 + org.openide.awt.Mnemonics.setLocalizedText(collapseSpacesCb, org.openide.util.NbBundle.getMessage(FmtSpaces.class, "FmtSpaces.collapseSpacesCb.text")); // NOI18N
195.101 +
195.102 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
195.103 + this.setLayout(layout);
195.104 + layout.setHorizontalGroup(
195.105 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
195.106 + .addGroup(layout.createSequentialGroup()
195.107 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
195.108 + .addComponent(addAroundOp)
195.109 + .addGroup(layout.createSequentialGroup()
195.110 + .addGap(27, 27, 27)
195.111 + .addComponent(removeInParam))
195.112 + .addComponent(removeInParen)
195.113 + .addComponent(addAfterComma)
195.114 + .addComponent(removeBeforeSep)
195.115 + .addComponent(collapseSpacesCb))
195.116 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
195.117 + );
195.118 + layout.setVerticalGroup(
195.119 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
195.120 + .addGroup(layout.createSequentialGroup()
195.121 + .addComponent(addAroundOp)
195.122 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
195.123 + .addComponent(removeInParam)
195.124 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
195.125 + .addComponent(removeInParen)
195.126 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
195.127 + .addComponent(addAfterComma)
195.128 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
195.129 + .addComponent(removeBeforeSep)
195.130 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
195.131 + .addComponent(collapseSpacesCb)
195.132 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
195.133 + );
195.134 + }// </editor-fold>//GEN-END:initComponents
195.135 +
195.136 +
195.137 + // Variables declaration - do not modify//GEN-BEGIN:variables
195.138 + private javax.swing.JCheckBox addAfterComma;
195.139 + private javax.swing.JCheckBox addAroundOp;
195.140 + private javax.swing.JCheckBox collapseSpacesCb;
195.141 + private javax.swing.JCheckBox removeBeforeSep;
195.142 + private javax.swing.JCheckBox removeInParam;
195.143 + private javax.swing.JCheckBox removeInParen;
195.144 + // End of variables declaration//GEN-END:variables
195.145 +
195.146 +}
196.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
196.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtTabsIndents.form Wed Sep 02 20:31:18 2015 +0200
196.3 @@ -0,0 +1,127 @@
196.4 +<?xml version="1.0" encoding="UTF-8" ?>
196.5 +
196.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
196.7 + <Properties>
196.8 + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
196.9 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_TabsAndIndents" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
196.10 + </Property>
196.11 + <Property name="opaque" type="boolean" value="false"/>
196.12 + </Properties>
196.13 + <AuxValues>
196.14 + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
196.15 + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
196.16 + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
196.17 + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
196.18 + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
196.19 + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
196.20 + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
196.21 + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
196.22 + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
196.23 + </AuxValues>
196.24 +
196.25 + <Layout>
196.26 + <DimensionLayout dim="0">
196.27 + <Group type="103" groupAlignment="0" attributes="0">
196.28 + <Group type="102" alignment="0" attributes="0">
196.29 + <Group type="103" groupAlignment="0" attributes="0">
196.30 + <Component id="continuationIndentSizeLabel" max="32767" attributes="0"/>
196.31 + <Component id="labelIndentLabel" min="-2" max="-2" attributes="0"/>
196.32 + </Group>
196.33 + <EmptySpace max="-2" attributes="0"/>
196.34 + <Group type="103" groupAlignment="1" attributes="0">
196.35 + <Component id="continuationIndentSizeField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
196.36 + <Component id="labelIndentField" linkSize="2" min="-2" pref="36" max="-2" attributes="1"/>
196.37 + </Group>
196.38 + </Group>
196.39 + <Component id="indentCasesFromSwitchCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
196.40 + <Component id="indentTopLevelClassMembersCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
196.41 + <Component id="absoluteLabelIndentCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
196.42 + </Group>
196.43 + </DimensionLayout>
196.44 + <DimensionLayout dim="1">
196.45 + <Group type="103" groupAlignment="0" attributes="0">
196.46 + <Group type="102" attributes="0">
196.47 + <EmptySpace max="-2" attributes="0"/>
196.48 + <Group type="103" groupAlignment="3" attributes="0">
196.49 + <Component id="continuationIndentSizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
196.50 + <Component id="continuationIndentSizeField" alignment="3" min="-2" max="-2" attributes="0"/>
196.51 + </Group>
196.52 + <EmptySpace min="-2" max="-2" attributes="0"/>
196.53 + <Group type="103" groupAlignment="3" attributes="0">
196.54 + <Component id="labelIndentLabel" alignment="3" min="-2" max="-2" attributes="0"/>
196.55 + <Component id="labelIndentField" alignment="3" min="-2" max="-2" attributes="0"/>
196.56 + </Group>
196.57 + <EmptySpace type="unrelated" max="-2" attributes="0"/>
196.58 + <Component id="absoluteLabelIndentCheckBox" min="-2" max="-2" attributes="0"/>
196.59 + <EmptySpace max="-2" attributes="0"/>
196.60 + <Component id="indentTopLevelClassMembersCheckBox" min="-2" max="-2" attributes="0"/>
196.61 + <EmptySpace max="-2" attributes="0"/>
196.62 + <Component id="indentCasesFromSwitchCheckBox" min="-2" max="-2" attributes="0"/>
196.63 + <EmptySpace max="32767" attributes="0"/>
196.64 + </Group>
196.65 + </Group>
196.66 + </DimensionLayout>
196.67 + </Layout>
196.68 + <SubComponents>
196.69 + <Component class="javax.swing.JLabel" name="continuationIndentSizeLabel">
196.70 + <Properties>
196.71 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
196.72 + <ComponentRef name="continuationIndentSizeField"/>
196.73 + </Property>
196.74 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
196.75 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_ContinuationIndentSize" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
196.76 + </Property>
196.77 + </Properties>
196.78 + </Component>
196.79 + <Component class="javax.swing.JTextField" name="continuationIndentSizeField">
196.80 + </Component>
196.81 + <Component class="javax.swing.JLabel" name="labelIndentLabel">
196.82 + <Properties>
196.83 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
196.84 + <ComponentRef name="labelIndentField"/>
196.85 + </Property>
196.86 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
196.87 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_LabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
196.88 + </Property>
196.89 + </Properties>
196.90 + </Component>
196.91 + <Component class="javax.swing.JTextField" name="labelIndentField">
196.92 + </Component>
196.93 + <Component class="javax.swing.JCheckBox" name="absoluteLabelIndentCheckBox">
196.94 + <Properties>
196.95 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
196.96 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_AbsoluteLabelIndent" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
196.97 + </Property>
196.98 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
196.99 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
196.100 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
196.101 + </Border>
196.102 + </Property>
196.103 + </Properties>
196.104 + </Component>
196.105 + <Component class="javax.swing.JCheckBox" name="indentTopLevelClassMembersCheckBox">
196.106 + <Properties>
196.107 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
196.108 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentTopLevelClassMemberts" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
196.109 + </Property>
196.110 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
196.111 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
196.112 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
196.113 + </Border>
196.114 + </Property>
196.115 + </Properties>
196.116 + </Component>
196.117 + <Component class="javax.swing.JCheckBox" name="indentCasesFromSwitchCheckBox">
196.118 + <Properties>
196.119 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
196.120 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_IndentCasesFromSwitch" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
196.121 + </Property>
196.122 + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
196.123 + <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
196.124 + <EmptyBorder bottom="0" left="0" right="0" top="0"/>
196.125 + </Border>
196.126 + </Property>
196.127 + </Properties>
196.128 + </Component>
196.129 + </SubComponents>
196.130 +</Form>
197.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
197.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtTabsIndents.java Wed Sep 02 20:31:18 2015 +0200
197.3 @@ -0,0 +1,196 @@
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-2006 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 +
197.48 +package org.netbeans.modules.python.source.ui;
197.49 +
197.50 +//import org.netbeans.modules.python.source.CodeStyle.WrapStyle;
197.51 +//import static org.netbeans.modules.python.source.ui.FmtOptions.*;
197.52 +//import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
197.53 +//import org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport;
197.54 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
197.55 +
197.56 +/**
197.57 + *
197.58 + * @author phrebejk
197.59 + */
197.60 +public class FmtTabsIndents extends javax.swing.JPanel {
197.61 +
197.62 + /** Creates new form FmtTabsIndents */
197.63 + public FmtTabsIndents() {
197.64 + initComponents();
197.65 +/*
197.66 +// expandTabCheckBox.putClientProperty(OPTION_ID, expandTabToSpaces);
197.67 +// tabSizeField.putClientProperty(OPTION_ID, tabSize);
197.68 +// indentSizeField.putClientProperty(OPTION_ID, new String [] { indentSize, spacesPerTab });
197.69 + continuationIndentSizeField.putClientProperty(OPTION_ID, continuationIndentSize);
197.70 + labelIndentField.putClientProperty(OPTION_ID, labelIndent);
197.71 + absoluteLabelIndentCheckBox.putClientProperty(OPTION_ID, absoluteLabelIndent);
197.72 + indentTopLevelClassMembersCheckBox.putClientProperty(OPTION_ID, indentTopLevelClassMembers);
197.73 + indentCasesFromSwitchCheckBox.putClientProperty(OPTION_ID, indentCasesFromSwitch);
197.74 +// rightMarginField.putClientProperty(OPTION_ID, rightMargin);
197.75 + }
197.76 +
197.77 + public static PreferencesCustomizer.Factory getController() {
197.78 + return new CategorySupport.Factory(PreferencesCustomizer.TABS_AND_INDENTS_ID, FmtTabsIndents.class, //NOI18N
197.79 + org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "SAMPLE_TabsIndents"), // NOI18N
197.80 + new String[] { FmtOptions.rightMargin, "30" }, //NOI18N
197.81 + new String[] { FmtOptions.wrapAnnotations, WrapStyle.WRAP_ALWAYS.name() },
197.82 + new String[] { FmtOptions.wrapArrayInit, WrapStyle.WRAP_ALWAYS.name() },
197.83 + new String[] { FmtOptions.wrapAssert, WrapStyle.WRAP_ALWAYS.name() },
197.84 + new String[] { FmtOptions.wrapAssignOps, WrapStyle.WRAP_ALWAYS.name() },
197.85 + new String[] { FmtOptions.wrapBinaryOps, WrapStyle.WRAP_ALWAYS.name() },
197.86 + new String[] { FmtOptions.wrapChainedMethodCalls, WrapStyle.WRAP_ALWAYS.name() },
197.87 + new String[] { FmtOptions.wrapDoWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
197.88 + new String[] { FmtOptions.wrapEnumConstants, WrapStyle.WRAP_ALWAYS.name() },
197.89 + new String[] { FmtOptions.wrapExtendsImplementsKeyword, WrapStyle.WRAP_ALWAYS.name() },
197.90 + new String[] { FmtOptions.wrapExtendsImplementsList, WrapStyle.WRAP_ALWAYS.name() },
197.91 + new String[] { FmtOptions.wrapFor, WrapStyle.WRAP_ALWAYS.name() },
197.92 + new String[] { FmtOptions.wrapForStatement, WrapStyle.WRAP_ALWAYS.name() },
197.93 + new String[] { FmtOptions.wrapIfStatement, WrapStyle.WRAP_ALWAYS.name() },
197.94 + new String[] { FmtOptions.wrapMethodCallArgs, WrapStyle.WRAP_ALWAYS.name() },
197.95 + new String[] { FmtOptions.wrapMethodParams, WrapStyle.WRAP_ALWAYS.name() },
197.96 + new String[] { FmtOptions.wrapTernaryOps, WrapStyle.WRAP_ALWAYS.name() },
197.97 + new String[] { FmtOptions.wrapThrowsKeyword, WrapStyle.WRAP_ALWAYS.name() },
197.98 + new String[] { FmtOptions.wrapThrowsList, WrapStyle.WRAP_ALWAYS.name() },
197.99 + new String[] { FmtOptions.wrapWhileStatement, WrapStyle.WRAP_ALWAYS.name() },
197.100 + new String[] { FmtOptions.alignMultilineArrayInit, Boolean.FALSE.toString() },
197.101 + new String[] { FmtOptions.alignMultilineAssignment, Boolean.FALSE.toString() },
197.102 + new String[] { FmtOptions.alignMultilineBinaryOp, Boolean.FALSE.toString() },
197.103 + new String[] { FmtOptions.alignMultilineCallArgs, Boolean.FALSE.toString() },
197.104 + new String[] { FmtOptions.alignMultilineFor, Boolean.FALSE.toString() },
197.105 + new String[] { FmtOptions.alignMultilineImplements, Boolean.FALSE.toString() },
197.106 + new String[] { FmtOptions.alignMultilineMethodParams, Boolean.FALSE.toString() },
197.107 + new String[] { FmtOptions.alignMultilineParenthesized, Boolean.FALSE.toString() },
197.108 + new String[] { FmtOptions.alignMultilineTernaryOp, Boolean.FALSE.toString() },
197.109 + new String[] { FmtOptions.alignMultilineThrows, Boolean.FALSE.toString() }
197.110 + );
197.111 + */
197.112 + }
197.113 +
197.114 + /** This method is called from within the constructor to
197.115 + * initialize the form.
197.116 + * WARNING: Do NOT modify this code. The content of this method is
197.117 + * always regenerated by the Form Editor.
197.118 + */
197.119 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
197.120 + private void initComponents() {
197.121 +
197.122 + continuationIndentSizeLabel = new javax.swing.JLabel();
197.123 + continuationIndentSizeField = new javax.swing.JTextField();
197.124 + labelIndentLabel = new javax.swing.JLabel();
197.125 + labelIndentField = new javax.swing.JTextField();
197.126 + absoluteLabelIndentCheckBox = new javax.swing.JCheckBox();
197.127 + indentTopLevelClassMembersCheckBox = new javax.swing.JCheckBox();
197.128 + indentCasesFromSwitchCheckBox = new javax.swing.JCheckBox();
197.129 +
197.130 + setName(org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_TabsAndIndents")); // NOI18N
197.131 + setOpaque(false);
197.132 +
197.133 + continuationIndentSizeLabel.setLabelFor(continuationIndentSizeField);
197.134 + org.openide.awt.Mnemonics.setLocalizedText(continuationIndentSizeLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_ContinuationIndentSize")); // NOI18N
197.135 +
197.136 + labelIndentLabel.setLabelFor(labelIndentField);
197.137 + org.openide.awt.Mnemonics.setLocalizedText(labelIndentLabel, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_LabelIndent")); // NOI18N
197.138 +
197.139 + org.openide.awt.Mnemonics.setLocalizedText(absoluteLabelIndentCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_AbsoluteLabelIndent")); // NOI18N
197.140 + absoluteLabelIndentCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
197.141 +
197.142 + org.openide.awt.Mnemonics.setLocalizedText(indentTopLevelClassMembersCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentTopLevelClassMemberts")); // NOI18N
197.143 + indentTopLevelClassMembersCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
197.144 +
197.145 + org.openide.awt.Mnemonics.setLocalizedText(indentCasesFromSwitchCheckBox, org.openide.util.NbBundle.getMessage(FmtTabsIndents.class, "LBL_IndentCasesFromSwitch")); // NOI18N
197.146 + indentCasesFromSwitchCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
197.147 +
197.148 + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
197.149 + this.setLayout(layout);
197.150 + layout.setHorizontalGroup(
197.151 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
197.152 + .addGroup(layout.createSequentialGroup()
197.153 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
197.154 + .addComponent(continuationIndentSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
197.155 + .addComponent(labelIndentLabel))
197.156 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
197.157 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
197.158 + .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
197.159 + .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)))
197.160 + .addComponent(indentCasesFromSwitchCheckBox)
197.161 + .addComponent(indentTopLevelClassMembersCheckBox)
197.162 + .addComponent(absoluteLabelIndentCheckBox)
197.163 + );
197.164 +
197.165 + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {continuationIndentSizeField, labelIndentField});
197.166 +
197.167 + layout.setVerticalGroup(
197.168 + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
197.169 + .addGroup(layout.createSequentialGroup()
197.170 + .addContainerGap()
197.171 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
197.172 + .addComponent(continuationIndentSizeLabel)
197.173 + .addComponent(continuationIndentSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
197.174 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
197.175 + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
197.176 + .addComponent(labelIndentLabel)
197.177 + .addComponent(labelIndentField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
197.178 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
197.179 + .addComponent(absoluteLabelIndentCheckBox)
197.180 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
197.181 + .addComponent(indentTopLevelClassMembersCheckBox)
197.182 + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
197.183 + .addComponent(indentCasesFromSwitchCheckBox)
197.184 + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
197.185 + );
197.186 + }// </editor-fold>//GEN-END:initComponents
197.187 +
197.188 +
197.189 + // Variables declaration - do not modify//GEN-BEGIN:variables
197.190 + private javax.swing.JCheckBox absoluteLabelIndentCheckBox;
197.191 + private javax.swing.JTextField continuationIndentSizeField;
197.192 + private javax.swing.JLabel continuationIndentSizeLabel;
197.193 + private javax.swing.JCheckBox indentCasesFromSwitchCheckBox;
197.194 + private javax.swing.JCheckBox indentTopLevelClassMembersCheckBox;
197.195 + private javax.swing.JTextField labelIndentField;
197.196 + private javax.swing.JLabel labelIndentLabel;
197.197 + // End of variables declaration//GEN-END:variables
197.198 +
197.199 +}
198.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
198.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/FmtWrapping.form Wed Sep 02 20:31:18 2015 +0200
198.3 @@ -0,0 +1,706 @@
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_Wrapping" 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="2"/>
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 + <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"/>
198.24 + </AuxValues>
198.25 +
198.26 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
198.27 + <SubComponents>
198.28 + <Container class="javax.swing.JScrollPane" name="scrollPane">
198.29 + <Properties>
198.30 + <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
198.31 + <Dimension value="[300, 200]"/>
198.32 + </Property>
198.33 + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
198.34 + <Dimension value="[350, 600]"/>
198.35 + </Property>
198.36 + </Properties>
198.37 + <Constraints>
198.38 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
198.39 + <BorderConstraints direction="Center"/>
198.40 + </Constraint>
198.41 + </Constraints>
198.42 +
198.43 + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
198.44 + <SubComponents>
198.45 + <Container class="javax.swing.JPanel" name="panel1">
198.46 + <Properties>
198.47 + <Property name="opaque" type="boolean" value="false"/>
198.48 + </Properties>
198.49 +
198.50 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
198.51 + <SubComponents>
198.52 + <Component class="javax.swing.JLabel" name="extendsImplemetsKeywordLabel">
198.53 + <Properties>
198.54 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.55 + <ComponentRef name="extendsImplementsKeywordCombo"/>
198.56 + </Property>
198.57 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.58 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.59 + </Property>
198.60 + </Properties>
198.61 + <Constraints>
198.62 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.64 + </Constraint>
198.65 + </Constraints>
198.66 + </Component>
198.67 + <Component class="javax.swing.JComboBox" name="extendsImplementsKeywordCombo">
198.68 + <Properties>
198.69 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.70 + <StringArray count="4">
198.71 + <StringItem index="0" value="Item 1"/>
198.72 + <StringItem index="1" value="Item 2"/>
198.73 + <StringItem index="2" value="Item 3"/>
198.74 + <StringItem index="3" value="Item 4"/>
198.75 + </StringArray>
198.76 + </Property>
198.77 + </Properties>
198.78 + <Constraints>
198.79 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.81 + </Constraint>
198.82 + </Constraints>
198.83 + </Component>
198.84 + <Component class="javax.swing.JLabel" name="extendsImplementsListLabel">
198.85 + <Properties>
198.86 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.87 + <ComponentRef name="extendsImplementsListCombo"/>
198.88 + </Property>
198.89 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.90 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_extendsImplementsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.91 + </Property>
198.92 + </Properties>
198.93 + <Constraints>
198.94 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.96 + </Constraint>
198.97 + </Constraints>
198.98 + </Component>
198.99 + <Component class="javax.swing.JComboBox" name="extendsImplementsListCombo">
198.100 + <Properties>
198.101 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.102 + <StringArray count="4">
198.103 + <StringItem index="0" value="Item 1"/>
198.104 + <StringItem index="1" value="Item 2"/>
198.105 + <StringItem index="2" value="Item 3"/>
198.106 + <StringItem index="3" value="Item 4"/>
198.107 + </StringArray>
198.108 + </Property>
198.109 + </Properties>
198.110 + <Constraints>
198.111 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.113 + </Constraint>
198.114 + </Constraints>
198.115 + </Component>
198.116 + <Component class="javax.swing.JLabel" name="methodParamsLabel">
198.117 + <Properties>
198.118 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.119 + <ComponentRef name="methodParamsCombo"/>
198.120 + </Property>
198.121 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.122 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodParameters" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.123 + </Property>
198.124 + </Properties>
198.125 + <Constraints>
198.126 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.128 + </Constraint>
198.129 + </Constraints>
198.130 + </Component>
198.131 + <Component class="javax.swing.JComboBox" name="methodParamsCombo">
198.132 + <Properties>
198.133 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.134 + <StringArray count="4">
198.135 + <StringItem index="0" value="Item 1"/>
198.136 + <StringItem index="1" value="Item 2"/>
198.137 + <StringItem index="2" value="Item 3"/>
198.138 + <StringItem index="3" value="Item 4"/>
198.139 + </StringArray>
198.140 + </Property>
198.141 + </Properties>
198.142 + <Constraints>
198.143 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.145 + </Constraint>
198.146 + </Constraints>
198.147 + </Component>
198.148 + <Component class="javax.swing.JLabel" name="methodCallArgsLabel">
198.149 + <Properties>
198.150 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.151 + <ComponentRef name="methodCallArgsCombo"/>
198.152 + </Property>
198.153 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.154 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_methodCallArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.155 + </Property>
198.156 + </Properties>
198.157 + <Constraints>
198.158 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.160 + </Constraint>
198.161 + </Constraints>
198.162 + </Component>
198.163 + <Component class="javax.swing.JComboBox" name="methodCallArgsCombo">
198.164 + <Properties>
198.165 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.166 + <StringArray count="4">
198.167 + <StringItem index="0" value="Item 1"/>
198.168 + <StringItem index="1" value="Item 2"/>
198.169 + <StringItem index="2" value="Item 3"/>
198.170 + <StringItem index="3" value="Item 4"/>
198.171 + </StringArray>
198.172 + </Property>
198.173 + </Properties>
198.174 + <Constraints>
198.175 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.177 + </Constraint>
198.178 + </Constraints>
198.179 + </Component>
198.180 + <Component class="javax.swing.JLabel" name="annotationArgsLabel">
198.181 + <Properties>
198.182 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.183 + <ComponentRef name="annotationArgsCombo"/>
198.184 + </Property>
198.185 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.186 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotationArgs" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.187 + </Property>
198.188 + </Properties>
198.189 + <Constraints>
198.190 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.192 + </Constraint>
198.193 + </Constraints>
198.194 + </Component>
198.195 + <Component class="javax.swing.JComboBox" name="annotationArgsCombo">
198.196 + <Properties>
198.197 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.198 + <StringArray count="4">
198.199 + <StringItem index="0" value="Item 1"/>
198.200 + <StringItem index="1" value="Item 2"/>
198.201 + <StringItem index="2" value="Item 3"/>
198.202 + <StringItem index="3" value="Item 4"/>
198.203 + </StringArray>
198.204 + </Property>
198.205 + </Properties>
198.206 + <Constraints>
198.207 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.209 + </Constraint>
198.210 + </Constraints>
198.211 + </Component>
198.212 + <Component class="javax.swing.JLabel" name="chainedMethodCallsLabel">
198.213 + <Properties>
198.214 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.215 + <ComponentRef name="chainedMethodCallsCombo"/>
198.216 + </Property>
198.217 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.218 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_chainedMethodCalls" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.219 + </Property>
198.220 + </Properties>
198.221 + <Constraints>
198.222 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.224 + </Constraint>
198.225 + </Constraints>
198.226 + </Component>
198.227 + <Component class="javax.swing.JComboBox" name="chainedMethodCallsCombo">
198.228 + <Properties>
198.229 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.230 + <StringArray count="4">
198.231 + <StringItem index="0" value="Item 1"/>
198.232 + <StringItem index="1" value="Item 2"/>
198.233 + <StringItem index="2" value="Item 3"/>
198.234 + <StringItem index="3" value="Item 4"/>
198.235 + </StringArray>
198.236 + </Property>
198.237 + </Properties>
198.238 + <Constraints>
198.239 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.241 + </Constraint>
198.242 + </Constraints>
198.243 + </Component>
198.244 + <Component class="javax.swing.JLabel" name="throwsKeywordLabel">
198.245 + <Properties>
198.246 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.247 + <ComponentRef name="throwsKeywordCombo"/>
198.248 + </Property>
198.249 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.250 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsKeyword" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.251 + </Property>
198.252 + </Properties>
198.253 + <Constraints>
198.254 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.256 + </Constraint>
198.257 + </Constraints>
198.258 + </Component>
198.259 + <Component class="javax.swing.JComboBox" name="throwsKeywordCombo">
198.260 + <Properties>
198.261 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.262 + <StringArray count="4">
198.263 + <StringItem index="0" value="Item 1"/>
198.264 + <StringItem index="1" value="Item 2"/>
198.265 + <StringItem index="2" value="Item 3"/>
198.266 + <StringItem index="3" value="Item 4"/>
198.267 + </StringArray>
198.268 + </Property>
198.269 + </Properties>
198.270 + <Constraints>
198.271 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.273 + </Constraint>
198.274 + </Constraints>
198.275 + </Component>
198.276 + <Component class="javax.swing.JLabel" name="throwsListLabel">
198.277 + <Properties>
198.278 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.279 + <ComponentRef name="throwsListCombo"/>
198.280 + </Property>
198.281 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.282 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_throwsList" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.283 + </Property>
198.284 + </Properties>
198.285 + <Constraints>
198.286 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.288 + </Constraint>
198.289 + </Constraints>
198.290 + </Component>
198.291 + <Component class="javax.swing.JComboBox" name="throwsListCombo">
198.292 + <Properties>
198.293 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.294 + <StringArray count="4">
198.295 + <StringItem index="0" value="Item 1"/>
198.296 + <StringItem index="1" value="Item 2"/>
198.297 + <StringItem index="2" value="Item 3"/>
198.298 + <StringItem index="3" value="Item 4"/>
198.299 + </StringArray>
198.300 + </Property>
198.301 + </Properties>
198.302 + <Constraints>
198.303 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.305 + </Constraint>
198.306 + </Constraints>
198.307 + </Component>
198.308 + <Component class="javax.swing.JLabel" name="arrayInitLabel">
198.309 + <Properties>
198.310 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.311 + <ComponentRef name="arrayInitCombo"/>
198.312 + </Property>
198.313 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.314 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_arrayInit" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.315 + </Property>
198.316 + </Properties>
198.317 + <Constraints>
198.318 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.320 + </Constraint>
198.321 + </Constraints>
198.322 + </Component>
198.323 + <Component class="javax.swing.JComboBox" name="arrayInitCombo">
198.324 + <Properties>
198.325 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.326 + <StringArray count="4">
198.327 + <StringItem index="0" value="Item 1"/>
198.328 + <StringItem index="1" value="Item 2"/>
198.329 + <StringItem index="2" value="Item 3"/>
198.330 + <StringItem index="3" value="Item 4"/>
198.331 + </StringArray>
198.332 + </Property>
198.333 + </Properties>
198.334 + <Constraints>
198.335 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.337 + </Constraint>
198.338 + </Constraints>
198.339 + </Component>
198.340 + <Component class="javax.swing.JLabel" name="forLabel">
198.341 + <Properties>
198.342 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.343 + <ComponentRef name="forCombo"/>
198.344 + </Property>
198.345 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.346 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_for" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.347 + </Property>
198.348 + </Properties>
198.349 + <Constraints>
198.350 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.352 + </Constraint>
198.353 + </Constraints>
198.354 + </Component>
198.355 + <Component class="javax.swing.JComboBox" name="forCombo">
198.356 + <Properties>
198.357 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.358 + <StringArray count="4">
198.359 + <StringItem index="0" value="Item 1"/>
198.360 + <StringItem index="1" value="Item 2"/>
198.361 + <StringItem index="2" value="Item 3"/>
198.362 + <StringItem index="3" value="Item 4"/>
198.363 + </StringArray>
198.364 + </Property>
198.365 + </Properties>
198.366 + <Constraints>
198.367 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.369 + </Constraint>
198.370 + </Constraints>
198.371 + </Component>
198.372 + <Component class="javax.swing.JLabel" name="forStatementLabel">
198.373 + <Properties>
198.374 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.375 + <ComponentRef name="forStatementCombo"/>
198.376 + </Property>
198.377 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.378 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_forStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.379 + </Property>
198.380 + </Properties>
198.381 + <Constraints>
198.382 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.384 + </Constraint>
198.385 + </Constraints>
198.386 + </Component>
198.387 + <Component class="javax.swing.JComboBox" name="forStatementCombo">
198.388 + <Properties>
198.389 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.390 + <StringArray count="4">
198.391 + <StringItem index="0" value="Item 1"/>
198.392 + <StringItem index="1" value="Item 2"/>
198.393 + <StringItem index="2" value="Item 3"/>
198.394 + <StringItem index="3" value="Item 4"/>
198.395 + </StringArray>
198.396 + </Property>
198.397 + </Properties>
198.398 + <Constraints>
198.399 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.401 + </Constraint>
198.402 + </Constraints>
198.403 + </Component>
198.404 + <Component class="javax.swing.JLabel" name="ifStatementLabel">
198.405 + <Properties>
198.406 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.407 + <ComponentRef name="ifStatementCombo"/>
198.408 + </Property>
198.409 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.410 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ifStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.411 + </Property>
198.412 + </Properties>
198.413 + <Constraints>
198.414 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.416 + </Constraint>
198.417 + </Constraints>
198.418 + </Component>
198.419 + <Component class="javax.swing.JComboBox" name="ifStatementCombo">
198.420 + <Properties>
198.421 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.422 + <StringArray count="4">
198.423 + <StringItem index="0" value="Item 1"/>
198.424 + <StringItem index="1" value="Item 2"/>
198.425 + <StringItem index="2" value="Item 3"/>
198.426 + <StringItem index="3" value="Item 4"/>
198.427 + </StringArray>
198.428 + </Property>
198.429 + </Properties>
198.430 + <Constraints>
198.431 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.433 + </Constraint>
198.434 + </Constraints>
198.435 + </Component>
198.436 + <Component class="javax.swing.JLabel" name="whileStatementLabel">
198.437 + <Properties>
198.438 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.439 + <ComponentRef name="whileStatementComboBox"/>
198.440 + </Property>
198.441 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.442 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_whileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.443 + </Property>
198.444 + </Properties>
198.445 + <Constraints>
198.446 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.448 + </Constraint>
198.449 + </Constraints>
198.450 + </Component>
198.451 + <Component class="javax.swing.JComboBox" name="whileStatementComboBox">
198.452 + <Properties>
198.453 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.454 + <StringArray count="4">
198.455 + <StringItem index="0" value="Item 1"/>
198.456 + <StringItem index="1" value="Item 2"/>
198.457 + <StringItem index="2" value="Item 3"/>
198.458 + <StringItem index="3" value="Item 4"/>
198.459 + </StringArray>
198.460 + </Property>
198.461 + </Properties>
198.462 + <Constraints>
198.463 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.465 + </Constraint>
198.466 + </Constraints>
198.467 + </Component>
198.468 + <Component class="javax.swing.JLabel" name="doWhileStatementLabel">
198.469 + <Properties>
198.470 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.471 + <ComponentRef name="doWhileStatementCombo"/>
198.472 + </Property>
198.473 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.474 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_doWhileStatement" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.475 + </Property>
198.476 + </Properties>
198.477 + <Constraints>
198.478 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.480 + </Constraint>
198.481 + </Constraints>
198.482 + </Component>
198.483 + <Component class="javax.swing.JComboBox" name="doWhileStatementCombo">
198.484 + <Properties>
198.485 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.486 + <StringArray count="4">
198.487 + <StringItem index="0" value="Item 1"/>
198.488 + <StringItem index="1" value="Item 2"/>
198.489 + <StringItem index="2" value="Item 3"/>
198.490 + <StringItem index="3" value="Item 4"/>
198.491 + </StringArray>
198.492 + </Property>
198.493 + </Properties>
198.494 + <Constraints>
198.495 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.497 + </Constraint>
198.498 + </Constraints>
198.499 + </Component>
198.500 + <Component class="javax.swing.JLabel" name="assertLabel">
198.501 + <Properties>
198.502 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.503 + <ComponentRef name="assertCombo"/>
198.504 + </Property>
198.505 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.506 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assert" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.507 + </Property>
198.508 + </Properties>
198.509 + <Constraints>
198.510 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.512 + </Constraint>
198.513 + </Constraints>
198.514 + </Component>
198.515 + <Component class="javax.swing.JComboBox" name="assertCombo">
198.516 + <Properties>
198.517 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.518 + <StringArray count="4">
198.519 + <StringItem index="0" value="Item 1"/>
198.520 + <StringItem index="1" value="Item 2"/>
198.521 + <StringItem index="2" value="Item 3"/>
198.522 + <StringItem index="3" value="Item 4"/>
198.523 + </StringArray>
198.524 + </Property>
198.525 + </Properties>
198.526 + <Constraints>
198.527 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.529 + </Constraint>
198.530 + </Constraints>
198.531 + </Component>
198.532 + <Component class="javax.swing.JLabel" name="enumConstantsLabel">
198.533 + <Properties>
198.534 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.535 + <ComponentRef name="enumConstantsCombo"/>
198.536 + </Property>
198.537 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.538 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_enumConstants" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.539 + </Property>
198.540 + </Properties>
198.541 + <Constraints>
198.542 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.544 + </Constraint>
198.545 + </Constraints>
198.546 + </Component>
198.547 + <Component class="javax.swing.JComboBox" name="enumConstantsCombo">
198.548 + <Properties>
198.549 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.550 + <StringArray count="4">
198.551 + <StringItem index="0" value="Item 1"/>
198.552 + <StringItem index="1" value="Item 2"/>
198.553 + <StringItem index="2" value="Item 3"/>
198.554 + <StringItem index="3" value="Item 4"/>
198.555 + </StringArray>
198.556 + </Property>
198.557 + </Properties>
198.558 + <Constraints>
198.559 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.561 + </Constraint>
198.562 + </Constraints>
198.563 + </Component>
198.564 + <Component class="javax.swing.JLabel" name="annotationsLabel">
198.565 + <Properties>
198.566 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.567 + <ComponentRef name="annotationsCombo"/>
198.568 + </Property>
198.569 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.570 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_annotations" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.571 + </Property>
198.572 + </Properties>
198.573 + <Constraints>
198.574 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.576 + </Constraint>
198.577 + </Constraints>
198.578 + </Component>
198.579 + <Component class="javax.swing.JComboBox" name="annotationsCombo">
198.580 + <Properties>
198.581 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.582 + <StringArray count="4">
198.583 + <StringItem index="0" value="Item 1"/>
198.584 + <StringItem index="1" value="Item 2"/>
198.585 + <StringItem index="2" value="Item 3"/>
198.586 + <StringItem index="3" value="Item 4"/>
198.587 + </StringArray>
198.588 + </Property>
198.589 + </Properties>
198.590 + <Constraints>
198.591 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.593 + </Constraint>
198.594 + </Constraints>
198.595 + </Component>
198.596 + <Component class="javax.swing.JLabel" name="binaryOpsLabel">
198.597 + <Properties>
198.598 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.599 + <ComponentRef name="binaryOpsCombo"/>
198.600 + </Property>
198.601 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.602 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_binaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.603 + </Property>
198.604 + </Properties>
198.605 + <Constraints>
198.606 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.608 + </Constraint>
198.609 + </Constraints>
198.610 + </Component>
198.611 + <Component class="javax.swing.JComboBox" name="binaryOpsCombo">
198.612 + <Properties>
198.613 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.614 + <StringArray count="4">
198.615 + <StringItem index="0" value="Item 1"/>
198.616 + <StringItem index="1" value="Item 2"/>
198.617 + <StringItem index="2" value="Item 3"/>
198.618 + <StringItem index="3" value="Item 4"/>
198.619 + </StringArray>
198.620 + </Property>
198.621 + </Properties>
198.622 + <Constraints>
198.623 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.625 + </Constraint>
198.626 + </Constraints>
198.627 + </Component>
198.628 + <Component class="javax.swing.JLabel" name="ternaryOpsLabel">
198.629 + <Properties>
198.630 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.631 + <ComponentRef name="ternaryOpsCombo"/>
198.632 + </Property>
198.633 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.634 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_ternaryOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.635 + </Property>
198.636 + </Properties>
198.637 + <Constraints>
198.638 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.640 + </Constraint>
198.641 + </Constraints>
198.642 + </Component>
198.643 + <Component class="javax.swing.JComboBox" name="ternaryOpsCombo">
198.644 + <Properties>
198.645 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.646 + <StringArray count="4">
198.647 + <StringItem index="0" value="Item 1"/>
198.648 + <StringItem index="1" value="Item 2"/>
198.649 + <StringItem index="2" value="Item 3"/>
198.650 + <StringItem index="3" value="Item 4"/>
198.651 + </StringArray>
198.652 + </Property>
198.653 + </Properties>
198.654 + <Constraints>
198.655 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.657 + </Constraint>
198.658 + </Constraints>
198.659 + </Component>
198.660 + <Component class="javax.swing.JLabel" name="assignOpsLabel">
198.661 + <Properties>
198.662 + <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
198.663 + <ComponentRef name="assignOpsCombo"/>
198.664 + </Property>
198.665 + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
198.666 + <ResourceString bundle="org/netbeans/modules/python/editor/options/Bundle.properties" key="LBL_wrp_assignOps" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
198.667 + </Property>
198.668 + </Properties>
198.669 + <Constraints>
198.670 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.672 + </Constraint>
198.673 + </Constraints>
198.674 + </Component>
198.675 + <Component class="javax.swing.JComboBox" name="assignOpsCombo">
198.676 + <Properties>
198.677 + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
198.678 + <StringArray count="4">
198.679 + <StringItem index="0" value="Item 1"/>
198.680 + <StringItem index="1" value="Item 2"/>
198.681 + <StringItem index="2" value="Item 3"/>
198.682 + <StringItem index="3" value="Item 4"/>
198.683 + </StringArray>
198.684 + </Property>
198.685 + </Properties>
198.686 + <Constraints>
198.687 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.689 + </Constraint>
198.690 + </Constraints>
198.691 + </Component>
198.692 + <Container class="javax.swing.JPanel" name="spacerPanel1">
198.693 + <Properties>
198.694 + <Property name="opaque" type="boolean" value="false"/>
198.695 + </Properties>
198.696 + <Constraints>
198.697 + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
198.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"/>
198.699 + </Constraint>
198.700 + </Constraints>
198.701 +
198.702 + <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
198.703 + </Container>
198.704 + </SubComponents>
198.705 + </Container>
198.706 + </SubComponents>
198.707 + </Container>
198.708 + </SubComponents>
198.709 +</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/FmtWrapping.java Wed Sep 02 20:31:18 2015 +0200
199.3 @@ -0,0 +1,505 @@
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 org.netbeans.modules.python.source.CodeStyle;
199.51 +//import static org.netbeans.modules.python.source.ui.FmtOptions.*;
199.52 +//import static org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport.OPTION_ID;
199.53 +//import org.netbeans.modules.python.source.ui.FmtOptions.CategorySupport;
199.54 +//import org.netbeans.modules.options.editor.spi.PreferencesCustomizer;
199.55 +
199.56 +
199.57 +/**
199.58 + *
199.59 + * @author phrebejk
199.60 + */
199.61 +public class FmtWrapping extends javax.swing.JPanel {
199.62 +
199.63 + /** Creates new form FmtWrapping */
199.64 + public FmtWrapping() {
199.65 + initComponents();
199.66 +
199.67 + scrollPane.getViewport().setBackground(java.awt.SystemColor.controlLtHighlight);
199.68 +
199.69 +/*
199.70 + extendsImplementsKeywordCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsKeyword);
199.71 + extendsImplementsListCombo.putClientProperty(OPTION_ID, wrapExtendsImplementsList);
199.72 + methodParamsCombo.putClientProperty(OPTION_ID, wrapMethodParams);
199.73 + methodCallArgsCombo.putClientProperty(OPTION_ID, wrapMethodCallArgs);
199.74 + annotationArgsCombo.putClientProperty(OPTION_ID, wrapAnnotationArgs);
199.75 + chainedMethodCallsCombo.putClientProperty(OPTION_ID, wrapChainedMethodCalls);
199.76 + throwsKeywordCombo.putClientProperty(OPTION_ID, wrapThrowsKeyword);
199.77 + throwsListCombo.putClientProperty(OPTION_ID, wrapThrowsList);
199.78 + arrayInitCombo.putClientProperty(OPTION_ID, wrapArrayInit);
199.79 + forCombo.putClientProperty(OPTION_ID, wrapFor);
199.80 + forStatementCombo.putClientProperty(OPTION_ID, wrapForStatement );
199.81 + ifStatementCombo.putClientProperty(OPTION_ID, wrapIfStatement);
199.82 + whileStatementComboBox.putClientProperty(OPTION_ID, wrapWhileStatement);
199.83 + doWhileStatementCombo.putClientProperty(OPTION_ID, wrapDoWhileStatement);
199.84 + assertCombo.putClientProperty(OPTION_ID, wrapAssert);
199.85 + enumConstantsCombo.putClientProperty(OPTION_ID, wrapEnumConstants);
199.86 + annotationsCombo.putClientProperty(OPTION_ID, wrapAnnotations);
199.87 + binaryOpsCombo.putClientProperty(OPTION_ID, wrapBinaryOps);
199.88 + ternaryOpsCombo.putClientProperty(OPTION_ID, wrapTernaryOps);
199.89 + assignOpsCombo.putClientProperty(OPTION_ID, wrapAssignOps);
199.90 + }
199.91 +
199.92 + public static PreferencesCustomizer.Factory getController() {
199.93 + return new CategorySupport.Factory("wrapping", FmtWrapping.class, //NOI18N
199.94 + org.openide.util.NbBundle.getMessage(FmtWrapping.class, "SAMPLE_Wrapping"), //NOI18N
199.95 + new String[] { FmtOptions.rightMargin, "30" } //NOI18N
199.96 +// new String[] { FmtOptions.redundantDoWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
199.97 +// new String[] { FmtOptions.redundantForBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
199.98 +// new String[] { FmtOptions.redundantIfBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() },
199.99 +// new String[] { FmtOptions.redundantWhileBraces, CodeStyle.BracesGenerationStyle.LEAVE_ALONE.name() }
199.100 + ); // NOI18N
199.101 + */
199.102 + }
199.103 +
199.104 + /** This method is called from within the constructor to
199.105 + * initialize the form.
199.106 + * WARNING: Do NOT modify this code. The content of this method is
199.107 + * always regenerated by the Form Editor.
199.108 + */
199.109 + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
199.110 + private void initComponents() {
199.111 + java.awt.GridBagConstraints gridBagConstraints;
199.112 +
199.113 + scrollPane = new javax.swing.JScrollPane();
199.114 + panel1 = new javax.swing.JPanel();
199.115 + extendsImplemetsKeywordLabel = new javax.swing.JLabel();
199.116 + extendsImplementsKeywordCombo = new javax.swing.JComboBox();
199.117 + extendsImplementsListLabel = new javax.swing.JLabel();
199.118 + extendsImplementsListCombo = new javax.swing.JComboBox();
199.119 + methodParamsLabel = new javax.swing.JLabel();
199.120 + methodParamsCombo = new javax.swing.JComboBox();
199.121 + methodCallArgsLabel = new javax.swing.JLabel();
199.122 + methodCallArgsCombo = new javax.swing.JComboBox();
199.123 + annotationArgsLabel = new javax.swing.JLabel();
199.124 + annotationArgsCombo = new javax.swing.JComboBox();
199.125 + chainedMethodCallsLabel = new javax.swing.JLabel();
199.126 + chainedMethodCallsCombo = new javax.swing.JComboBox();
199.127 + throwsKeywordLabel = new javax.swing.JLabel();
199.128 + throwsKeywordCombo = new javax.swing.JComboBox();
199.129 + throwsListLabel = new javax.swing.JLabel();
199.130 + throwsListCombo = new javax.swing.JComboBox();
199.131 + arrayInitLabel = new javax.swing.JLabel();
199.132 + arrayInitCombo = new javax.swing.JComboBox();
199.133 + forLabel = new javax.swing.JLabel();
199.134 + forCombo = new javax.swing.JComboBox();
199.135 + forStatementLabel = new javax.swing.JLabel();
199.136 + forStatementCombo = new javax.swing.JComboBox();
199.137 + ifStatementLabel = new javax.swing.JLabel();
199.138 + ifStatementCombo = new javax.swing.JComboBox();
199.139 + whileStatementLabel = new javax.swing.JLabel();
199.140 + whileStatementComboBox = new javax.swing.JComboBox();
199.141 + doWhileStatementLabel = new javax.swing.JLabel();
199.142 + doWhileStatementCombo = new javax.swing.JComboBox();
199.143 + assertLabel = new javax.swing.JLabel();
199.144 + assertCombo = new javax.swing.JComboBox();
199.145 + enumConstantsLabel = new javax.swing.JLabel();
199.146 + enumConstantsCombo = new javax.swing.JComboBox();
199.147 + annotationsLabel = new javax.swing.JLabel();
199.148 + annotationsCombo = new javax.swing.JComboBox();
199.149 + binaryOpsLabel = new javax.swing.JLabel();
199.150 + binaryOpsCombo = new javax.swing.JComboBox();
199.151 + ternaryOpsLabel = new javax.swing.JLabel();
199.152 + ternaryOpsCombo = new javax.swing.JComboBox();
199.153 + assignOpsLabel = new javax.swing.JLabel();
199.154 + assignOpsCombo = new javax.swing.JComboBox();
199.155 + spacerPanel1 = new javax.swing.JPanel();
199.156 +
199.157 + setName(org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_Wrapping")); // NOI18N
199.158 + setOpaque(false);
199.159 + setLayout(new java.awt.BorderLayout());
199.160 +
199.161 + scrollPane.setMinimumSize(new java.awt.Dimension(300, 200));
199.162 + scrollPane.setPreferredSize(new java.awt.Dimension(350, 600));
199.163 +
199.164 + panel1.setOpaque(false);
199.165 + panel1.setLayout(new java.awt.GridBagLayout());
199.166 +
199.167 + extendsImplemetsKeywordLabel.setLabelFor(extendsImplementsKeywordCombo);
199.168 + org.openide.awt.Mnemonics.setLocalizedText(extendsImplemetsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsKeyword")); // NOI18N
199.169 + gridBagConstraints = new java.awt.GridBagConstraints();
199.170 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.171 + gridBagConstraints.insets = new java.awt.Insets(8, 8, 4, 0);
199.172 + panel1.add(extendsImplemetsKeywordLabel, gridBagConstraints);
199.173 +
199.174 + extendsImplementsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.175 + gridBagConstraints = new java.awt.GridBagConstraints();
199.176 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.177 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.178 + gridBagConstraints.weightx = 1.0;
199.179 + gridBagConstraints.insets = new java.awt.Insets(8, 6, 4, 8);
199.180 + panel1.add(extendsImplementsKeywordCombo, gridBagConstraints);
199.181 +
199.182 + extendsImplementsListLabel.setLabelFor(extendsImplementsListCombo);
199.183 + org.openide.awt.Mnemonics.setLocalizedText(extendsImplementsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_extendsImplementsList")); // NOI18N
199.184 + gridBagConstraints = new java.awt.GridBagConstraints();
199.185 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.186 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.187 + panel1.add(extendsImplementsListLabel, gridBagConstraints);
199.188 +
199.189 + extendsImplementsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.190 + gridBagConstraints = new java.awt.GridBagConstraints();
199.191 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.192 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.193 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.194 + panel1.add(extendsImplementsListCombo, gridBagConstraints);
199.195 +
199.196 + methodParamsLabel.setLabelFor(methodParamsCombo);
199.197 + org.openide.awt.Mnemonics.setLocalizedText(methodParamsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodParameters")); // NOI18N
199.198 + gridBagConstraints = new java.awt.GridBagConstraints();
199.199 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.200 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.201 + panel1.add(methodParamsLabel, gridBagConstraints);
199.202 +
199.203 + methodParamsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.204 + gridBagConstraints = new java.awt.GridBagConstraints();
199.205 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.206 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.207 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.208 + panel1.add(methodParamsCombo, gridBagConstraints);
199.209 +
199.210 + methodCallArgsLabel.setLabelFor(methodCallArgsCombo);
199.211 + org.openide.awt.Mnemonics.setLocalizedText(methodCallArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_methodCallArgs")); // NOI18N
199.212 + gridBagConstraints = new java.awt.GridBagConstraints();
199.213 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.214 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.215 + panel1.add(methodCallArgsLabel, gridBagConstraints);
199.216 +
199.217 + methodCallArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.218 + gridBagConstraints = new java.awt.GridBagConstraints();
199.219 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.220 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.221 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.222 + panel1.add(methodCallArgsCombo, gridBagConstraints);
199.223 +
199.224 + annotationArgsLabel.setLabelFor(annotationArgsCombo);
199.225 + org.openide.awt.Mnemonics.setLocalizedText(annotationArgsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotationArgs")); // NOI18N
199.226 + gridBagConstraints = new java.awt.GridBagConstraints();
199.227 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.228 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.229 + panel1.add(annotationArgsLabel, gridBagConstraints);
199.230 +
199.231 + annotationArgsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.232 + gridBagConstraints = new java.awt.GridBagConstraints();
199.233 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.234 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.235 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.236 + panel1.add(annotationArgsCombo, gridBagConstraints);
199.237 +
199.238 + chainedMethodCallsLabel.setLabelFor(chainedMethodCallsCombo);
199.239 + org.openide.awt.Mnemonics.setLocalizedText(chainedMethodCallsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_chainedMethodCalls")); // NOI18N
199.240 + gridBagConstraints = new java.awt.GridBagConstraints();
199.241 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.242 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.243 + panel1.add(chainedMethodCallsLabel, gridBagConstraints);
199.244 +
199.245 + chainedMethodCallsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.246 + gridBagConstraints = new java.awt.GridBagConstraints();
199.247 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.248 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.249 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.250 + panel1.add(chainedMethodCallsCombo, gridBagConstraints);
199.251 +
199.252 + throwsKeywordLabel.setLabelFor(throwsKeywordCombo);
199.253 + org.openide.awt.Mnemonics.setLocalizedText(throwsKeywordLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsKeyword")); // NOI18N
199.254 + gridBagConstraints = new java.awt.GridBagConstraints();
199.255 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.256 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.257 + panel1.add(throwsKeywordLabel, gridBagConstraints);
199.258 +
199.259 + throwsKeywordCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.260 + gridBagConstraints = new java.awt.GridBagConstraints();
199.261 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.262 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.263 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.264 + panel1.add(throwsKeywordCombo, gridBagConstraints);
199.265 +
199.266 + throwsListLabel.setLabelFor(throwsListCombo);
199.267 + org.openide.awt.Mnemonics.setLocalizedText(throwsListLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_throwsList")); // NOI18N
199.268 + gridBagConstraints = new java.awt.GridBagConstraints();
199.269 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.270 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.271 + panel1.add(throwsListLabel, gridBagConstraints);
199.272 +
199.273 + throwsListCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.274 + gridBagConstraints = new java.awt.GridBagConstraints();
199.275 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.276 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.277 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.278 + panel1.add(throwsListCombo, gridBagConstraints);
199.279 +
199.280 + arrayInitLabel.setLabelFor(arrayInitCombo);
199.281 + org.openide.awt.Mnemonics.setLocalizedText(arrayInitLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_arrayInit")); // NOI18N
199.282 + gridBagConstraints = new java.awt.GridBagConstraints();
199.283 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.284 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.285 + panel1.add(arrayInitLabel, gridBagConstraints);
199.286 +
199.287 + arrayInitCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.288 + gridBagConstraints = new java.awt.GridBagConstraints();
199.289 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.290 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.291 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.292 + panel1.add(arrayInitCombo, gridBagConstraints);
199.293 +
199.294 + forLabel.setLabelFor(forCombo);
199.295 + org.openide.awt.Mnemonics.setLocalizedText(forLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_for")); // NOI18N
199.296 + gridBagConstraints = new java.awt.GridBagConstraints();
199.297 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.298 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.299 + panel1.add(forLabel, gridBagConstraints);
199.300 +
199.301 + forCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.302 + gridBagConstraints = new java.awt.GridBagConstraints();
199.303 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.304 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.305 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.306 + panel1.add(forCombo, gridBagConstraints);
199.307 +
199.308 + forStatementLabel.setLabelFor(forStatementCombo);
199.309 + org.openide.awt.Mnemonics.setLocalizedText(forStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_forStatement")); // NOI18N
199.310 + gridBagConstraints = new java.awt.GridBagConstraints();
199.311 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.312 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.313 + panel1.add(forStatementLabel, gridBagConstraints);
199.314 +
199.315 + forStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.316 + gridBagConstraints = new java.awt.GridBagConstraints();
199.317 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.318 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.319 + gridBagConstraints.weightx = 1.0;
199.320 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.321 + panel1.add(forStatementCombo, gridBagConstraints);
199.322 +
199.323 + ifStatementLabel.setLabelFor(ifStatementCombo);
199.324 + org.openide.awt.Mnemonics.setLocalizedText(ifStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ifStatement")); // NOI18N
199.325 + gridBagConstraints = new java.awt.GridBagConstraints();
199.326 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.327 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.328 + panel1.add(ifStatementLabel, gridBagConstraints);
199.329 +
199.330 + ifStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.331 + gridBagConstraints = new java.awt.GridBagConstraints();
199.332 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.333 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.334 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.335 + panel1.add(ifStatementCombo, gridBagConstraints);
199.336 +
199.337 + whileStatementLabel.setLabelFor(whileStatementComboBox);
199.338 + org.openide.awt.Mnemonics.setLocalizedText(whileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_whileStatement")); // NOI18N
199.339 + gridBagConstraints = new java.awt.GridBagConstraints();
199.340 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.341 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.342 + panel1.add(whileStatementLabel, gridBagConstraints);
199.343 +
199.344 + whileStatementComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.345 + gridBagConstraints = new java.awt.GridBagConstraints();
199.346 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.347 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.348 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.349 + panel1.add(whileStatementComboBox, gridBagConstraints);
199.350 +
199.351 + doWhileStatementLabel.setLabelFor(doWhileStatementCombo);
199.352 + org.openide.awt.Mnemonics.setLocalizedText(doWhileStatementLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_doWhileStatement")); // NOI18N
199.353 + gridBagConstraints = new java.awt.GridBagConstraints();
199.354 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.355 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.356 + panel1.add(doWhileStatementLabel, gridBagConstraints);
199.357 +
199.358 + doWhileStatementCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.359 + gridBagConstraints = new java.awt.GridBagConstraints();
199.360 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.361 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.362 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.363 + panel1.add(doWhileStatementCombo, gridBagConstraints);
199.364 +
199.365 + assertLabel.setLabelFor(assertCombo);
199.366 + org.openide.awt.Mnemonics.setLocalizedText(assertLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assert")); // NOI18N
199.367 + gridBagConstraints = new java.awt.GridBagConstraints();
199.368 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.369 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.370 + panel1.add(assertLabel, gridBagConstraints);
199.371 +
199.372 + assertCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.373 + gridBagConstraints = new java.awt.GridBagConstraints();
199.374 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.375 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.376 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.377 + panel1.add(assertCombo, gridBagConstraints);
199.378 +
199.379 + enumConstantsLabel.setLabelFor(enumConstantsCombo);
199.380 + org.openide.awt.Mnemonics.setLocalizedText(enumConstantsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_enumConstants")); // NOI18N
199.381 + gridBagConstraints = new java.awt.GridBagConstraints();
199.382 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.383 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.384 + panel1.add(enumConstantsLabel, gridBagConstraints);
199.385 +
199.386 + enumConstantsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.387 + gridBagConstraints = new java.awt.GridBagConstraints();
199.388 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.389 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.390 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.391 + panel1.add(enumConstantsCombo, gridBagConstraints);
199.392 +
199.393 + annotationsLabel.setLabelFor(annotationsCombo);
199.394 + org.openide.awt.Mnemonics.setLocalizedText(annotationsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_annotations")); // NOI18N
199.395 + gridBagConstraints = new java.awt.GridBagConstraints();
199.396 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.397 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.398 + panel1.add(annotationsLabel, gridBagConstraints);
199.399 +
199.400 + annotationsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.401 + gridBagConstraints = new java.awt.GridBagConstraints();
199.402 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.403 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.404 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.405 + panel1.add(annotationsCombo, gridBagConstraints);
199.406 +
199.407 + binaryOpsLabel.setLabelFor(binaryOpsCombo);
199.408 + org.openide.awt.Mnemonics.setLocalizedText(binaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_binaryOps")); // NOI18N
199.409 + gridBagConstraints = new java.awt.GridBagConstraints();
199.410 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.411 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.412 + panel1.add(binaryOpsLabel, gridBagConstraints);
199.413 +
199.414 + binaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.415 + gridBagConstraints = new java.awt.GridBagConstraints();
199.416 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.417 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.418 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.419 + panel1.add(binaryOpsCombo, gridBagConstraints);
199.420 +
199.421 + ternaryOpsLabel.setLabelFor(ternaryOpsCombo);
199.422 + org.openide.awt.Mnemonics.setLocalizedText(ternaryOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_ternaryOps")); // NOI18N
199.423 + gridBagConstraints = new java.awt.GridBagConstraints();
199.424 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.425 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.426 + panel1.add(ternaryOpsLabel, gridBagConstraints);
199.427 +
199.428 + ternaryOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.429 + gridBagConstraints = new java.awt.GridBagConstraints();
199.430 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.431 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.432 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.433 + panel1.add(ternaryOpsCombo, gridBagConstraints);
199.434 +
199.435 + assignOpsLabel.setLabelFor(assignOpsCombo);
199.436 + org.openide.awt.Mnemonics.setLocalizedText(assignOpsLabel, org.openide.util.NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assignOps")); // NOI18N
199.437 + gridBagConstraints = new java.awt.GridBagConstraints();
199.438 + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
199.439 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 4, 0);
199.440 + panel1.add(assignOpsLabel, gridBagConstraints);
199.441 +
199.442 + assignOpsCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
199.443 + gridBagConstraints = new java.awt.GridBagConstraints();
199.444 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.445 + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
199.446 + gridBagConstraints.insets = new java.awt.Insets(0, 6, 4, 8);
199.447 + panel1.add(assignOpsCombo, gridBagConstraints);
199.448 +
199.449 + spacerPanel1.setOpaque(false);
199.450 + gridBagConstraints = new java.awt.GridBagConstraints();
199.451 + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
199.452 + gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
199.453 + gridBagConstraints.weighty = 1.0;
199.454 + gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 8);
199.455 + panel1.add(spacerPanel1, gridBagConstraints);
199.456 +
199.457 + scrollPane.setViewportView(panel1);
199.458 +
199.459 + add(scrollPane, java.awt.BorderLayout.CENTER);
199.460 + }// </editor-fold>//GEN-END:initComponents
199.461 +
199.462 + // Variables declaration - do not modify//GEN-BEGIN:variables
199.463 + private javax.swing.JComboBox annotationArgsCombo;
199.464 + private javax.swing.JLabel annotationArgsLabel;
199.465 + private javax.swing.JComboBox annotationsCombo;
199.466 + private javax.swing.JLabel annotationsLabel;
199.467 + private javax.swing.JComboBox arrayInitCombo;
199.468 + private javax.swing.JLabel arrayInitLabel;
199.469 + private javax.swing.JComboBox assertCombo;
199.470 + private javax.swing.JLabel assertLabel;
199.471 + private javax.swing.JComboBox assignOpsCombo;
199.472 + private javax.swing.JLabel assignOpsLabel;
199.473 + private javax.swing.JComboBox binaryOpsCombo;
199.474 + private javax.swing.JLabel binaryOpsLabel;
199.475 + private javax.swing.JComboBox chainedMethodCallsCombo;
199.476 + private javax.swing.JLabel chainedMethodCallsLabel;
199.477 + private javax.swing.JComboBox doWhileStatementCombo;
199.478 + private javax.swing.JLabel doWhileStatementLabel;
199.479 + private javax.swing.JComboBox enumConstantsCombo;
199.480 + private javax.swing.JLabel enumConstantsLabel;
199.481 + private javax.swing.JComboBox extendsImplementsKeywordCombo;
199.482 + private javax.swing.JComboBox extendsImplementsListCombo;
199.483 + private javax.swing.JLabel extendsImplementsListLabel;
199.484 + private javax.swing.JLabel extendsImplemetsKeywordLabel;
199.485 + private javax.swing.JComboBox forCombo;
199.486 + private javax.swing.JLabel forLabel;
199.487 + private javax.swing.JComboBox forStatementCombo;
199.488 + private javax.swing.JLabel forStatementLabel;
199.489 + private javax.swing.JComboBox ifStatementCombo;
199.490 + private javax.swing.JLabel ifStatementLabel;
199.491 + private javax.swing.JComboBox methodCallArgsCombo;
199.492 + private javax.swing.JLabel methodCallArgsLabel;
199.493 + private javax.swing.JComboBox methodParamsCombo;
199.494 + private javax.swing.JLabel methodParamsLabel;
199.495 + private javax.swing.JPanel panel1;
199.496 + private javax.swing.JScrollPane scrollPane;
199.497 + private javax.swing.JPanel spacerPanel1;
199.498 + private javax.swing.JComboBox ternaryOpsCombo;
199.499 + private javax.swing.JLabel ternaryOpsLabel;
199.500 + private javax.swing.JComboBox throwsKeywordCombo;
199.501 + private javax.swing.JLabel throwsKeywordLabel;
199.502 + private javax.swing.JComboBox throwsListCombo;
199.503 + private javax.swing.JLabel throwsListLabel;
199.504 + private javax.swing.JComboBox whileStatementComboBox;
199.505 + private javax.swing.JLabel whileStatementLabel;
199.506 + // End of variables declaration//GEN-END:variables
199.507 +
199.508 +}
200.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
200.2 +++ b/python.source/src/org/netbeans/modules/python/source/ui/NumericKeyListener.java Wed Sep 02 20:31:18 2015 +0200
200.3 @@ -0,0 +1,74 @@
200.4 +/*
200.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
200.6 + *
200.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
200.8 + *
200.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
200.10 + * Other names may be trademarks of their respective owners.
200.11 + *
200.12 + * The contents of this file are subject to the terms of either the GNU
200.13 + * General Public License Version 2 only ("GPL") or the Common
200.14 + * Development and Distribution License("CDDL") (collectively, the
200.15 + * "License"). You may not use this file except in compliance with the
200.16 + * License. You can obtain a copy of the License at
200.17 + * http://www.netbeans.org/cddl-gplv2.html
200.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
200.19 + * specific language governing permissions and limitations under the
200.20 + * License. When distributing the software, include this License Header
200.21 + * Notice in each file and include the License file at
200.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
200.23 + * particular file as subject to the "Classpath" exception as provided
200.24 + * by Oracle in the GPL Version 2 section of the License file that
200.25 + * accompanied this code. If applicable, add the following below the
200.26 + * License Header, with the fields enclosed by brackets [] replaced by
200.27 + * your own identifying information:
200.28 + * "Portions Copyrighted [year] [name of copyright owner]"
200.29 + *
200.30 + * If you wish your version of this file to be governed by only the CDDL
200.31 + * or only the GPL Version 2, indicate your decision by adding
200.32 + * "[Contributor] elects to include this software in this distribution
200.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
200.34 + * single choice of license, a recipient has the option to distribute
200.35 + * your version of this file under either the CDDL, the GPL Version 2 or
200.36 + * to extend the choice of license to its licensees as provided above.
200.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
200.38 + * Version 2 license, then the option applies only if the new code is
200.39 + * made subject to such option by the copyright holder.
200.40 + *
200.41 + * Contributor(s):
200.42 + *
200.43 + * Portions Copyrighted 2008 Sun Microsystems, Inc.
200.44 + */
200.45 +package org.netbeans.modules.python.editor.options;
200.46 +
200.47 +import java.awt.Component;
200.48 +import java.awt.event.KeyEvent;
200.49 +import java.awt.event.KeyListener;
200.50 +
200.51 +/**
200.52 + *
200.53 + * @author tester
200.54 + */
200.55 +public class NumericKeyListener implements KeyListener {
200.56 + public NumericKeyListener() {
200.57 + }
200.58 +
200.59 + @Override
200.60 + public void keyPressed(KeyEvent evt) {
200.61 + }
200.62 +
200.63 + @Override
200.64 + public void keyReleased(KeyEvent evt) {
200.65 + }
200.66 +
200.67 + @Override
200.68 + public void keyTyped(KeyEvent evt) {
200.69 + if (!Character.isDigit(evt.getKeyChar()) && !Character.isISOControl(evt.getKeyChar())) {
200.70 + evt.consume();
200.71 + Component c = evt.getComponent();
200.72 + if (c != null) {
200.73 + c.getToolkit().beep();
200.74 + }
200.75 + }
200.76 + }
200.77 +}