blob: 4576d7de4e6f0d1dbf121d2555d9dd0409015535 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.tcl.internal.parser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.declarations.Argument;
import org.eclipse.dltk.ast.declarations.FieldDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.tcl.ast.TclStatement;
import org.eclipse.dltk.tcl.ast.expressions.TclBlockExpression;
import org.eclipse.dltk.tcl.ast.expressions.TclExecuteExpression;
public class OldTclParserUtils {
public static final Object AST = "ast";
public static List parseArguments(List st) {
List arguments = new ArrayList();
if (st != null && st.size() > 0) {
for (int y = 0; y < st.size(); ++y) {
Object sty = st.get(y);
if (sty instanceof FieldDeclaration) {
Argument a = new Argument();
a.set(((FieldDeclaration) sty).getRef(), null);
arguments.add(a);
} else if (sty instanceof TclStatement) {
TclStatement tclSt = (TclStatement) sty;
if (tclSt instanceof TclStatement) {
Iterator i = tclSt.getExpressions().iterator();
while (i.hasNext()) {
Expression ex = (Expression) i.next();
if (ex instanceof SimpleReference) {
Argument a = new Argument();
a.set((SimpleReference) ex, null);
arguments.add(a);
} else if (ex instanceof TclBlockExpression) {
TclBlockExpression bl = (TclBlockExpression) ex;
// try {
List elements = bl.parseBlockSimple();
if (elements.size() > 0) {
ASTNode node = (ASTNode) elements.get(0);
Expression initializer = null;
if (elements.size() > 1) {
if (elements
.get(1) instanceof Expression) {
initializer = (Expression) elements
.get(1);
}
}
if (node instanceof TclStatement
&& ((TclStatement) node)
.getCount() > 0) {
TclStatement stat = ((TclStatement) node);
node = stat.getAt(0);
if (stat.getCount() > 1) {
initializer = stat.getAt(1);
}
}
if (node instanceof SimpleReference) {
Argument a = new Argument();
a.set((SimpleReference) node, null);
a.setInitializationExpression(
initializer);
arguments.add(a);
} else if (node instanceof TclBlockExpression) {
String name = ((TclBlockExpression) node)
.getBlock();
Argument a = new Argument();
a.setStart(node.sourceStart() + 1);
a.setEnd(node.sourceEnd() + 1);
a.setArgumentName(
nameFromBlock(name, '{', '}'));
a.setInitializationExpression(
initializer);
arguments.add(a);
} else if (node instanceof StringLiteral) {
String name = ((StringLiteral) node)
.getValue();
Argument a = new Argument();
a.setStart(node.sourceStart() + 1);
a.setEnd(node.sourceEnd() + 1);
a.setArgumentName(
nameFromBlock(name, '"', '"'));
a.setInitializationExpression(
initializer);
arguments.add(a);
} else if (node instanceof TclExecuteExpression) {
String name = ((TclExecuteExpression) node)
.getExpression();
Argument a = new Argument();
a.setStart(node.sourceStart() + 1);
a.setEnd(node.sourceEnd() + 1);
a.setArgumentName(name);
a.setInitializationExpression(
initializer);
arguments.add(a);
}
}
}
}
}
}
}
}
return arguments;
}
public static String nameFromBlock(String name, char c1, char c2) {
if (name.charAt(0) == c1 || name.charAt(name.length() - 1) == c2) {
return name.substring(1, name.length() - 1);
}
return name;
}
public static String[] returnVariable(TclStatement s) {
Expression sName = s.getAt(0);
List variableName = new ArrayList();
if (!(sName instanceof SimpleReference)) {
return null;
}
String name = ((SimpleReference) sName).getName();
if (name.equals("set") && s.getCount() > 2) {
variableName.add(s.getAt(1));
} else if (name.equals("variable") && s.getCount() >= 2) {
for (int j = 1; j < s.getCount(); j += 2) {
variableName.add(s.getAt(j));
}
} else if (name.equals("global") && s.getCount() >= 2) {
for (int j = 1; j < s.getCount(); ++j) {
variableName.add(s.getAt(j));
}
} else if (name.equals("upvar")) {
Expression level = s.getAt(1);
int startIndex = 1;
if (level instanceof SimpleReference) {
SimpleReference sLevel = (SimpleReference) level;
String str = sLevel.getName();
if (str == null || str.length() == 0) {
throw new RuntimeException("empty upvar level name");
}
if (str.startsWith("#") || Character.isDigit(str.charAt(0))) {
// first arg is a level
startIndex++;
}
}
// TODO: Add multiple variable definitions here.
for (int i = startIndex; i < s.getCount(); i += 2) {
Expression vName = s.getAt(i + 1);
if (vName == null) {
return null;
}
variableName.add(vName);
break;
}
}
if (variableName == null) {
return null;
}
List<String> names = new ArrayList<>();
for (int k = 0; k < variableName.size(); ++k) {
if (variableName.get(k) instanceof SimpleReference) {
name = ((SimpleReference) variableName.get(k)).getName();
if (name.indexOf('(') != -1) {
name = name.substring(0, name.indexOf('('));
}
} else if (variableName.get(k) instanceof TclBlockExpression) {
name = ((TclBlockExpression) variableName.get(k)).getBlock();
name = nameFromBlock(name, '{', '}');
} else if (variableName.get(k) instanceof StringLiteral) {
name = ((StringLiteral) variableName.get(k)).getValue();
name = nameFromBlock(name, '"', '"');
} else if (variableName.get(k) instanceof TclExecuteExpression) {
name = ((TclExecuteExpression) variableName.get(k))
.getExpression();
} else {
name = null;
}
if (name != null) {
names.add(name);
}
}
if (names.size() == 0) {
return null;
}
return names.toArray(new String[names.size()]);
}
public static String returnVariableCheck(TclStatement s, int position) {
Expression sName = s.getAt(0);
Expression variableName;
if (!(sName instanceof SimpleReference)) {
return null;
}
String name = ((SimpleReference) sName).getName();
if (name.equals("set") && s.getCount() > 2) {
variableName = s.getAt(1);
} else if (name.equals("variable") && s.getCount() >= 2) {
variableName = s.getAt(1);
} else if (name.equals("global") && s.getCount() >= 2) {
variableName = s.getAt(1);
} else if (name.equals("upvar") && s.getCount() >= 4) {
variableName = s.getAt(3);
} else {
return null;
}
if (variableName.sourceStart() > position
|| position > variableName.sourceEnd()) {
return null;
}
if (variableName instanceof SimpleReference) {
name = ((SimpleReference) variableName).getName();
} else if (variableName instanceof TclBlockExpression) {
name = ((TclBlockExpression) variableName).getBlock();
name = nameFromBlock(name, '{', '}');
} else if (variableName instanceof StringLiteral) {
name = ((StringLiteral) variableName).getValue();
name = nameFromBlock(name, '"', '"');
} else if (variableName instanceof TclExecuteExpression) {
name = ((TclExecuteExpression) variableName).getExpression();
} else {
return null;
}
return name;
}
public static SimpleReference extractVariableFromString(
StringLiteral literal, int pos) {
String content = nameFromBlock(literal.getValue(), '"', '"');
return extractVariableFromString(literal.sourceStart(),
literal.sourceEnd(), pos, content);
}
public static SimpleReference extractVariableFromString(int start, int end,
int pos, String content) {
int position = pos - 1;
int index = content.lastIndexOf('$', position);
if (index != -1 && index < position) {
String sub = content.substring(index, position);
if (sub.indexOf(' ') == -1) {
return new SimpleReference(start + index + 1,
end + index + 1 + sub.length(), sub);
}
}
return null;
}
public static SimpleReference findVariableFromString(StringLiteral literal,
int pos) {
String content = nameFromBlock(literal.getValue(), '"', '"');
int position = pos - 1;
int start = startLineOrNoSymbol(position, content);
if (position < 0) {
position = 0;
}
try {
if (content.charAt(position) == '$') {
position++;
if (position < content.length()
&& content.charAt(position) == '{')
position++;
}
} catch (IndexOutOfBoundsException e) {
}
int end = endLineOrNoSymbol(position, content);
if (start < 0) {
start = 0;
}
if (start + 1 < content.length()
&& (content.charAt(start) == '$'
&& content.charAt(start + 1) == '{')
|| (start < content.length() && content.charAt(start) == '{')) {
while (content.charAt(end) != '}' && content.charAt(end) != '\\'
&& end < content.length())
end++;
end++;
}
if (start < end) {
String sub = content.substring(start, end);
return new SimpleReference(literal.sourceStart() + start + 1,
literal.sourceStart() + 1 + sub.length(), sub);
}
return null;
}
public static int endLineOrSymbol(int from, String content) {
int pos = 0;
for (pos = from; pos < content.length(); ++pos) {
char c = content.charAt(pos);
if (c == '\n' || c == '\r' || c == ';') {
return pos;
}
if (!Character.isWhitespace(c)) {
return pos;
}
}
if (pos == content.length()) {
return pos;
}
return from;
}
public static int startLineOrSymbol(int from, String content) {
if (from == -1) {
from = 0;
}
if (from >= content.length())
from--;
for (int pos = from - 1; pos > 0; --pos) {
char c = content.charAt(pos);
if (c == '\n' || c == '\r' || c == ';') {
return pos + 1;
}
if (!Character.isWhitespace(c)) {
return pos + 1;
}
}
return from;
}
public static int endLineOrNoSymbol(int from, String content) {
int pos = 0;
if (from == -1) {
from = 0;
}
if (from >= content.length())
from--;
for (pos = from; pos >= 0 && pos < content.length(); ++pos) {
if (checkBounds(content, pos)) {
if (content.charAt(pos) == '$' && pos == from) {
continue;
}
return pos;
}
}
if (pos == content.length()) {
return pos;
}
return pos;
}
private static boolean checkBounds(String content, int pos) {
char[] syms = { ' ', '\t', '\n', '\r', ']', '[', '}', '{', '(', ')',
'$', '\\', ',' };
if (pos == -1) {
pos = 1;
}
char c = content.charAt(pos);
for (int i = 0; i < syms.length; ++i) {
if (syms[i] == c) {
return true;
}
}
return false;
}
public static int startLineOrNoSymbol(int from, String content) {
if (from == -1) {
from = 0;
}
if (from >= content.length())
from--;
int pos;
for (pos = from; pos >= 0 && pos < content.length(); --pos) {
if (checkBounds(content, pos)) {
if (content.charAt(pos) == '$') {
return pos;
}
return pos + 1;
}
}
if (pos == -1) {
return 0;
}
return pos;
}
public static String processMethodName(IMethod method, String tok) {
String elName = method.getElementName();
if (elName.startsWith("::")) {
return checkDots(elName, tok);
}
String name = "";
try {
name = method.getTypeQualifiedName("$", false);
} catch (ModelException e1) {
e1.printStackTrace();
}
// name = name.replace("$", "::");
name = name.replaceAll("\\$", "::");
if (tok.startsWith("::") && !name.startsWith("::")) {
name = "::" + name;
}
return checkDots(name, tok);
}
public static String processFieldName(IField field, String tok) {
String elName = field.getElementName();
if (elName.startsWith("::")) {
return checkDots(elName, tok);
}
String name = "";
try {
name = field.getTypeQualifiedName("$", false);
} catch (ModelException e1) {
e1.printStackTrace();
}
// name = name.replace("$", "::");
name = name.replaceAll("\\$", "::");
if (tok.startsWith("::") && !name.startsWith("::")) {
name = "::" + name;
}
return checkDots(name, tok);
}
private static String checkDots(String elName, String tok) {
if (elName.startsWith("::") && !tok.startsWith("::")) {
return elName.substring(2);
}
return elName;
}
public static String processTypeName(IType type, String tok) {
String elName = type.getElementName();
if (elName.startsWith("::")) {
return elName;
}
String name = type.getTypeQualifiedName("$");
name = name.replaceAll("\\$", "::");
if (tok.startsWith("::") && !name.startsWith("::")) {
name = "::" + name;
}
return name;
}
public static FieldDeclaration[] returnVariableDeclarations(
TclStatement statement) {
List<FieldDeclaration> fields = new ArrayList<>();
String[] vars = OldTclParserUtils.returnVariable(statement);
if (vars != null) {
for (int j = 0; j < vars.length; ++j) {
int nStart = statement.sourceStart();
int nEnd = statement.sourceEnd();
List nodes = statement.getExpressions();
for (int k = 0; k < nodes.size(); ++k) {
Object o = nodes.get(k);
if (o instanceof SimpleReference) {
SimpleReference r = (SimpleReference) o;
if (r.getName().equals(vars[j])) {
nStart = r.sourceStart();
nEnd = r.sourceEnd();
}
}
}
fields.add(new FieldDeclaration(vars[j], nStart, nEnd, nStart,
nEnd));
}
}
return fields.toArray(new FieldDeclaration[fields.size()]);
}
}