Bug 242162 - [API] Please make usage of InferEngine more pluggable
Summary: [API] Please make usage of InferEngine more pluggable
Status: RESOLVED FIXED
Alias: None
Product: JSDT
Classification: WebTools
Component: General (show other bugs)
Version: 3.0   Edit
Hardware: PC Linux
: P2 major (vote)
Target Milestone: 3.2 M5   Edit
Assignee: Jacek Pospychala CLA
QA Contact: Nitin Dahyabhai CLA
URL:
Whiteboard:
Keywords: api
Depends on:
Blocks:
 
Reported: 2008-07-27 04:46 EDT by Michael Spector CLA
Modified: 2010-03-03 11:12 EST (History)
4 users (show)

See Also:
david_williams: pmc_approved-


Attachments
patch (12.92 KB, patch)
2009-12-15 11:51 EST, Jacek Pospychala CLA
no flags Details | Diff
patch v2 (12.95 KB, patch)
2009-12-16 03:47 EST, Jacek Pospychala CLA
no flags Details | Diff
patch v3 (13.58 KB, patch)
2010-01-07 07:35 EST, Jacek Pospychala CLA
cmjaun: iplog+
cmjaun: review+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Spector CLA 2008-07-27 04:46:39 EDT
Currently it's too much difficult to provide additional inference engine.
Comment 1 Phil Berkland CLA 2008-07-28 15:51:51 EDT
Would like to do this, but API changes are not allowed anymore for 3.0.* releases.   
WebTools PMC has denied previous request to make similar changes.
Will have to target for 3.1 (next year's release)
Comment 2 Marcus Better CLA 2009-01-05 11:25:17 EST
Here are some fields that I've run into when subclassing InferEngine, that should have protected access scope:

compUnit
currentContext
Comment 3 Nitin Dahyabhai CLA 2009-01-05 13:28:39 EST
If access protection for anything needs to be changed, the reasons for doing so need to be explained.  Michael, please start with specific members.  Marcus, please explain why those fields need to be visible, i.e. what you're trying to do that can't be accomplished with the current visibility.
Comment 4 Marcus Better CLA 2009-01-05 13:54:28 EST
(In reply to comment #3)
> please explain why those fields need to be visible,

I just discovered the findDefinedType method which removes the need for me to access compUnit. As for currentContext I got by without it in the end, so I retract my earlier comment. I'll fill in more information if I bump into any other issue with access.
Comment 5 Nitin Dahyabhai CLA 2009-01-05 14:59:51 EST
Thanks, Marcus.
Comment 6 Michael Spector CLA 2009-01-06 03:52:10 EST
We use the following methods/fields:

1. org.eclipse.wst.jsdt.core.infer.InferEngine.populateType(InferredType, ObjectLiteral, boolean)
2. org.eclipse.wst.jsdt.core.infer.InferEngine.currentContext
3. org.eclipse.wst.jsdt.core.infer.InferEngine.Context.currentType

But, I think we should think about possible implementors of this class; may be creating an interface for this class (and for Context) is better even.


(In reply to comment #3)
> If access protection for anything needs to be changed, the reasons for doing so
> need to be explained.  Michael, please start with specific members. 
Comment 7 Nitin Dahyabhai CLA 2009-03-11 18:36:51 EDT
(In reply to comment #6)
> We use the following methods/fields:
> 
> 1. org.eclipse.wst.jsdt.core.infer.InferEngine.populateType(InferredType,
> ObjectLiteral, boolean)
> 2. org.eclipse.wst.jsdt.core.infer.InferEngine.currentContext
> 3. org.eclipse.wst.jsdt.core.infer.InferEngine.Context.currentType
> 
> But, I think we should think about possible implementors of this class; may be
> creating an interface for this class (and for Context) is better even.

You're right, although I think Context could stay as a concrete class while InferEngine becomes an interface.  For now, though, InferEngine is at least a public class and M6 should support multiple InferrenceProviders properly.




Submitting to PMC review for M7 to create an IInferEngine interface, deprecate the current class in favor of a "DefaultInferEngine" replacement, and turn the internal static class, "Context", into a public top-level class of its own.
Comment 8 David Williams CLA 2009-03-11 18:50:05 EDT
Can you explain a bit more what this new API is for? What is trying to be accomplished? Is it something like different library formats? Some new functionality? 

Comment 9 Nitin Dahyabhai CLA 2009-03-11 19:57:11 EDT
It can be used for different libraries and their documentation formats to determine additional object types for use later during resolution.  Largely it's a refactoring since the current InferrenceProvider interface returns the concrete InferEngine class.  Interaction with that class is done as an ASTVisitor with a few initializers, so it's possible that we should create an abstract class above it instead.
Comment 10 David Williams CLA 2009-03-12 02:56:11 EDT
Thanks Nitin. This sounds like some very important function and some very good changes. But, it does sound like "new" function, and post M6 is not the time to get started on new function -- finish it up maybe, but not get started. The odds are great it would take 2 or 3 milestones to "get right". 

I think your intentions are good in trying to help out others in the community, but how much would we use this API in WTP itself this release? ... so that we'd know if it was right and met several use-cases? You even say "so it's possible that we should create an abstract class above it instead." and similar remarks in other comments make it sound like this API is still being designed. Again, post M6 is not the time to start designing an API for the release. Post M6 exceptions are more for finishing touches on a new API that has been there a milestone or two, and a just discovered changes found to be required to finish it up, or handle corner cases. 

If you wanted to get started on it now, I think that's great, but it should be in a side branch, where it can iterate a few times before being finalized in the next release, presumably the 3.2 release we are considering for Dec. 

Thanks for bringing it forward for consideration. It does sound important, just too risky in knowing you had the API right in such a short time. 
Comment 11 Chris Jaun CLA 2009-09-15 10:51:48 EDT
Categorizing JSDT bugzillas for planning purposes.
Comment 12 Jacek Pospychala CLA 2009-12-15 11:47:36 EST
hi, can we get back to this topic?

For start it would be good to separate InferEngine from ASTVisitor, as not every inference engine has to be ASTVisitor.
From current JSDT code, my understanding is that inference engine works following way:
1. InferEngine.initialize();  is called from Parser
 -> InferEngine uses this for some internal initialization
2. InferEngine.setCompilationUnit(CompilationUnitDeclaration parsedUnit); is called from Parser
 -> InferEngine uses this to attach itself to compilation unit
3. InferEngine.doInfer(); is called from Parser
 -> InferEngine does it's main work here
 4. InferEngine adds types to CompilationUnitDeclaration passed ealier by changing following public fields:
 - compUnit.numberInferredTypes - number of inferred types
 - compUnit.inferredTypes - array with inferred types
 - compUnit.inferredTypesHash - map with inferred types
5. InferEngine also sometimes uses following method to query for already found types:
compUnit.findInferredType(key) - alias for compUnit.inferredTypesHash.get(key)

More than one InferEngine can be executed on compUnit, so engines should be careful about it.
There are also some fields (appliesTo and inferenceProvider) in InferEngine, that can be changed by InferenceManager.
And there are two static fields accessed by others.

is this all that one should know when implementing his own inference engine?
Comment 13 Jacek Pospychala CLA 2009-12-15 11:51:57 EST
Created attachment 154494 [details]
patch

first take on extracting InferEngine to interface.
Based on previous comment.

Patch was created by searching for all references to InterEngine and replacing them with IInferEngine. I intentionally left some references to InferEngine in tests plug-in, because that tests probably test only this one particular InferEngine class.
Comments are welcome. (patch is based on HEAD)
Comment 14 Nitin Dahyabhai CLA 2009-12-15 13:54:30 EST
I like it, but why the IInferengine#setAppliesTo(boolean)?  org.eclipse.wst.jsdt.core.infer.InferrenceProvider#applysTo(IInferenceFile) is responsible for telling InferenceManager that a particular engine should be run; I'm not sure why you'd need to tell the engine anything.
Comment 15 Jacek Pospychala CLA 2009-12-16 03:41:50 EST
I added IInferEngine.setAppliesTo(int), to correctly refactor two assignments to inferEngine.appliesTo field in InferenceManager in lines 61 and 71. But indeed, the InferEngine.appliesTo field is never read, so it can probably be removed together with IInferEngine.setAppliesTo
Comment 16 Jacek Pospychala CLA 2009-12-16 03:47:07 EST
Created attachment 154546 [details]
patch v2

updated patch with removed InferEngine.appliesTo, IInferEngine.setAppliesTo(int) and related assignments in InferenceManager
Comment 17 Jacek Pospychala CLA 2009-12-28 10:02:06 EST
Nitin, assuming there's no other concerns, would it be possible to commit last patch?

A possible next step could be to separate out ASTVisitor from InferEngine. This would make InferEngine more a utility class that helps manage context (push/pop) and types (findType, populateType, etc.). The real action would still stay in ASTVisitor but it'd be easier to switch between different visitors.
Comment 18 Nitin Dahyabhai CLA 2010-01-05 10:31:53 EST
Looks good, but IInferEngine#setInferenceProvider(InferrenceProvider) isn't actually needed, it's more of an implementation detail that's unrelated to how that interface is meant to used.  Since the engines are always and only created by their inferrence provider, the provider can take care of that using whatever contract it wants.

If nothing else I want to actively discourage anyone *else* from being able to tamper with that value.
Comment 19 Jacek Pospychala CLA 2010-01-07 07:35:28 EST
Created attachment 155488 [details]
patch v3

Updated the patch to remove setInferenceProvider() as pointed out by Nitin in comment 18. Indeed DefaultInferenceProvider takes care of setting inferenceProvider field in InferEngine (default impl). So InferenceManager or anyone else should not re-set this.

I also added a little javadoc to IInferEngine.
Comment 20 Chris Jaun CLA 2010-01-08 14:29:08 EST
Thank you for your work on this patch Jacek and for your quick response to our feedback.

v3 patch has been checked into 3.2m5.