blob: 7a221659b9915038a1a9fe48087dae4ae459f497 [file] [log] [blame]
/*
* 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.psi.impl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyCallExpression;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyReferenceExpression;
import org.jetbrains.annotations.Nullable;
import java.io.File;
/**
* @author yole
*/
public class PyPathEvaluator extends PyEvaluator {
private final String myContainingFilePath;
public PyPathEvaluator(String containingFilePath) {
myContainingFilePath = containingFilePath;
}
@Nullable
public static String evaluatePath(PyExpression expr) {
if (expr == null) {
return null;
}
VirtualFile vFile = expr.getContainingFile().getVirtualFile();
Object result = new PyPathEvaluator(vFile == null ? null : vFile.getPath()).evaluate(expr);
return result instanceof String ? (String) result : null;
}
@Override
protected Object evaluateCall(PyCallExpression call) {
final PyExpression[] args = call.getArguments();
if (call.isCalleeText(PyNames.DIRNAME) && args.length == 1) {
Object argValue = evaluate(args[0]);
return argValue instanceof String ? new File((String) argValue).getParent() : null;
}
else if (call.isCalleeText(PyNames.JOIN) && args.length >= 1) {
return evaluatePathInJoin(args, args.length);
}
else if (call.isCalleeText(PyNames.NORMPATH, PyNames.REALPATH) && args.length == 1) {
// we don't care about the exact transformation performed by python but need to preserve the availability of the path
return evaluate(args[0]);
}
else if (call.isCalleeText(PyNames.ABSPATH) && args.length == 1) {
Object argValue = evaluate(args[0]);
// relative to directory of 'containingFilePath', not file
if (!(argValue instanceof String)) {
return null;
}
if (FileUtil.isAbsolutePlatformIndependent((String)argValue)) {
return argValue;
}
else {
String path = new File(new File(myContainingFilePath).getParent(), (String)argValue).getPath();
return path.replace("\\", "/");
}
}
return super.evaluateCall(call);
}
@Override
protected Object evaluateReferenceExpression(PyReferenceExpression expr) {
if (PyNames.PARDIR.equals(expr.getName())) {
return "..";
}
else if (PyNames.CURDIR.equals(expr.getName())) {
return ".";
}
if (!expr.isQualified() && PyNames.FILE.equals(expr.getReferencedName())) {
return myContainingFilePath;
}
return super.evaluateReferenceExpression(expr);
}
public String evaluatePathInJoin(PyExpression[] args, int endElement) {
String result = null;
for (int i = 0; i < endElement; i++) {
Object arg = evaluate(args[i]);
if (!(arg instanceof String)) {
return null;
}
if (result == null) {
result = (String)arg;
}
else {
result = new File(result, (String)arg).getPath().replace("\\", "/");
}
}
return result;
}
}