| 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; |
| } |
| |
| } |