package org.eclipse.dltk.tcl.internal.core.parser.processors.tcl; 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.ast.references.SimpleReference; import org.eclipse.dltk.ast.statements.Block; import org.eclipse.dltk.compiler.problem.ProblemSeverities; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.tcl.ast.TclStatement; import org.eclipse.dltk.tcl.ast.expressions.TclBlockExpression; import org.eclipse.dltk.tcl.core.AbstractTclCommandProcessor; import org.eclipse.dltk.tcl.core.ITclParser; import org.eclipse.dltk.tcl.core.TclParseUtil; public class TclNamespaceProcessor extends AbstractTclCommandProcessor { private ASTNode findRealParent(ASTNode node) { List levels = TclParseUtil.findLevelsTo(this.getModuleDeclaration(), node); for (int i = levels.size() - 1; i >= 0; --i) { ASTNode n = (ASTNode) levels.get(i); if (n instanceof MethodDeclaration || n instanceof TypeDeclaration || n instanceof ModuleDeclaration) { return n; } } return null; } public ASTNode process(TclStatement statement, ITclParser parser, ASTNode parent) { Expression nameSpaceArg = statement.getAt(1); if (nameSpaceArg == null || !(nameSpaceArg instanceof SimpleReference)) { this.report(parser, "Syntax error: a namespace name expected.", statement, ProblemSeverities.Error); if (DLTKCore.DEBUG) { System.err .println("tcl: namespace argument is null or not simple reference"); } // continue; } if (!(nameSpaceArg instanceof SimpleReference)) { return null; } String sNameSpaceArg = ((SimpleReference) nameSpaceArg).getName(); if (sNameSpaceArg.equals("eval")) { Expression nameSpaceName = statement.getAt(2); if (!(nameSpaceName instanceof SimpleReference)) { return null; } String sNameSpaceName = ((SimpleReference) nameSpaceName).getName(); if (nameSpaceName == null || !(nameSpaceName instanceof SimpleReference)) { this.report(parser, "Syntax error: namespace name expected", statement, ProblemSeverities.Error); // continue; // by now, just ignore return null; } final int FIRST_ARGUMENT_POSITION = 3; if (statement.getCount() < 4) { return null; } // List statements = new ArrayList(statement.getCount() - // FIRST_ARGUMENT_POSITION); int start = statement.getAt(FIRST_ARGUMENT_POSITION).sourceStart(); int end = statement.getAt(statement.getCount() - 1).sourceEnd(); Block code = new Block(start, end); TypeDeclaration type = new TypeDeclaration(sNameSpaceName, nameSpaceName.sourceStart(), nameSpaceName.sourceEnd(), statement.sourceStart(), statement.sourceEnd()); type.setModifiers(Modifiers.AccNameSpace); ASTNode realParent = findRealParent(parent); if (realParent instanceof TypeDeclaration) { TypeDeclaration t = ((TypeDeclaration) realParent); type.setEnclosingTypeName(t.getEnclosingTypeName() + "$" + t.getName()); } addToParent(parent, type); type.setBody(code); for (int i = FIRST_ARGUMENT_POSITION; i < statement.getCount(); i++) { Expression expr = statement.getAt(i); if (expr == null) { return null; } if (expr instanceof Block) { code.getStatements().addAll(((Block) expr).getStatements()); } else if (expr instanceof TclBlockExpression) { TclBlockExpression block = (TclBlockExpression) expr; String blockContent = block.getBlock(); if (blockContent.length() > 2) { blockContent = blockContent.substring(1, blockContent .length() - 1); parser.parse(blockContent, block.sourceStart() + 1 - parser.getStartPos(), code); } // code.getStatements().addAll(bl.getStatements()); } else { code.getStatements().add(expr); } } return type; } return null; } }