package org.rubypeople.rdt.internal.corext.template.ruby; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.templates.GlobalTemplateVariables; import org.eclipse.jface.text.templates.SimpleTemplateVariableResolver; import org.eclipse.jface.text.templates.TemplateContext; import org.rubypeople.rdt.core.IMethod; import org.rubypeople.rdt.core.IRubyElement; import org.rubypeople.rdt.core.IRubyScript; import org.rubypeople.rdt.core.IType; import org.rubypeople.rdt.core.RubyModelException; import org.rubypeople.rdt.internal.ui.RubyPlugin; public class RubyContextType extends RubyScriptContextType { public static final String NAME = "ruby"; //$NON-NLS-1$ /** * Creates a ruby context type. */ public RubyContextType() { super(NAME); // global variables addResolver(new GlobalTemplateVariables.Cursor()); addResolver(new GlobalTemplateVariables.WordSelection()); addResolver(new GlobalTemplateVariables.LineSelection()); addResolver(new GlobalTemplateVariables.Dollar()); addResolver(new GlobalTemplateVariables.Date()); addResolver(new GlobalTemplateVariables.Year()); addResolver(new GlobalTemplateVariables.Time()); addResolver(new GlobalTemplateVariables.User()); // ruby specific template variables addResolver(new File()); addResolver(new Path()); addResolver(new Class()); addResolver(new ClassFullyQualifiedName()); addResolver(new Method()); addResolver(new MethodFullyQualifiedName()); } /* * (non-Javadoc) * * @see org.rubypeople.rdt.internal.corext.template.ruby.RubyFileContextType#createContext(org.eclipse.jface.text.IDocument, * int, int, org.rubypeople.rdt.core.IRubyScript) */ public RubyScriptContext createContext(IDocument document, int offset, int length, IRubyScript script) { return new RubyContext(this, document, offset, length, script); } /** * The file variable evaluates to the current filename. */ public static class File extends SimpleTemplateVariableResolver { /** * Creates a new file name variable */ public File() { super("file", "Expands to the current filename, such as foo.rb"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * {@inheritDoc} */ protected String resolve(TemplateContext context) { if (context instanceof RubyScriptContext) { RubyScriptContext rsContext = (RubyScriptContext) context; IRubyScript script = rsContext.getRubyScript(); return script.getElementName(); } return ""; } } /** * The path variable evaluates to the current filename path. */ public static class Path extends SimpleTemplateVariableResolver { /** * Creates a new path name variable */ public Path() { super("path", "Expands to the name of the current full file path, such as /foo/bar.rb"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * {@inheritDoc} */ protected String resolve(TemplateContext context) { if (context instanceof RubyScriptContext) { RubyScriptContext rsContext = (RubyScriptContext) context; IRubyScript script = rsContext.getRubyScript(); IPath path = script.getPath(); if (path.segmentCount() > 0 && path.segment(0).equals(script.getRubyProject().getElementName())) { path = path.removeFirstSegments(1); } return path.toPortableString(); } return ""; } } // TODO Refactor all the common code shared by these variable resolvers (tehre's quite a bit here) /** * The class variable evaluates to the current surrounding type name. */ public static class Class extends SimpleTemplateVariableResolver { /** * Creates a new class name variable */ public Class() { super("class", "Expands to the name of the class surrounding the template expansion location, such as Foo"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * {@inheritDoc} */ protected String resolve(TemplateContext context) { try { if (context instanceof RubyScriptContext) { RubyScriptContext rsContext = (RubyScriptContext) context; IRubyScript script = rsContext.getRubyScript(); IRubyElement element = script.getElementAt(rsContext.getStart()); if (element == null) return ""; IType type = null; if (element.isType(IRubyElement.TYPE)) { type = (IType) element; } else { type = (IType) element.getAncestor(IRubyElement.TYPE); } if (type != null) return type.getElementName(); } } catch (RubyModelException e) { RubyPlugin.log(e); } return ""; } } /** * The classfqn variable evaluates to the current surrounding type's fully qualified name. */ public static class ClassFullyQualifiedName extends SimpleTemplateVariableResolver { /** * Creates a new classfqn name variable */ public ClassFullyQualifiedName() { super("classfqn", "Expands to the fully qualified name of the class surrounding the template expansion location, such as Foo::Bar"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * {@inheritDoc} */ protected String resolve(TemplateContext context) { try { if (context instanceof RubyScriptContext) { RubyScriptContext rsContext = (RubyScriptContext) context; IRubyScript script = rsContext.getRubyScript(); IRubyElement element = script.getElementAt(rsContext.getStart()); if (element == null) return ""; IType type = null; if (element.isType(IRubyElement.TYPE)) { type = (IType) element; } else { type = (IType) element.getAncestor(IRubyElement.TYPE); } if (type != null) return type.getFullyQualifiedName(); } } catch (RubyModelException e) { RubyPlugin.log(e); } return ""; } } /** * The method variable evaluates to the current surrounding method name. */ public static class Method extends SimpleTemplateVariableResolver { /** * Creates a new method name variable */ public Method() { super("method", "Expands to the name of the method surrounding the template expansion location, such as foo"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * {@inheritDoc} */ protected String resolve(TemplateContext context) { try { if (context instanceof RubyScriptContext) { RubyScriptContext rsContext = (RubyScriptContext) context; IRubyScript script = rsContext.getRubyScript(); IRubyElement element = script.getElementAt(rsContext.getStart()); if (element == null) return ""; IMethod method = null; if (element.isType(IRubyElement.METHOD)) { method = (IMethod) element; } else { method = (IMethod) element.getAncestor(IRubyElement.METHOD); } if (method != null) return method.getElementName(); } } catch (RubyModelException e) { RubyPlugin.log(e); } return ""; } } /** * The methodfqn variable evaluates to the current surrounding method's fully qualified name. */ public static class MethodFullyQualifiedName extends SimpleTemplateVariableResolver { /** * Creates a new methodfqn name variable */ public MethodFullyQualifiedName() { super("methodfqn", "Expands to the fully qualified name of the method surrounding the template expansion location, such as Foo::Bar#foo"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * {@inheritDoc} */ protected String resolve(TemplateContext context) { try { if (context instanceof RubyScriptContext) { RubyScriptContext rsContext = (RubyScriptContext) context; IRubyScript script = rsContext.getRubyScript(); IRubyElement element = script.getElementAt(rsContext.getStart()); if (element == null) return ""; IMethod method = null; if (element.isType(IRubyElement.METHOD)) { method = (IMethod) element; } else { method = (IMethod) element.getAncestor(IRubyElement.METHOD); } if (method != null) { IType type = method.getDeclaringType(); String name = ""; if (type != null) { name += type.getFullyQualifiedName(); } if (method.isSingleton()) { name += "::"; } else { name += "#"; } name += method.getElementName(); return name; } } } catch (RubyModelException e) { RubyPlugin.log(e); } return ""; } } }