}
}
}
// first time parsing - compute scopes and variable declarations
AstRoot root = createParser().parse(_document.get(_region.getOffset(), _region.getLength()), null, 0);
root.visit(new NodeVisitor() {
public boolean visit(AstNode node) {
Scope scope = node.getEnclosingScope();
List<Integer> scopePath = new ArrayList<Integer>();
while (scope != null) {
scopePath.add(scope.getAbsolutePosition());
scope = scope.getParentScope();
}
Collections.reverse(scopePath);
String path = WGUtils.serializeCollection(scopePath, ".");
TMLScriptScope tmlScriptScope = _scopes.get(path);
if (tmlScriptScope == null && node.getEnclosingScope() != null) {
tmlScriptScope = new TMLScriptScope(path, node.getEnclosingScope().getAbsolutePosition(), node.getEnclosingScope().getLength());
_scopes.put(path, tmlScriptScope);
}
if (node instanceof VariableDeclaration || node instanceof ExpressionStatement) {
if (node instanceof VariableDeclaration) {
VariableDeclaration declaration = (VariableDeclaration) node;
String source = declaration.toSource();
String name = source.substring(0, source.indexOf("=")).trim();
name = name.substring(name.indexOf("var") + 3).trim();
String value = source.substring(source.indexOf("=") + 1).trim();
TMLScriptVariableDeclaration tmlScriptVarDec = new TMLScriptVariableDeclaration(tmlScriptScope, name);
tmlScriptVarDec.setValue(value);
tmlScriptVarDec.setOffset(declaration.getAbsolutePosition());
tmlScriptScope.getVariableDeclarations().add(tmlScriptVarDec);
} else if (node instanceof ExpressionStatement) {
ExpressionStatement expressionStatement = (ExpressionStatement) node;
String source = expressionStatement.getExpression().toSource();
if (source != null && source.contains("=")) {
String name = source.substring(0, source.indexOf("=")).trim();
String value = source.substring(source.indexOf("=") + 1).trim();
TMLScriptVariableDeclaration tmlScriptVarDec = new TMLScriptVariableDeclaration(tmlScriptScope, name);
tmlScriptVarDec.setValue(value);
tmlScriptVarDec.setOffset(expressionStatement.getAbsolutePosition());
tmlScriptVarDec.setTmlVariable(true);
tmlScriptScope.getVariableDeclarations().add(tmlScriptVarDec);
}
}
}
return true;
}
});
// second parsing run - compute type of variables
Iterator<TMLScriptScope> scopes = _scopes.values().iterator();
while (scopes.hasNext()) {
TMLScriptScope scope = scopes.next();
Iterator<TMLScriptVariableDeclaration> vars = scope.getVariableDeclarations().iterator();
while (vars.hasNext()) {
final TMLScriptVariableDeclaration fVar = vars.next();
Map<String,TMLScriptVariableDeclaration> visibleVars = retrieveVisibleVars(fVar);
String currentEnvironmentObject = ReflectionManager.GLOBAL_SCOPE_CLASSNAME;
String[] varValues = splitVariableValue(fVar.getValue(), false);
if (fVar.getValue().startsWith("Packages") || (fVar.getValue().startsWith("new") && fVar.getValue().contains("Packages"))) {
fVar.setType(resolvePackageOrConstructorCall(fVar.getValue(), false));
} else {
for (String value : varValues) {
AstRoot valueAst = createParser().parse(value, "", 0);
TypeVisitor visitor = new TypeVisitor(currentEnvironmentObject, visibleVars, _versionCompliance, _envFlags);
valueAst.visit(visitor);
currentEnvironmentObject = visitor.getType();
if (currentEnvironmentObject == null) {
break;
}
}
//fVar.setType(ReflectionManager.jsWrap(currentEnvironmentObject));
fVar.setType(currentEnvironmentObject);
}
}
}
// compute user input
IRegion lineRegion = _document.getLineInformationOfOffset(_cursorInDocument);
if (lineRegion.getOffset() < _region.getOffset()) {
// stay in parsion region
lineRegion = _region;
}
// read backwards until open bracket / line start or control character
int numClosedBrackets = 0;
int pos =_cursorInDocument -1;
while (pos >= lineRegion.getOffset()) {
char c = _document.getChar(pos);
if (c == ')') {
numClosedBrackets++;
}
if (c =='(') {
if (numClosedBrackets == 0) {
break;
} else {
numClosedBrackets--;
}
}
if (c == '=' || c==';' || c=='>' || c=='<' || c == '|') {
break;
}
if (c == ',' && numClosedBrackets == 0) {
break;
}
pos--;
}
_typed = _document.get(pos + 1, _cursorInDocument - pos - 1).trim();
// compute object in context
_env = ReflectionManager.GLOBAL_SCOPE_CLASSNAME;
if (_typed != null) {
String[] tokens = splitVariableValue(_typed, true);
if (_typed.startsWith("Packages") || (_typed.startsWith("new") && _typed.contains("Packages"))) {
_env = resolvePackageOrConstructorCall(_typed, true);
} else {
for (int i = 0; i < tokens.length; i++) {
String value = tokens[i];
if (!value.equals(".") && (i < tokens.length - 1)) {
AstRoot valueAst = createParser().parse(value, "", 0);
TypeVisitor visitor = new TypeVisitor(_env, retrieveVisibleVars(), _versionCompliance, _envFlags);
valueAst.visit(visitor);
_env = visitor.getType();
// if ((i == tokens.length - 3) || (i == tokens.length - 2)) {
// // last token - check if we have to wrap
// if (!visitor.skipJSWrapping()) {
// _env = ReflectionManager.jsWrap(_env);