blob: 73910d7ce3127ab2987638c0fcde62d4f4216633 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.modules.php.editor;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.swing.text.Document;
import org.netbeans.modules.csl.spi.ParserResult;
import org.netbeans.modules.php.editor.parser.api.Utils;
import org.netbeans.modules.php.editor.parser.astnodes.ASTNode;
import org.netbeans.modules.php.editor.parser.astnodes.Expression;
import org.netbeans.modules.php.editor.parser.astnodes.Include;
import org.netbeans.modules.php.editor.parser.astnodes.ParenthesisExpression;
import org.netbeans.modules.php.editor.parser.astnodes.Scalar;
import org.netbeans.modules.php.editor.parser.astnodes.Scalar.Type;
import org.netbeans.modules.php.editor.parser.astnodes.visitors.DefaultVisitor;
import org.netbeans.modules.php.project.api.PhpSourcePath;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
/**
*
* @author Jan Lahoda
*/
public final class NavUtils {
private NavUtils() {
}
public static List<ASTNode> underCaret(ParserResult info, final int offset) {
class Result extends Error {
private final ArrayDeque<ASTNode> result;
Result(ArrayDeque<ASTNode> result) {
this.result = result;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}
try {
new DefaultVisitor() {
private final ArrayDeque<ASTNode> s = new ArrayDeque<>();
@Override
public void scan(ASTNode node) {
if (node == null) {
return;
}
if (node.getStartOffset() <= offset && offset <= node.getEndOffset()) {
s.push(node);
super.scan(node);
throw new Result(s);
}
}
}.scan(Utils.getRoot(info));
} catch (Result r) {
List<ASTNode> list = new ArrayList<>();
Iterator<ASTNode> iterator = r.result.descendingIterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
return Collections.emptyList();
}
public static boolean isQuoted(String value) {
return value.length() >= 2 && (value.startsWith("\"") || value.startsWith("'")) && (value.endsWith("\"") || value.endsWith("'"));
}
public static String dequote(String value) {
assert isQuoted(value);
return value.substring(1, value.length() - 1);
}
public static FileObject resolveInclude(ParserResult info, Include include) {
Expression e = include.getExpression();
if (e instanceof ParenthesisExpression) {
e = ((ParenthesisExpression) e).getExpression();
}
if (e instanceof Scalar) {
Scalar s = (Scalar) e;
if (Type.STRING == s.getScalarType()) {
String fileName = s.getStringValue();
fileName = fileName.length() >= 2 ? fileName.substring(1, fileName.length() - 1) : fileName; //TODO: not nice
return resolveRelativeFile(info, fileName);
}
}
return null;
}
private static FileObject resolveRelativeFile(ParserResult info, String name) {
while (true) {
FileObject result;
// if (psp != null) {
result = PhpSourcePath.resolveFile(info.getSnapshot().getSource().getFileObject().getParent(), name);
// } else {
// result = info.getFileObject().getParent().getFileObject(name);
// }
if (result != null) {
return result;
}
//try to strip a directory from the "name":
int slash = name.indexOf('/');
if (slash != (-1)) {
name = name.substring(slash + 1);
} else {
return null;
}
}
}
public static FileObject getFile(Document doc) {
Object o = doc.getProperty(Document.StreamDescriptionProperty);
if (o instanceof DataObject) {
DataObject od = (DataObject) o;
return od.getPrimaryFile();
}
return null;
}
}