package org.eclipse.dltk.xotcl.internal.core.parser.processors.xotcl; import java.util.ArrayList; import java.util.List; import org.eclipse.dltk.ast.ASTNode; import org.eclipse.dltk.ast.declarations.Argument; import org.eclipse.dltk.ast.declarations.TypeDeclaration; import org.eclipse.dltk.ast.expressions.Expression; import org.eclipse.dltk.ast.references.SimpleReference; import org.eclipse.dltk.ast.statements.Block; import org.eclipse.dltk.compiler.problem.ProblemSeverities; import org.eclipse.dltk.tcl.ast.TclStatement; import org.eclipse.dltk.tcl.ast.expressions.TclBlockExpression; import org.eclipse.dltk.tcl.ast.expressions.TclExecuteExpression; import org.eclipse.dltk.tcl.core.AbstractTclCommandProcessor; import org.eclipse.dltk.tcl.core.ITclParser; import org.eclipse.dltk.tcl.core.ast.ExtendedTclMethodDeclaration; import org.eclipse.dltk.tcl.internal.core.parser.processors.tcl.Messages; import org.eclipse.dltk.tcl.internal.parser.OldTclParserUtils; import org.eclipse.dltk.xotcl.core.IXOTclModifiers; import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclExInstanceVariable; import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclInstanceVariable; import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclMethodDeclaration; import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclObjectDeclaration; /** * Process "#Class#instproc", "#Class#proc" and "#Object#proc", and instance * proc commands. * * @author haiodo * */ public class XOTclClassAllProcProcessor extends AbstractTclCommandProcessor { private static final String KIND_PROC_STR = "proc"; private static final String KIND_INSTPROC_STR = "instproc"; public XOTclClassAllProcProcessor() { } public ASTNode process(TclStatement statement, ITclParser parser, ASTNode parent) { ASTNode decl = null; if (getDetectedParameter() != null && (getDetectedParameter() instanceof ASTNode)) { decl = (ASTNode) getDetectedParameter(); } if (decl == null) { return null; } if (statement.getCount() < 5) { this.report(parser, Messages.TclProcProcessor_Wrong_Number_of_Arguments, statement.sourceStart(), statement.sourceEnd(), ProblemSeverities.Error); return null; } int index = 2; Expression procName = statement.getAt(index); String sName = null; sName = extractName(procName); if (sName == null || sName.length() == 0) { this.report(parser, Messages.TclProcProcessor_Empty_Proc_Name, statement.sourceStart(), statement.sourceEnd(), ProblemSeverities.Error); return null; } Expression procArguments = statement.getAt(index + 1); Expression procCode = statement.getAt(index + 2); List arguments = null; if (procArguments instanceof TclBlockExpression) { List/* < Statement > */st = null; st = ((TclBlockExpression) procArguments).parseBlockSimple(); arguments = OldTclParserUtils.parseArguments(st); } if (procArguments instanceof SimpleReference) { arguments = new ArrayList(); Argument a = new Argument((SimpleReference) procArguments, procArguments.sourceStart(), null, 0); arguments.add(a); } ExtendedTclMethodDeclaration method = new XOTclMethodDeclaration( statement.sourceStart(), statement.sourceEnd()); method.setDeclaringType(decl); if (decl instanceof TypeDeclaration) { method.setDeclaringTypeName(((TypeDeclaration) decl).getName()); } else if (decl instanceof XOTclInstanceVariable) { method.setDeclaringTypeName(((XOTclInstanceVariable) decl) .getName()); } else if (decl instanceof XOTclExInstanceVariable) { String name = ((XOTclExInstanceVariable) decl) .getDeclaringClassParameter().getClassName(); method.setDeclaringTypeName(name); } method.setModifiers(IXOTclModifiers.AccXOTcl); method.setName(sName); method.setNameStart(procName.sourceStart()); method.setNameEnd(procName.sourceEnd()); method.setTypeNameRef((SimpleReference) statement.getAt(0)); method.acceptArguments(arguments); Block block = new Block(procCode.sourceStart(), procCode.sourceEnd()); if (procCode instanceof Block) { block.getStatements().addAll(((Block) procCode).getStatements()); } else if (procCode instanceof TclBlockExpression) { String content = ((TclBlockExpression) procCode).getBlock(); if (content.startsWith("{") && content.endsWith("}")) { content = content.substring(1, content.length() - 1); } parser.parse(content, procCode.sourceStart() + 1, block); } method.acceptBody(block); this.addToParent(parent, method); if (decl instanceof TypeDeclaration) { ((TypeDeclaration) decl).getMethodList().add(method); } /** * Parse method kind. */ Expression kind = statement.getAt(1); String kindName = this.extractName(kind); if (kindName != null) { if (KIND_PROC_STR.equals(kindName)) { method.setKind(ExtendedTclMethodDeclaration.KIND_PROC); } else if (KIND_INSTPROC_STR.equals(kindName)) { method.setKind(ExtendedTclMethodDeclaration.KIND_INSTPROC); if (decl instanceof XOTclObjectDeclaration) { // report(parser, "Adding instproc to object", kind, // ProblemSeverities.Warning); } } } // parser.parse(content, procCode.sourceStart() + 1, block); return method; } private String extractName(Expression procName) { if (procName instanceof SimpleReference) { return ((SimpleReference) procName).getName(); } else if (procName instanceof TclBlockExpression) { return ((TclBlockExpression) procName).getBlock(); } else if (procName instanceof TclExecuteExpression) { return ((TclExecuteExpression) procName).getExpression(); } return null; } }