blob: fd2ec2d4eb40ff4cffdd298200b27b54de6f3e20 [file] [log] [blame]
package org.eclipse.dltk.itcl.internal.core.parser.processors;
import java.util.List;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.Modifiers;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.compiler.problem.ProblemSeverities;
import org.eclipse.dltk.itcl.internal.core.IIncrTclModifiers;
import org.eclipse.dltk.itcl.internal.core.classes.IncrTclClassesManager;
import org.eclipse.dltk.itcl.internal.core.parser.ast.IncrTclBodyDeclaration;
import org.eclipse.dltk.tcl.ast.TclStatement;
import org.eclipse.dltk.tcl.core.AbstractTclCommandProcessor;
import org.eclipse.dltk.tcl.core.ITclParser;
import org.eclipse.dltk.tcl.core.TclParseUtil;
import org.eclipse.dltk.tcl.core.ast.ExtendedTclMethodDeclaration;
import org.eclipse.dltk.tcl.internal.core.codeassist.TclVisibilityUtils;
public class IncrTclBodyCommandProcessor extends AbstractTclCommandProcessor {
public IncrTclBodyCommandProcessor() {
}
@Override
public ASTNode process(TclStatement statement, ITclParser parser, ASTNode parent) {
if (statement == null || (statement.getCount() == 0)) {
return null;
}
if (statement.getCount() < 4) {
this.report(parser, "Wrong number of arguments", statement.sourceStart(), statement.sourceEnd(),
ProblemSeverities.Error);
addToParent(parent, statement);
return statement;
}
Expression procName = statement.getAt(1);
String sName = IncrTclUtils.extractMethodName(procName);
if (sName == null || sName.length() == 0) {
this.report(parser, "Wrong number of arguments", statement.sourceStart(), statement.sourceEnd(),
ProblemSeverities.Error);
addToParent(parent, statement);
return statement;
}
Expression procArguments = statement.getAt(2);
Expression procCode = statement.getAt(3);
List arguments = IncrTclUtils.extractMethodArguments(procArguments);
IncrTclBodyDeclaration method = new IncrTclBodyDeclaration(statement.sourceStart(), statement.sourceEnd());
int index = sName.lastIndexOf("::");
if (index == -1) {
this.report(parser, "Wrong Class name", statement.sourceStart(), statement.sourceEnd(),
ProblemSeverities.Error);
return statement;
}
String className = sName.substring(0, index);
String methodName = sName.substring(index + 2);
method.setName(methodName);
method.setNameStart(procName.sourceStart());
method.setNameEnd(procName.sourceEnd());
method.acceptArguments(arguments);
method.setKind(ExtendedTclMethodDeclaration.KIND_INSTPROC);
// For correct modifiers we need to add
IncrTclUtils.parseBlockAdd(parser, procCode, method);
// method.setModifier(IIncrTclModifiers.AccIncrTcl |
// IIncrTclModifiers.AccPublic);
if (TclVisibilityUtils.isPrivate(sName)) {
method.setModifier(IIncrTclModifiers.AccIncrTcl | Modifiers.AccPrivate);
} else {
method.setModifier(IIncrTclModifiers.AccIncrTcl | Modifiers.AccPublic);
}
ModuleDeclaration module = this.getModuleDeclaration();
TypeDeclaration possiblyType = TclParseUtil.findTclTypeDeclarationFrom(module, parent, className, false);
if (possiblyType != null) {
MethodDeclaration[] methods = possiblyType.getMethods();
boolean found = false;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName)) {
method.setModifiers(methods[i].getModifiers());
method.setDeclaringType(possiblyType);
method.setDeclaringTypeName(TclParseUtil.getElementFQN(possiblyType, "::", module));
this.addToParent(parent, method);
found = true;
break;
}
}
if (!found) {
// May be not correct
this.addToParent(parent, method);
this.report(parser,
"Function " + method.getName() + " is not defined in class " + possiblyType.getName(),
statement.sourceStart(), statement.sourceEnd(), ProblemSeverities.Warning);
}
} else {
if (!IncrTclClassesManager.getDefault().isClass(className)) {
this.report(parser, "Body declaration for unknown class", statement.sourceStart(),
statement.sourceEnd(), ProblemSeverities.Error);
}
this.addToParent(parent, method);
}
return method;
}
}