| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.jetbrains.python; |
| |
| import com.intellij.codeInsight.intention.IntentionAction; |
| import com.intellij.testFramework.TestDataFile; |
| import com.intellij.testFramework.TestDataPath; |
| import com.jetbrains.python.codeInsight.PyCodeInsightSettings; |
| import com.jetbrains.python.documentation.DocStringFormat; |
| import com.jetbrains.python.documentation.PyDocumentationSettings; |
| import com.jetbrains.python.fixtures.PyTestCase; |
| import com.jetbrains.python.inspections.*; |
| import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection; |
| import com.jetbrains.python.psi.LanguageLevel; |
| import org.jetbrains.annotations.NonNls; |
| |
| /** |
| * @author dcheryasov |
| */ |
| @TestDataPath("$CONTENT_ROOT/../testData/inspections/") |
| public class PyQuickFixTest extends PyTestCase { |
| |
| public void testAddImport() { |
| doInspectionTest(new String[] { "AddImport.py", "ImportTarget.py" }, PyUnresolvedReferencesInspection.class, "Import 'ImportTarget'", true, true); |
| } |
| |
| public void testAddImportDoc() { |
| doInspectionTest(new String[] { "AddImportDoc.py", "ImportTarget.py" }, PyUnresolvedReferencesInspection.class, "Import 'ImportTarget'", true, true); |
| } |
| |
| public void testAddImportDocComment() { // PY-728 |
| doInspectionTest(new String[] { "AddImportDocComment.py", "ImportTarget.py" }, PyUnresolvedReferencesInspection.class, "Import 'ImportTarget'", true, true); |
| } |
| |
| public void testImportFromModule() { |
| doInspectionTest(new String[] { "importFromModule/foo/bar.py", "importFromModule/foo/baz.py", "importFromModule/foo/__init__.py" }, |
| PyUnresolvedReferencesInspection.class, "Import 'importFromModule.foo.baz'", true, true); |
| } |
| |
| public void testImportFromModuleStar() { // PY-6302 |
| myFixture.enableInspections(PyUnresolvedReferencesInspection.class); |
| myFixture.copyDirectoryToProject("importFromModuleStar", ""); |
| myFixture.configureFromTempProjectFile("source.py"); |
| myFixture.checkHighlighting(true, false, false); |
| final IntentionAction intentionAction = myFixture.findSingleIntention("Import 'target.xyzzy()'"); |
| assertNotNull(intentionAction); |
| myFixture.launchAction(intentionAction); |
| myFixture.checkResultByFile("importFromModuleStar/source_after.py"); |
| } |
| |
| public void testQualifyByImport() { |
| final PyCodeInsightSettings settings = PyCodeInsightSettings.getInstance(); |
| boolean oldPreferFrom = settings.PREFER_FROM_IMPORT; |
| boolean oldHighlightUnused = settings.HIGHLIGHT_UNUSED_IMPORTS; |
| settings.PREFER_FROM_IMPORT = false; |
| settings.HIGHLIGHT_UNUSED_IMPORTS = false; |
| try { |
| doInspectionTest(new String[]{"QualifyByImport.py", "QualifyByImportFoo.py"}, PyUnresolvedReferencesInspection.class, PyBundle.message("ACT.qualify.with.module"), true, true); |
| } |
| finally { |
| settings.PREFER_FROM_IMPORT = oldPreferFrom; |
| settings.HIGHLIGHT_UNUSED_IMPORTS = oldHighlightUnused; |
| } |
| } |
| |
| public void testAddToImportFromList() { |
| final PyCodeInsightSettings settings = PyCodeInsightSettings.getInstance(); |
| boolean oldHighlightUnused = settings.HIGHLIGHT_UNUSED_IMPORTS; |
| settings.HIGHLIGHT_UNUSED_IMPORTS = false; |
| try { |
| doInspectionTest(new String[]{"AddToImportFromList.py", "AddToImportFromFoo.py"}, PyUnresolvedReferencesInspection.class, "Import 'foo(a) from AddToImportFromFoo'", true, true); |
| } |
| finally { |
| settings.HIGHLIGHT_UNUSED_IMPORTS = oldHighlightUnused; |
| } |
| } |
| // TODO: add a test for multiple variants of above |
| |
| // TODO: add tests for stub indexes-based autoimport of unimported somehow. |
| |
| public void testAddSelf() { |
| doInspectionTest("AddSelf.py", PyMethodParametersInspection.class, PyBundle.message("QFIX.add.parameter.self", "self"), true, true); |
| } |
| |
| public void testReplacePrint() { |
| doInspectionTest("ReplacePrint.py", PyCompatibilityInspection.class, PyBundle.message("QFIX.statement.effect"), true, true); |
| } |
| |
| public void testAddSelfFunction() { //PY-4556 |
| doInspectionTest("AddSelfFunction.py", |
| PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.unresolved.reference", "get_a", "self"), true, true); |
| } |
| |
| public void testAddSelfToClassmethod() { //PY-9721 |
| doInspectionTest("AddSelfToClassmethod.py", |
| PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.unresolved.reference", "foo", "cls"), true, true); |
| } |
| |
| public void testAddCls() { |
| doInspectionTest("AddCls.py", PyMethodParametersInspection.class, PyBundle.message("QFIX.add.parameter.self", "cls"), true, true); |
| } |
| |
| public void testRenameToSelf() { |
| doInspectionTest("RenameToSelf.py", PyMethodParametersInspection.class, PyBundle.message("QFIX.rename.parameter.to.$0", "self"), true, |
| true); |
| } |
| |
| public void testRemoveTrailingSemicolon() { |
| doInspectionTest("RemoveTrailingSemicolon.py", PyTrailingSemicolonInspection.class, PyBundle.message("QFIX.remove.trailing.semicolon"), |
| true, true); |
| } |
| |
| public void testDictCreation() { |
| doInspectionTest("DictCreation.py", PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true); |
| } |
| |
| public void testDictCreationTuple() { //PY-6283 |
| doInspectionTest("DictCreationTuple.py", PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true); |
| } |
| |
| public void testDictCreationDuplicate() { //PY-7318 |
| doInspectionTest("DictCreationDuplicate.py", PyDictCreationInspection.class, PyBundle.message("QFIX.dict.creation"), true, true); |
| } |
| |
| public void testTransformClassicClass() { |
| doInspectionTest("TransformClassicClass.py", PyClassicStyleClassInspection.class, |
| PyBundle.message("QFIX.classic.class.transform"), true, true); |
| } |
| |
| public void testAddGlobalQuickFix() { |
| doInspectionTest("AddGlobalStatement.py", PyUnboundLocalVariableInspection.class, |
| PyBundle.message("QFIX.add.global"), true, true); |
| } |
| |
| public void testAddGlobalExistingQuickFix() { |
| doInspectionTest("AddGlobalExistingStatement.py", PyUnboundLocalVariableInspection.class, |
| PyBundle.message("QFIX.add.global"), true, true); |
| } |
| |
| public void testSimplifyBooleanCheckQuickFix() { |
| doInspectionTest("SimplifyBooleanCheck.py", PySimplifyBooleanCheckInspection.class, |
| PyBundle.message("QFIX.simplify.$0", "b"), true, true); |
| } |
| |
| public void testFromFutureImportQuickFix() { |
| doInspectionTest("MoveFromFutureImport.py", PyFromFutureImportInspection.class, |
| PyBundle.message("QFIX.move.from.future.import"), true, true); |
| } |
| |
| public void testFromFutureImportQuickFixDocString() { // PY-10080 |
| doInspectionTest("MoveFromFutureImportDocString.py", PyFromFutureImportInspection.class, |
| PyBundle.message("QFIX.move.from.future.import"), true, true); |
| } |
| |
| public void testComparisonWithNoneQuickFix() { |
| doInspectionTest("ComparisonWithNone.py", PyComparisonWithNoneInspection.class, |
| PyBundle.message("QFIX.replace.equality"), true, true); |
| } |
| |
| public void testAddClassFix() { |
| doInspectionTest("AddClass.py", PyUnresolvedReferencesInspection.class, "Create class 'Xyzzy'", true, true); |
| } |
| |
| |
| public void testAddFunctionToModule() { // PY-1602 |
| doInspectionTest( |
| "AddFunctionToModule.py", |
| PyUnresolvedReferencesInspection.class, |
| PyBundle.message("QFIX.NAME.add.function.$0.to.module.$1", "frob", "AddFunctionToModule.py"), |
| true, true |
| ); |
| } |
| |
| public void testRedundantParentheses() { // PY-1470 |
| String[] testFiles = new String[]{"RedundantParentheses.py"}; |
| myFixture.enableInspections(PyRedundantParenthesesInspection.class); |
| myFixture.configureByFiles(testFiles); |
| myFixture.checkHighlighting(true, false, true); |
| final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("QFIX.redundant.parentheses")); |
| assertNotNull(intentionAction); |
| myFixture.launchAction(intentionAction); |
| myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after")); |
| |
| } |
| |
| public void testRedundantParenthesesBoolean() { // PY-3095 |
| doInspectionTest("RedundantParenthesesBoolean.py", PyRedundantParenthesesInspection.class, |
| PyBundle.message("QFIX.redundant.parentheses"), true, true); |
| } |
| |
| public void testRedundantParenthesesMore() { // PY-3239 |
| doInspectionTest("RedundantParenthesesMore.py", PyRedundantParenthesesInspection.class, |
| PyBundle.message("QFIX.redundant.parentheses"), true, true); |
| } |
| |
| public void testRedundantParenthesesParenthesizedExpression() { // PY-12679 |
| doInspectionTest("RedundantParenthesesParenthesizedExpression.py", PyRedundantParenthesesInspection.class, |
| PyBundle.message("QFIX.redundant.parentheses"), true, true); |
| } |
| |
| public void testChainedComparisons() { // PY-1020 |
| doInspectionTest("ChainedComparisons.py", PyChainedComparisonsInspection.class, |
| PyBundle.message("QFIX.chained.comparison"), true, true); |
| } |
| |
| public void testChainedComparison1() { // PY-3126 |
| doInspectionTest("ChainedComparison1.py", PyChainedComparisonsInspection.class, |
| PyBundle.message("QFIX.chained.comparison"), true, true); |
| } |
| |
| public void testChainedComparison2() { // PY-3126 |
| doInspectionTest("ChainedComparison2.py", PyChainedComparisonsInspection.class, |
| PyBundle.message("QFIX.chained.comparison"), true, true); |
| } |
| |
| public void testChainedComparison3() { // PY-3126 |
| doInspectionTest("ChainedComparison3.py", PyChainedComparisonsInspection.class, |
| PyBundle.message("QFIX.chained.comparison"), true, true); |
| } |
| |
| public void testChainedComparison4() { // PY-5623 |
| doInspectionTest("ChainedComparison4.py", PyChainedComparisonsInspection.class, |
| PyBundle.message("QFIX.chained.comparison"), true, true); |
| } |
| |
| public void testChainedComparison5() { // PY-6467 |
| doInspectionTest("ChainedComparison5.py", PyChainedComparisonsInspection.class, |
| PyBundle.message("QFIX.chained.comparison"), true, true); |
| } |
| |
| public void testStatementEffect() { // PY-1362, PY-2585 |
| doInspectionTest("StatementEffect.py", PyStatementEffectInspection.class, |
| PyBundle.message("QFIX.statement.effect"), true, true); |
| } |
| |
| public void testStatementEffectIntroduceVariable() { // PY-1265 |
| doInspectionTest("StatementEffectIntroduceVariable.py", PyStatementEffectInspection.class, |
| PyBundle.message("QFIX.statement.effect.introduce.variable"), true, true); |
| } |
| |
| public void testReplacePrintEnd() { |
| runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() { |
| @Override |
| public void run() { |
| doInspectionTest("ReplacePrintEnd.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, true); |
| }}); |
| } |
| |
| public void testReplacePrintComment() { |
| runWithLanguageLevel(LanguageLevel.PYTHON34, new Runnable() { |
| @Override |
| public void run() { |
| doInspectionTest("ReplacePrintComment.py", PyStatementEffectInspection.class, PyBundle.message("QFIX.statement.effect"), true, |
| true); |
| }}); |
| } |
| |
| public void testUnresolvedWith() { // PY-2083 |
| setLanguageLevel(LanguageLevel.PYTHON25); |
| doInspectionTest("UnresolvedWith.py", PyUnresolvedReferencesInspection.class, |
| PyBundle.message("QFIX.unresolved.reference.add.future"), true, true); |
| } |
| |
| public void testUnresolvedRefCreateFunction() { // PY-2092 |
| doInspectionTest("UnresolvedRefCreateFunction.py", PyUnresolvedReferencesInspection.class, |
| PyBundle.message("QFIX.unresolved.reference.create.function.$0", "ref"), true, true); |
| } |
| |
| public void testUnresolvedRefNoCreateFunction() { |
| myFixture.enableInspections(PyUnresolvedReferencesInspection.class); |
| myFixture.configureByFile("UnresolvedRefNoCreateFunction.py"); |
| myFixture.checkHighlighting(true, false, false); |
| final IntentionAction intentionAction = myFixture.getAvailableIntention( |
| PyBundle.message("QFIX.unresolved.reference.create.function.$0", "ref")); |
| assertNull(intentionAction); |
| } |
| |
| public void testReplaceNotEqOperator() { |
| doInspectionTest("ReplaceNotEqOperator.py", PyCompatibilityInspection.class, |
| PyBundle.message("INTN.replace.noteq.operator"), true, true); |
| } |
| |
| public void testListCreation() { |
| doInspectionTest("ListCreation.py", PyListCreationInspection.class, |
| PyBundle.message("QFIX.list.creation"), true, true); |
| } |
| |
| public void testConvertSingleQuotedDocstring() { //PY-1445 |
| doInspectionTest("ConvertSingleQuotedDocstring.py", PySingleQuotedDocstringInspection.class, |
| PyBundle.message("QFIX.convert.single.quoted.docstring"), true, true); |
| } |
| |
| public void testConvertSingleQuotedDocstringEscape() { //PY-8926 |
| doInspectionTest("ConvertSingleQuotedDocstringEscape.py", PySingleQuotedDocstringInspection.class, |
| PyBundle.message("QFIX.convert.single.quoted.docstring"), true, true); |
| } |
| |
| public void testDefaultArgument() { //PY-3127 |
| doInspectionTest("DefaultArgument.py", PyDefaultArgumentInspection.class, |
| PyBundle.message("QFIX.default.argument"), true, true); |
| } |
| |
| public void testDefaultArgumentEmptyList() { |
| doInspectionTest("DefaultArgumentEmptyList.py", PyDefaultArgumentInspection.class, |
| PyBundle.message("QFIX.default.argument"), true, true); |
| } |
| |
| public void testPyArgumentEqualDefault() { //PY-3125 |
| doInspectionTest("ArgumentEqualDefault.py", PyArgumentEqualDefaultInspection.class, |
| PyBundle.message("QFIX.remove.argument.equal.default"), true, true); |
| } |
| |
| public void testAddCallSuper() { //PY-3315 |
| doInspectionTest("AddCallSuper.py", PyMissingConstructorInspection.class, |
| PyBundle.message("QFIX.add.super"), true, true); |
| } |
| |
| public void testAddCallSuper1() { //PY-4017 |
| doInspectionTest("AddCallSuper1.py", PyMissingConstructorInspection.class, |
| PyBundle.message("QFIX.add.super"), true, true); |
| } |
| |
| public void testAddCallSuperAnnotations() { |
| runWithLanguageLevel(LanguageLevel.PYTHON33, new Runnable() { |
| @Override |
| public void run() { |
| doInspectionTest("AddCallSuperAnnotations.py", |
| PyMissingConstructorInspection.class, |
| PyBundle.message("QFIX.add.super"), true, true); |
| } |
| }); |
| } |
| |
| public void testAddCallSuperPass() { //PY-8654 |
| doInspectionTest("AddCallSuperPass.py", PyMissingConstructorInspection.class, |
| PyBundle.message("QFIX.add.super"), true, true); |
| } |
| |
| public void testAddEncoding() { //PY-491 |
| doInspectionTest("AddEncoding.py", PyMandatoryEncodingInspection.class, |
| PyBundle.message("QFIX.add.encoding"), true, true); |
| } |
| |
| public void testRemoveDecorator() { //PY-3348 |
| doInspectionTest("RemoveDecorator.py", PyDecoratorInspection.class, |
| PyBundle.message("QFIX.remove.decorator"), true, true); |
| } |
| |
| public void testAddParameter() { |
| doInspectionTest("AddParameter.py", PyUnresolvedReferencesInspection.class, |
| PyBundle.message("QFIX.unresolved.reference.add.param.$0", "test"), true, true); |
| } |
| |
| public void testRenameUnresolvedReference() { //PY-6595 |
| doInspectionTest("RenameUnresolvedReference.py", PyUnresolvedReferencesInspection.class, |
| PyBundle.message("QFIX.rename.unresolved.reference"), true, true); |
| } |
| |
| public void testSetFunctionToLiteral() { //PY-3120 |
| setLanguageLevel(LanguageLevel.PYTHON27); |
| doInspectionTest("SetFunctionToLiteral.py", PySetFunctionToLiteralInspection.class, |
| PyBundle.message("QFIX.replace.function.set.with.literal"), true, true); |
| } |
| |
| public void testDictComprehensionToCall() { |
| doInspectionTest("DictComprehensionToCall.py", PyCompatibilityInspection.class, |
| PyBundle.message("INTN.convert.dict.comp.to"), true, true); |
| } |
| |
| public void testDocstringParams() { //PY-3394 |
| PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule()); |
| documentationSettings.setFormat(DocStringFormat.EPYTEXT); |
| try { |
| doInspectionTest("DocstringParams.py", PyDocstringInspection.class, |
| PyBundle.message("QFIX.docstring.add.$0", "b"), true, true); |
| } |
| finally { |
| documentationSettings.setFormat(DocStringFormat.PLAIN); |
| } |
| } |
| |
| public void testDocstringParams1() { |
| PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule()); |
| documentationSettings.setFormat(DocStringFormat.EPYTEXT); |
| try { |
| doInspectionTest("DocstringParams1.py", PyDocstringInspection.class, |
| PyBundle.message("QFIX.docstring.remove.$0", "c"), true, true); |
| } |
| finally { |
| documentationSettings.setFormat(DocStringFormat.PLAIN); |
| } |
| } |
| |
| public void testDocstringParams2() { //PY-4964 |
| PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule()); |
| documentationSettings.setFormat(DocStringFormat.EPYTEXT); |
| try { |
| doInspectionTest("DocstringParams2.py", PyDocstringInspection.class, |
| PyBundle.message("QFIX.docstring.add.$0", "ham"), true, true); |
| } |
| finally { |
| documentationSettings.setFormat(DocStringFormat.PLAIN); |
| } |
| } |
| |
| public void testUnnecessaryBackslash() { |
| String[] testFiles = new String[]{"UnnecessaryBackslash.py"}; |
| myFixture.enableInspections(PyUnnecessaryBackslashInspection.class); |
| myFixture.configureByFiles(testFiles); |
| myFixture.checkHighlighting(true, false, true); |
| IntentionAction intentionAction = myFixture.getAvailableIntention(PyBundle.message("QFIX.remove.unnecessary.backslash")); |
| assertNotNull(intentionAction); |
| myFixture.launchAction(intentionAction); |
| myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after")); |
| } |
| |
| public void testUnresolvedRefTrueFalse() { //PY-3051 |
| doInspectionTest("UnresolvedRefTrueFalse.py", PyUnresolvedReferencesInspection.class, |
| PyBundle.message("QFIX.unresolved.reference.replace.$0", "True"), true, true); |
| } |
| |
| public void testUnnecessaryBackslashInArgumentList() { |
| String[] testFiles = new String[]{"UnnecessaryBackslashInArguments.py"}; |
| myFixture.enableInspections(PyUnnecessaryBackslashInspection.class); |
| myFixture.configureByFiles(testFiles); |
| myFixture.checkHighlighting(true, false, true); |
| IntentionAction intentionAction = myFixture.getAvailableIntention(PyBundle.message("QFIX.remove.unnecessary.backslash")); |
| assertNotNull(intentionAction); |
| myFixture.launchAction(intentionAction); |
| myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after")); |
| } |
| |
| // PY-8788 |
| public void testRenameShadowingBuiltins() { |
| final String fileName = "RenameShadowingBuiltins.py"; |
| myFixture.configureByFile(fileName); |
| myFixture.enableInspections(PyShadowingBuiltinsInspection.class); |
| myFixture.checkHighlighting(true, false, true); |
| final IntentionAction intentionAction = myFixture.getAvailableIntention("Rename element"); |
| assertNotNull(intentionAction); |
| myFixture.launchAction(intentionAction); |
| myFixture.checkResultByFile(graftBeforeExt(fileName, "_after")); |
| } |
| |
| // PY-8788 |
| public void testRenameFunctionShadowingBuiltins() { |
| final String fileName = "RenameFunctionShadowingBuiltins.py"; |
| myFixture.configureByFile(fileName); |
| myFixture.enableInspections(PyShadowingBuiltinsInspection.class); |
| myFixture.checkHighlighting(true, false, true); |
| final IntentionAction intentionAction = myFixture.getAvailableIntention("Rename element"); |
| assertNotNull(intentionAction); |
| myFixture.launchAction(intentionAction); |
| myFixture.checkResultByFile(graftBeforeExt(fileName, "_after")); |
| } |
| |
| @Override |
| @NonNls |
| protected String getTestDataPath() { |
| return PythonTestUtil.getTestDataPath() + "/inspections/"; |
| } |
| |
| protected void doInspectionTest(@TestDataFile @NonNls String testFileName, |
| final Class inspectionClass, |
| @NonNls String quickFixName, |
| boolean applyFix, |
| boolean available) { |
| doInspectionTest(new String[]{testFileName}, inspectionClass, quickFixName, applyFix, available); |
| } |
| |
| /** |
| * Runs daemon passes and looks for given fix within infos. |
| * |
| * @param testFiles names of files to participate; first is used for inspection and then for check by "_after". |
| * @param inspectionClass what inspection to run |
| * @param quickFixName how the resulting fix should be named (the human-readable name users see) |
| * @param applyFix true if the fix needs to be applied |
| * @param available true if the fix should be available, false if it should be explicitly not available. |
| * @throws Exception |
| */ |
| protected void doInspectionTest(@NonNls String[] testFiles, |
| final Class inspectionClass, |
| @NonNls String quickFixName, |
| boolean applyFix, |
| boolean available) { |
| myFixture.enableInspections(inspectionClass); |
| myFixture.configureByFiles(testFiles); |
| myFixture.checkHighlighting(true, false, false); |
| final IntentionAction intentionAction = myFixture.findSingleIntention(quickFixName); |
| if (available) { |
| assertNotNull(intentionAction); |
| if (applyFix) { |
| myFixture.launchAction(intentionAction); |
| |
| myFixture.checkResultByFile(graftBeforeExt(testFiles[0], "_after")); |
| } |
| } |
| else { |
| assertNull(intentionAction); |
| } |
| } |
| |
| // Turns "name.ext" to "name_insertion.ext" |
| |
| @NonNls |
| private static String graftBeforeExt(String name, String insertion) { |
| int dotpos = name.indexOf('.'); |
| if (dotpos < 0) dotpos = name.length(); |
| return name.substring(0, dotpos) + insertion + name.substring(dotpos, name.length()); |
| } |
| } |