Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 344875

Summary: [templates][templates view] TemplateContext.getVariable(String) method always returns null
Product: [Eclipse Project] JDT Reporter: Jim Mayer <jim>
Component: TextAssignee: Dani Megert <daniel_megert>
Status: RESOLVED WORKSFORME QA Contact:
Severity: normal    
Priority: P5 CC: daniel_megert
Version: 3.7   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard: investigate
Attachments:
Description Flags
Test case none

Description Jim Mayer CLA 2011-05-05 13:51:47 EDT
Build Identifier: 20110218-0911

It appears to be impossible to write a custom TemplateVariableResolver that references another variable in the TemplateContext.  JavaContext can do this, but relies on non-public methods.

Reproducible: Always

Steps to Reproduce:
1.Build the attached plugin
2.Create a template as described in the plugin documentation.
3.Invoke the plugin and watch the console output.
Comment 1 Jim Mayer CLA 2011-05-05 13:53:23 EDT
Created attachment 194857 [details]
Test case

See the class comment in TestVariableResolver.jar for information on running the test case.
Comment 2 Jim Mayer CLA 2011-05-05 13:55:32 EDT
I should add that I believe this problem applies to all platforms and operating systems.  I have personally observed this behavior on PC based Linux and Windows systems.
Comment 3 Dani Megert CLA 2011-05-06 02:51:40 EDT
The context in JDT is not API and there are no plans to change this. To get a variable you can use org.eclipse.jface.text.templates.TemplateContext.getVariable(String).
Comment 4 Jim Mayer CLA 2011-05-06 08:56:17 EDT
(In reply to comment #3)
> The context in JDT is not API and there are no plans to change this. To get a
> variable you can use
> org.eclipse.jface.text.templates.TemplateContext.getVariable(String).

That is what I tried initially.  The problem is that it doesn't work.  As shown in the attached test case, the org.eclipse.jface.text.templates.TemplateContext.getVariable(String) method always returns null.

The problem is that getVariable(string) is backed by TemplateContext.fVariables, but JavaContext overrides TemplateTranslator.createVariable and builds its own table.  Since JavaContext does not reimplement getVariable, it breaks the TemplateContext contract.

The other potential problem is that it appears that TemplateVariableResolver.resolve(variable,context) is not reevaluated when the dependent template variable is changes.  This means that given a template:

// ${name} -> ${changed:foo(name)}

We'd see the expansions:

(1) // [name] -> [changed]
(2) // [x] -> [changed]
(3) // [xy] -> [changed]
(4) // [xyz] -> [changed]

The "foo" variable resolver does not get called as "name" changes, so, even if it could see "name" (which it can't), it still couldn't expand property.

Perhaps the bug report should be changed to "JavaContext breaks the TemplateContext contract".

-- Jim
Comment 5 Dani Megert CLA 2011-05-06 09:00:19 EDT
>TemplateContext.getVariable(String) method always returns null.
I have problems to believe that because that's what's used in JDT for the template support.

Needs to be investigated to say more.
Comment 6 Dani Megert CLA 2012-01-09 10:59:45 EST
> org.eclipse.jface.text.templates.TemplateContext.getVariable(String) method
> always returns null.

I was not able to reproduce this. If you still have a problem using 3.8 M4 or newer, then please attach the sample plug-in which only uses API.