diff --git a/python/psi-api/src/com/jetbrains/python/PythonFileType.java b/python/psi-api/src/com/jetbrains/python/PythonFileType.java index d940be65f732..d3d78c5ab98f 100644 --- a/python/psi-api/src/com/jetbrains/python/PythonFileType.java +++ b/python/psi-api/src/com/jetbrains/python/PythonFileType.java @@ -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; diff --git a/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java b/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java index 536074e51d39..0b5c93c8dbaa 100644 --- a/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyByteLiteralInspection.java @@ -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; diff --git a/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java b/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java index 58e97044c4ab..d41cfbeea3cb 100644 --- a/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyMandatoryEncodingInspection.java @@ -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(); diff --git a/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java b/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java index 3038b64710d1..5fd0e565a6f8 100644 --- a/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java @@ -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; diff --git a/python/testSrc/com/jetbrains/python/PyEncodingTest.java b/python/testSrc/com/jetbrains/python/PyEncodingTest.java index cccd6d45cfde..608b8396c04a 100644 --- a/python/testSrc/com/jetbrains/python/PyEncodingTest.java +++ b/python/testSrc/com/jetbrains/python/PyEncodingTest.java @@ -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())); } }