/******************************************************************************* * Copyright (c) 2008 xored software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * xored software, Inc. - initial API and Implementation (Alex Panchenko) *******************************************************************************/ package org.eclipse.dltk.tcl.indexing; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.dltk.core.IExternalSourceModule; import org.eclipse.dltk.core.IScriptProject; import org.eclipse.dltk.core.ISourceModule; import org.eclipse.dltk.tcl.ast.TclArgument; import org.eclipse.dltk.tcl.ast.TclCommand; import org.eclipse.dltk.tcl.core.TclPlugin; import org.eclipse.dltk.tcl.core.packages.TclModuleInfo; import org.eclipse.dltk.tcl.core.packages.TclPackagesFactory; import org.eclipse.dltk.tcl.core.packages.TclSourceEntry; import org.eclipse.dltk.tcl.definitions.Command; import org.eclipse.dltk.tcl.internal.core.packages.TclPackageSourceModule; import org.eclipse.dltk.tcl.parser.TclParserUtils; import org.eclipse.dltk.tcl.parser.TclVisitor; import org.eclipse.dltk.tcl.parser.printer.SimpleCodePrinter; import org.eclipse.emf.common.util.EList; public class PackageSourceCollector extends TclVisitor { public static final String PACKAGE = "package"; //$NON-NLS-1$ static final String REQUIRE = "require"; //$NON-NLS-1$ static final String PROVIDE = "provide"; //$NON-NLS-1$ static final String IFNEEDED = "ifneeded"; //$NON-NLS-1$ static final String EXACT = "-exact"; //$NON-NLS-1$ static final String SOURCE = "source";//$NON-NLS-1$ private final Map<IScriptProject, List<TclModuleInfo>> modules = new HashMap<IScriptProject, List<TclModuleInfo>>(); private TclModuleInfo currentModuleInfo; private ISourceModule currentModule; public void process(List<TclCommand> declaration, ISourceModule module) { this.currentModule = module; try { currentModuleInfo = getCreateCurrentModuleInfo(module); currentModuleInfo.getProvided().clear(); currentModuleInfo.getRequired().clear(); currentModuleInfo.getSourced().clear(); TclParserUtils.traverse(declaration, this); } catch (Exception e) { TclPlugin.error(e); } } public TclModuleInfo getCreateCurrentModuleInfo(ISourceModule module) { if (module != null) { String identifier = module.getHandleIdentifier(); IScriptProject scriptProject = module.getScriptProject(); List<TclModuleInfo> list = modules.get(scriptProject); if (list == null) { list = new ArrayList<TclModuleInfo>(); modules.put(scriptProject, list); } TclModuleInfo result = null; // Remove all old required and provided packages. for (TclModuleInfo info : list) { if (info.getHandle().equals(identifier)) { result = info; break; } } if (result == null) { result = TclPackagesFactory.eINSTANCE.createTclModuleInfo(); result.setHandle(identifier); result.setExternal(module instanceof IExternalSourceModule); list.add(result); } return result; } return TclPackagesFactory.eINSTANCE.createTclModuleInfo(); } public boolean visit(TclCommand command) { Command definition = command.getDefinition(); if (definition != null && PACKAGE.equals(definition.getName())) { processPackageCommand(command); } if (!(currentModule instanceof TclPackageSourceModule)) { if (definition != null && SOURCE.equals(definition.getName())) { processSourceCommand(command); } } return super.visit(command); } private TclArgument getStringArg(EList<TclArgument> args, int index) { if (index < args.size()) { return args.get(index); } return null; } private void processPackageCommand(TclCommand command) { EList<TclArgument> args = command.getArguments(); TclArgument style = getStringArg(args, 0); if (style == null) { return; } final String keyword = SimpleCodePrinter.getArgumentString(style, style .getStart()); if (REQUIRE.equalsIgnoreCase(keyword)) { TclArgument pkgName = getStringArg(args, 1); if (pkgName == null) { return; } String packageName = SimpleCodePrinter.getArgumentString(pkgName, pkgName.getStart()); if (EXACT.equals(packageName)) { pkgName = getStringArg(args, 2); if (pkgName == null) { return; } packageName = SimpleCodePrinter.getArgumentString(pkgName, pkgName.getStart()); } // if (TclPackagesManager.isValidPackageName(packageName)) { TclSourceEntry entry = TclPackagesFactory.eINSTANCE .createTclSourceEntry(); entry.setValue(packageName); entry.setStart(pkgName.getStart()); entry.setEnd(pkgName.getEnd()); currentModuleInfo.getRequired().add(entry); // } } else if (/* * IFNEEDED.equalsIgnoreCase(keyword) || */PROVIDE.equalsIgnoreCase(keyword)) { TclArgument pkgName = getStringArg(args, 1); if (pkgName == null) { return; } String pkg = SimpleCodePrinter.getArgumentString(pkgName, pkgName .getStart()); // if (TclPackagesManager.isValidPackageName(pkg)) { // packagesProvided.add(new PackageInfo(pkg, null, currentModule)); // } TclSourceEntry entry = TclPackagesFactory.eINSTANCE .createTclSourceEntry(); entry.setValue(pkg); entry.setStart(pkgName.getStart()); entry.setEnd(pkgName.getEnd()); currentModuleInfo.getProvided().add(entry); } } private void processSourceCommand(TclCommand command) { EList<TclArgument> arguments = command.getArguments(); for (TclArgument tclArgument : arguments) { TclSourceEntry entry = TclPackagesFactory.eINSTANCE .createTclSourceEntry(); entry.setStart(tclArgument.getStart()); entry.setEnd(tclArgument.getEnd()); this.currentModuleInfo.getSourced().add(entry); entry.setValue(SimpleCodePrinter.getArgumentString(tclArgument, tclArgument.getStart())); } } /** * @return the packagesProvided */ public Map<IScriptProject, List<TclModuleInfo>> getModules() { return modules; } /** * For testing purposes only. */ public TclModuleInfo getCurrentModuleInfo() { return currentModuleInfo; } }