| /******************************************************************************* |
| * Copyright (c) 2009 xored software, Inc. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * xored software, Inc. - initial API and Implementation (Alex Panchenko) |
| *******************************************************************************/ |
| package org.eclipse.dltk.xotcl.internal.core.parser.structure; |
| |
| import org.eclipse.dltk.tcl.ast.TclArgument; |
| import org.eclipse.dltk.tcl.ast.TclCommand; |
| import org.eclipse.dltk.tcl.core.ITclCommandDetector.CommandInfo; |
| import org.eclipse.dltk.tcl.structure.ITclModelBuildContext; |
| import org.eclipse.dltk.tcl.structure.ITclModelBuilderDetector; |
| import org.eclipse.dltk.tcl.structure.TclModelBuilderUtil; |
| import org.eclipse.dltk.xotcl.internal.core.XOTclKeywords; |
| import org.eclipse.dltk.xotcl.internal.core.parser.XOTclCommandDetector.XOTclGlobalClassParameter; |
| |
| public class XOTclModelDetector extends TclModelBuilderUtil implements |
| ITclModelBuilderDetector { |
| |
| private static final String CLASS_PREFIX = "#Class#"; //$NON-NLS-1$ |
| private static final String OBJECT_PREFIX = "#Object#"; //$NON-NLS-1$ |
| static final String CREATE = "create"; //$NON-NLS-1$ |
| static final String INSTPROC = "instproc"; //$NON-NLS-1$ |
| static final String PROC = "proc"; //$NON-NLS-1$ |
| |
| private static final String CLASS_CREATE = CLASS_PREFIX + CREATE; |
| private static final String CLASS_NEW_INSTANCE = CLASS_PREFIX |
| + "$newInstance"; //$NON-NLS-1$ |
| // private static final String CLASS_PROC_CALL = CLASS_PREFIX + "$ProcCall"; //$NON-NLS-1$ |
| |
| private static final String OBJECT_CREATE = OBJECT_PREFIX + CREATE; |
| |
| private static final boolean INTERPRET_CLASS_UNKNOWN_AS_CREATE = true; |
| private static final boolean INTERPRET_OBJECT_UNKNOWN_AS_CREATE = true; |
| |
| public String detect(String commandName, TclCommand command, |
| ITclModelBuildContext context) { |
| if (commandName == null) { |
| return null; |
| } |
| commandName = normalize(commandName); |
| if (CLASS.equals(commandName)) { |
| return checkClass(command, commandName, context); |
| } else if (OBJECT.equals(commandName)) { |
| return checkObject(command, commandName, context); |
| } else { |
| return checkInstanceOperations(command, commandName, context); |
| } |
| } |
| |
| /** |
| * @param command |
| * @param context |
| * @return |
| */ |
| private String checkClass(TclCommand command, String commandName, |
| ITclModelBuildContext context) { |
| if (command.getArguments().isEmpty()) { |
| return null; |
| } |
| TclArgument subcmd = command.getArguments().get(0); |
| if (isSymbol(subcmd)) { |
| String value = asSymbol(subcmd); |
| // XOTclClassAttribute type = findXOTclType("Class"); |
| // if (type != null) { |
| // context.addAttribute(type); |
| // } |
| if (contains(value, XOTclKeywords.XOTclCommandClassArgs)) { |
| return CLASS_PREFIX + value; |
| } |
| String info = checkCreateType(context, command, commandName, |
| subcmd, value); |
| if (info != null) { |
| return info; |
| } |
| if (INTERPRET_CLASS_UNKNOWN_AS_CREATE) { |
| return CLASS_CREATE; |
| } |
| } |
| return null; |
| } |
| |
| private String checkObject(TclCommand command, String commandName, |
| ITclModelBuildContext context) { |
| if (command.getArguments().isEmpty()) { |
| return null; |
| } |
| TclArgument subcmd = command.getArguments().get(0); |
| if (isSymbol(subcmd)) { |
| String value = asSymbol(subcmd); |
| // XOTclClassAttribute type = findXOTclType("Object"); |
| // if (type != null) { |
| // context.addAttribute(type); |
| // } |
| if (contains(value, XOTclKeywords.XOTclCommandObjectArgs)) { |
| return OBJECT_PREFIX + value; |
| } |
| String info = checkCreateType(context, command, commandName, |
| subcmd, value); |
| if (info != null) { |
| return info; |
| } |
| // // Else unknown command or create command. |
| if (INTERPRET_OBJECT_UNKNOWN_AS_CREATE) { |
| return OBJECT_CREATE; |
| } |
| } |
| return null; |
| } |
| |
| private String checkCreateType(ITclModelBuildContext context, |
| TclCommand command, String commandName, TclArgument arg, |
| String value) { |
| if (value.equals(INSTPROC) || value.equals(PROC) || value.equals("set")) { |
| // context.addAttribute(new XOTclClassAttribute(commandName, command |
| // .getName())); |
| String info = checkCommands(value); |
| if (info != null) { |
| return info; |
| } |
| } |
| return null; |
| } |
| |
| private String checkCommands(String value) { |
| if (contains(value, XOTclKeywords.XOTclCommandClassArgs)) { |
| return CLASS_PREFIX + value; |
| } |
| if (contains(value, XOTclKeywords.XOTclCommandObjectArgs)) { |
| return OBJECT_PREFIX + value; |
| } |
| return null; |
| } |
| |
| private boolean contains(String value, String[] commands) { |
| for (int q = 0; q < commands.length; q++) { |
| if (value.equals(commands[q])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * @param command |
| * @param commandName |
| * @param context |
| * @return |
| */ |
| private String checkInstanceOperations(TclCommand command, |
| String commandName, ITclModelBuildContext context) { |
| if (command.getArguments().isEmpty()) { |
| return null; |
| } |
| final TclArgument subcmd = command.getArguments().get(0); |
| if (isSymbol(subcmd)) { |
| final XOTclNames names = XOTclNames.get(context); |
| if (names != null) { |
| final XOTclType type = names.resolve(commandName); |
| if (type != null) { |
| type.saveTo(context); |
| return check(subcmd); |
| } |
| } |
| } |
| // externally defined class? |
| if (commandName.length() >= 3) { |
| if (commandName.startsWith("::")) { |
| commandName = commandName.substring(2); |
| } |
| if (commandName.indexOf("::") > 0 |
| || Character.isUpperCase(commandName.charAt(0))) { |
| if (asSymbol(subcmd).equals(CREATE)) { |
| new XOTclType(commandName, null).saveTo(context); |
| return CLASS_NEW_INSTANCE; |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @param subcmd |
| */ |
| private String check(TclArgument subcmd) { |
| String value = asSymbol(subcmd); |
| if (!CREATE.equals(value)) { |
| String info = checkCommands(value); |
| if (info != null) { |
| return info; |
| } |
| } else { |
| return CLASS_NEW_INSTANCE; |
| } |
| return null; |
| } |
| |
| @SuppressWarnings("nls") |
| private static final String[] NAMESPACES = new String[] { "::xotcl::", |
| "xotcl::" }; |
| |
| private static final String CLASS = "Class"; //$NON-NLS-1$ |
| private static final String OBJECT = "Object"; //$NON-NLS-1$ |
| |
| /** |
| * Remove XOTcl namespaces from the specified command name |
| * |
| * @param commandName |
| * @return command name without namespace |
| */ |
| private String normalize(String commandName) { |
| for (String namespace : NAMESPACES) { |
| if (commandName.startsWith(namespace)) { |
| return commandName.substring(namespace.length()); |
| } |
| } |
| return commandName; |
| } |
| } |