JSDT is the JavaScript IDE now provided within the Web Tools Platform, a vendor neutral, standards oriented basis for web tools in Eclipse. Being vendor neutral, however, means not playing favorites among the many JavaScript toolkits being used to create Web 2.0 sites. Just as WTP offers mechanisms for application server vendors to have first class support within Eclipse, so too does JSDT offer extension points for enriching the experience when working with your JavaScript toolkit of choice. This presentation covers the limitations to JSDT's built-in language support and how to aid it in inferring type information from your sources and leveraging custom documentation formats.
This is “Supporting Javascript Toolkits – and its intended for developers to discover the underlying JSDT framework, and also the available extensions required to support the various Javascript toolkits and libraries.
WTP’s Original Javascript editor – Available in WTP 2.0 (Europa) - based on WTP’s SSE Framework
The original editor, based on WTP’s source editor framework, - provided simple syntax coloring, content assist on a limited list of well know browser objects. - It supported not only JS files, but also integration within the existing HTML and JSP editors
But restrictions start to pile up: - The editor provided no pluggable facility to upgrade syntax level as Javascript versions were released, - There was no extension mechanism for adding more objects / classes/ functions/ libraries. - No model existed to help provide features such as advanced content assist, hover help, refactoring, any meaningful semantic validation
JSDT began as a project by a small team within IBM Research. It became part of the Eclipse ATF project right around the time we started turning a critical eye to WTP’s JavaScript support and finding it lacking when it came to real world scenarios. JSDT’s abilities already surpassed what was in WTP 2.0, and once it was able to provide a similar level of integration with the other source editors, it was moved from ATF to become part of the WTP 3.0 release
As with many IDEs built on top of Eclipse, JSDT followed the tried-and-true route of starting as a fork from the JDT sources, in this case from a late JDT 3.3 milestone.
Among other changes, - parser was modified to support JavaScript syntax, - the compiler altered to not write out byte codes , - the Semantic analyzer and Search was updated, - the type resolution in the compiler altered to support the less stringent demands of JavaScript.
The core jsdt package has only the platform as a pre-req.
Components (Features) from WTP’s Common and Source Editing projects that support editing web pages also include the necessary plug-ins for integrating JSDT.
Java, in many ways, is designed for IDE support. A statically typed language, a Java compiler can relatively easily determine the type of a variable, and find whether a message being sent will be understood by that variable, or whether a field access will actually resolve properly. The evaluation of expressions is clearly defined for a given set of operands. Methods can only be defined to return objects of one type or satisfying one interface. The ordered classpath and source file layout ensure that for a given fully qualified type name, the matching source or binary file must be in one location relative to an entry in the classpath, which must searched in that order. All of the members of a type must also be defined in that single file or otherwise inherited from a supertype listed with the type declaration, for which there is a reserved keyword.
The dynamic (“duck”) typing allows for incredibly expressive and functional code to be written a very compact form. I come from a smalltalk background, and loved the elegance and simplicity But, this freedom can be daunting for programmers used to static type restrictions, and increasingly hard to navigate as the code base grows ever larger.
So how does JSDT tackle these “shortcomings” in the language to provide a high quality experience similar to that provided by JDT, but for JavaScript?
JavaScript doesn’t define a standard for how to work with content across multiple files. Web pages can define which script files they use statically.
or have that list of inclusions modified through client-side scripting or server-side scripting
The solution JSDT employs is to reuse the familiar JDT Build Path model, this time an an Include Path for folders whose files’ contents are simply always known to each other.
JSDT thus also inherits JDT’s support allowing plug-ins to contribute reusable libraries and containers to simplify working within teams.
the APIs for looking up types no longer restrict results with the expectation that a type be represented in one file—the model returns as many types of the same name as there are files declaring them,
or properties of them based on information provided from the inference engine - So what is an Inference engine?
Whether someone thinks JavaScript has or doesn’t have Types, it’s still a useful approach to working with source code in an IDE. A Java compiler, in one of its earlier stages, will convert the source into an Abstract Syntax Tree (AST). This representation models the types, methods, and fields, all the way down to individual statements and the expressions that compose them. The expressions declare which types are in use. JSDT also creates an AST, but then attempts to perform type inference using static analysis of the syntax tree along with any inline documentation. Common coding practices are recognized and used to infer types and their properties, those findings then used to drive IDE functions such as the Outline view, Content Assist, explorer views, and Search. This analysis is encapsulated in what we refer to as an Inference Engine . JSDT’s built-in inference engine recognizes the prototype keyword, types of literals, constructor-like usage of functions, type information documented using JSDoc, and more cases I won’t list here. It’s at this point that JSDT’s support for AJAX toolkits falters, many libraries having a unique or specific way to define types that eludes detection by our inference engine. And here’s where the most significant of our extension points comes into play: org.eclipse.wst.jsdt.core.inferrenceSupport
This extension point allows a plug-in developer to contribute their own Inference Engine to run on a file for analysis. That engine has access to the internal compiler AST, allowing it to add inferred types and members to JSDT’s knowledge of a particular file. org.eclipse.wst.jsdt.core.infer.IInferEngine – the interface all inference engines must implement org.eclipse.wst.jsdt.core.infer.InferEngine – our default implementation, largely built as an ASTVisitor. org.eclipse.wst.jsdt.internal.compiler.ast.CompilationUnitDeclaration – an object that provides the inference engines access to a single file’s location
org.eclipse.wst.jsdt.core.infer.InferredType – represents a “type” as a JavaScript developer might think of it. If a toolkit doesn’t use constructor functions directly, an engine can still add types so that they’re available for content assist and search. An inferred type is limited to knowing the fields and methods contained in the one file that the CompilationUnitDeclaration holds. InferredTypes are expected to be added for all referenced types and all declared types, even if it’s just for adding one property to a type that’s formally declared in a different file. Types that don’t have names (object literals) should also be added for completeness.
org.eclipse.wst.jsdt.core.infer.InferredMethod – represents any property of an object that points to a function by encapsulating that function expression. Different InferredMethods on different InferredTypes are allowed to point to the same function. Static analysis of the function and its documentation is used by the inference engine to set up type information for the method’s return type and argument types
org.eclipse.wst.jsdt.core.infer.InferredAttribute – a property of an object that is not a function, static analysis and documentation is used by the inference engine to set up type information for the attribute.
When JSDT is indexing your sources, it’s using these objects to help populate its Search Index. They’re also converted, as needed, into the IJavaScriptElements used to populate JSDT’s model and shown throughout JSDT’s UI. The declared engines have the critically important duty of thoroughly finding all of the declared types and picking the right offsets for the name of the inferred types and members, as that will be used when navigating with hyper-links, showing search results, and eventually proper Refactoring support. Without good engines, all you really get is syntax coloring.
Multiple inference engines can be run on the same file, allowing for the supporting of mixed coding styles and the derivation of type information from any number of inline documentation formats. Work is ongoing in the area of getting engines to coexist properly, and avoid duplicating both results and performance problems.
JSDT offers a general view for rendering documentation written in JSDoc, a format chosen in part because it is not tied to a particular toolkit and also for its resemblance to JavaDoc.
Tellingly, it’s not called the JSDoc view because as with the type inference mechanism, JSDT doesn’t assume that all documentation is written as JSDoc.
Enter the org.eclipse.wst.jsdt.ui.documentationProvider extension point. This extension point allows a plug-in developer to contribute a class for providing the text documentation associated with a type or member, as well as for rendering it into HTML for use in the Documentation view--an implementer of org.eclipse.wst.jsdt.ui.IDocumentationReader It is expected to provide a Reader for the documentation text as well as a Reader for the documentation text converted into HTML for a styled display.
“ Some” upgrades to ECMA5 will be finished by Indigo
Validation: working on filtering out problems in JSDT for unresolved fields/methods/types, duplicate variables JavaScript has a single function scope