Merge branch 'python-fixes'

This commit is contained in:
Andrey Vlasovskikh
2014-02-28 18:38:15 +04:00
6 changed files with 33 additions and 21 deletions
@@ -16,11 +16,15 @@
package com.jetbrains.python;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import icons.PythonPsiApiIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +45,7 @@ import java.util.regex.Pattern;
*/
public class PythonFileType extends LanguageFileType {
private static final Pattern ENCODING_PATTERN = Pattern.compile("coding[:=]\\s*([-\\w.]+)");
public static final int MAX_CHARSET_ENCODING_LINE = 2;
public static PythonFileType INSTANCE = new PythonFileType();
@@ -100,14 +105,28 @@ public class PythonFileType extends LanguageFileType {
}
@Nullable
public static String getCharsetFromEncodingDeclaration(String content) {
public static String getCharsetFromEncodingDeclaration(@NotNull PsiFile file) {
final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
final String content;
if (document != null && document.getLineCount() > MAX_CHARSET_ENCODING_LINE) {
final int offset = document.getLineEndOffset(MAX_CHARSET_ENCODING_LINE);
content = document.getText(TextRange.create(0, offset));
}
else {
content = file.getText();
}
return getCharsetFromEncodingDeclaration(content);
}
@Nullable
private static String getCharsetFromEncodingDeclaration(@Nullable String content) {
if (content == null || content.isEmpty()) {
return null;
}
try {
final BufferedReader reader = new BufferedReader(new StringReader(content));
try {
for (int i = 0; i < 2; i++) {
for (int i = 0; i < MAX_CHARSET_ENCODING_LINE; i++) {
final String line = reader.readLine();
if (line == null) {
return null;
@@ -75,7 +75,7 @@ public class PyByteLiteralInspection extends PyInspection {
);
}
final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file.getText());
final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file);
try {
if (charsetString != null && !Charset.forName(charsetString).equals(Charset.forName("US-ASCII")))
default_bytes = false;
@@ -62,7 +62,7 @@ public class PyMandatoryEncodingInspection extends PyInspection {
@Override
public void visitPyFile(PyFile node) {
final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(node.getText());
final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(node);
if (charsetString == null) {
TextRange tr = new TextRange(0,0);
ProblemsHolder holder = getHolder();
@@ -69,7 +69,7 @@ public class PyNonAsciiCharInspection extends PyInspection {
if (LanguageLevel.forElement(node).isPy3K()) return;
PsiFile file = node.getContainingFile(); // can't cache this in the instance, alas
if (file == null) return;
final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file.getText());
final String charsetString = PythonFileType.getCharsetFromEncodingDeclaration(file);
boolean hasNonAscii = false;
@@ -24,7 +24,8 @@ import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.QualifiedName;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.hash.HashSet;
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import com.jetbrains.python.psi.types.PyModuleType;
@@ -34,9 +35,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
@@ -71,17 +70,10 @@ public class PyPep8NamingInspection extends PyInspection {
public void visitPyAssignmentStatement(PyAssignmentStatement node) {
final PyFunction function = PsiTreeUtil.getParentOfType(node, PyFunction.class, true, PyClass.class);
if (function == null) return;
final Collection<PyGlobalStatement> globalStatements = PsiTreeUtil.findChildrenOfType(function, PyGlobalStatement.class);
final Set<String> globals = new HashSet<String>();
for (PyGlobalStatement statement : globalStatements) {
final PyTargetExpression[] statementGlobals = statement.getGlobals();
for (PyTargetExpression global : statementGlobals) {
globals.add(global.getName());
}
}
final Scope scope = ControlFlowCache.getScope(function);
for (PyExpression expression : node.getTargets()) {
final String name = expression.getName();
if (name == null || globals.contains(name)) continue;
if (name == null || scope.isGlobal(name)) continue;
if (expression instanceof PyTargetExpression) {
final PyExpression qualifier = ((PyTargetExpression)expression).getQualifier();
if (qualifier != null) {
@@ -15,12 +15,12 @@
*/
package com.jetbrains.python;
import junit.framework.TestCase;
import com.jetbrains.python.fixtures.PyTestCase;
/**
* @author yole
*/
public class PyEncodingTest extends TestCase {
public class PyEncodingTest extends PyTestCase {
public void testEncodingEmacs() {
doTest("#!/usr/bin/python\n# -*- coding: iso-8859-15 -*-\nimport os, sys", "iso-8859-15");
}
@@ -33,7 +33,8 @@ public class PyEncodingTest extends TestCase {
doTest("#!/usr/local/bin/python\n# coding: latin-1\nimport os, sys", "iso-8859-1");
}
private static void doTest(final String text, final String expected) {
assertEquals(expected, PythonFileType.getCharsetFromEncodingDeclaration(text));
private void doTest(final String text, final String expected) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
assertEquals(expected, PythonFileType.getCharsetFromEncodingDeclaration(myFixture.getFile()));
}
}