mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fixed file references from python string literals (PY-7433, PY-6234, PY-7434)
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiReferenceProvider;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyStringLiteralFileReferenceSet extends RootFileReferenceSet {
|
||||
private final PyStringLiteralExpression myStringLiteralExpression;
|
||||
|
||||
|
||||
public PyStringLiteralFileReferenceSet(@NotNull PyStringLiteralExpression element) {
|
||||
this(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public PyStringLiteralFileReferenceSet(@NotNull PyStringLiteralExpression element, boolean caseSensitive) {
|
||||
this(element.getStringValue(), element, element.getStringValueTextRange().getStartOffset(), null, caseSensitive, true, new FileType[0]);
|
||||
}
|
||||
|
||||
public PyStringLiteralFileReferenceSet(@NotNull String str,
|
||||
@NotNull PyStringLiteralExpression element,
|
||||
int startInElement,
|
||||
PsiReferenceProvider provider,
|
||||
boolean caseSensitive, boolean endingSlashNotAllowed, @Nullable FileType[] suitableFileTypes) {
|
||||
super(str, element, startInElement, provider, caseSensitive, endingSlashNotAllowed,
|
||||
suitableFileTypes);
|
||||
myStringLiteralExpression = element;
|
||||
reparse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reparse() {
|
||||
if (myStringLiteralExpression != null) {
|
||||
MyTextRangeConsumer textRangeConsumer = new MyTextRangeConsumer(this);
|
||||
|
||||
myStringLiteralExpression.iterateCharacterRanges(textRangeConsumer);
|
||||
textRangeConsumer.finish();
|
||||
|
||||
List<FileReference> referencesList = textRangeConsumer.myReferenceList;
|
||||
|
||||
myReferences = referencesList.toArray(new FileReference[referencesList.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyTextRangeConsumer implements PyStringLiteralExpression.TextRangeConsumer {
|
||||
private final StringBuilder myItem = new StringBuilder();
|
||||
private int myStartOffset = -1;
|
||||
private int myIndex = 0;
|
||||
private int myEndOffset = -1;
|
||||
private final FileReferenceSet myFileReferenceSet;
|
||||
|
||||
|
||||
private final List<FileReference> myReferenceList = new ArrayList<FileReference>();
|
||||
|
||||
private MyTextRangeConsumer(FileReferenceSet set) {
|
||||
myFileReferenceSet = set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(int startOffset, int endOffset, String value) {
|
||||
if ("\\".equals(value) || "/".equals(value)) {
|
||||
addReference(startOffset);
|
||||
}
|
||||
else {
|
||||
if (myStartOffset == -1) {
|
||||
myStartOffset = startOffset;
|
||||
}
|
||||
myEndOffset = endOffset;
|
||||
myItem.append(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addReference(int startOffset) {
|
||||
final FileReference ref = myFileReferenceSet.createFileReference(
|
||||
new TextRange(myStartOffset, startOffset),
|
||||
myIndex++,
|
||||
myItem.toString());
|
||||
myReferenceList.add(ref);
|
||||
myStartOffset = -1;
|
||||
myItem.setLength(0);
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
addReference(myEndOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Resolves absolute paths from FS root, not content roots
|
||||
*
|
||||
* @author traff
|
||||
*/
|
||||
public class RootFileReferenceSet extends FileReferenceSet {
|
||||
public RootFileReferenceSet(String str,
|
||||
PsiElement element,
|
||||
int startInElement,
|
||||
PsiReferenceProvider provider,
|
||||
boolean caseSensitive,
|
||||
boolean endingSlashNotAllowed, @Nullable FileType[] suitableFileTypes) {
|
||||
super(str, element, startInElement, provider, caseSensitive, endingSlashNotAllowed, suitableFileTypes);
|
||||
}
|
||||
|
||||
public RootFileReferenceSet(String s, PsiElement element, int offset, PsiReferenceProvider provider, boolean sensitive) {
|
||||
super(s, element, offset, provider, sensitive);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiFileSystemItem> computeDefaultContexts() {
|
||||
final PsiFile file = getContainingFile();
|
||||
if (file != null) {
|
||||
|
||||
if (isAbsolutePathReference() && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
VirtualFile root = LocalFileSystem.getInstance().getRoot();
|
||||
PsiDirectory directory = file.getManager().findDirectory(root);
|
||||
if (directory != null) {
|
||||
return Lists.<PsiFileSystemItem>newArrayList(directory);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return super.computeDefaultContexts();
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.templateLanguages;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PythonStringUtil;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import com.jetbrains.python.psi.PyStringLiteralFileReferenceSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyTemplateFileReferenceSet extends PyStringLiteralFileReferenceSet {
|
||||
public PyTemplateFileReferenceSet(PyStringLiteralExpression element) {
|
||||
super(element, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiFileSystemItem> computeDefaultContexts() {
|
||||
List<PsiFileSystemItem> contexts = ContainerUtil.newArrayList();
|
||||
if (getPathString().startsWith("/") || getPathString().startsWith("\\")) {
|
||||
return contexts;
|
||||
}
|
||||
Module module = ModuleUtilCore.findModuleForPsiElement(getElement());
|
||||
if (module != null) {
|
||||
List<VirtualFile> templatesFolders = getRoots(module);
|
||||
for (VirtualFile folder : templatesFolders) {
|
||||
final PsiDirectory directory = PsiManager.getInstance(module.getProject()).findDirectory(folder);
|
||||
if (directory != null) {
|
||||
contexts.add(directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
return contexts;
|
||||
}
|
||||
|
||||
protected List<VirtualFile> getRoots(Module module) {
|
||||
return TemplatesService.getInstance(module).getTemplateFolders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileReference createFileReference(TextRange range, int index, String text) {
|
||||
return new TemplateFileReference(this, range, index, text);
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,10 @@ public interface PyStringLiteralExpression extends PyLiteralExpression, StringLi
|
||||
List<ASTNode> getStringNodes();
|
||||
|
||||
int valueOffsetToTextOffset(int valueOffset);
|
||||
|
||||
void iterateCharacterRanges(TextRangeConsumer consumer);
|
||||
|
||||
interface TextRangeConsumer {
|
||||
boolean process(int startOffset, int endOffset, String value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,10 +326,6 @@ public class PyStringLiteralExpressionImpl extends PyElementImpl implements PySt
|
||||
return new StringLiteralTextEscaper(this);
|
||||
}
|
||||
|
||||
public interface TextRangeConsumer {
|
||||
boolean process(int startOffset, int endOffset, String value);
|
||||
}
|
||||
|
||||
private static class StringLiteralTextEscaper extends LiteralTextEscaper<PyStringLiteralExpression> {
|
||||
private final PyStringLiteralExpressionImpl myHost;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user