HMR
HMR

Reputation: 39250

Trying to get JavaScript code completion to work in netbeans with jsdoc

In my app.js I have the following:

angular.module('app').controller('userList', 
  ['appSettings'
 ,function (/*@type {app.appSettings}*/appSettings) {  
   appSettings.<<== it shows a list here but nothing from autocomplete.js

In my autocomplete.js I have the following (generated by JavaScript printing out my services and their members):

var app={};
app.appSettings={};
app.appSettings.userFailMessages={};
app.appSettings.userFailMessages.invalidJson
  ="Invalid request, user sent is not valid json.";

NetBeans refuses to code complete appSettings for me and doesn't seem to know it's defined in autocomplete.js. Maybe I'm getting my js doc wrong but tried a mix of combination of @var, @type and @param without success.

It code completes when I type app.appSettings. and gives me a list from autocomplete.js but I would like to know how I can tell NetBeans that the passed argument to the function is app.appSettings.

Maybe I should have autocomplete contain constructor functions instead of object literals as @type suggests a certain type and not an instance.

This is NetBeans 7.3.1

Upvotes: 1

Views: 623

Answers (1)

HMR
HMR

Reputation: 39250

Was close to the answer, to have NetBeans use type you have to define the type. Then to indicate that the parameters passed to your angular module (or any function) are of a certain type I use the @param jsdoc

The angular module:

angular.module('app').controller('userList'
 , ['$scope','appRules','appSettings'
 ,/**
* @param {app.appRules} appRules
* @param {app.appSettings} appSettings
* */
 function ($scope,appRules,appSettings,$timeout) {
   //<== here both appRules and appSettings give suggestions
   //  from autocomplete

autocomplete.js (not included in my html file but just there for code suggest)

/*@typedef {Object} app*/
var app={};
app.appRules={};
app.appRules.userIsInRole=function (user,role){};
app.appRules.general={};
app.appRules.general.isEmpty=function (val){};
app.appRules.general.isEmail=function (val){};
app.appSettings={};
app.appSettings.userFailMessages={};
app.appSettings.userFailMessages.invalidJson
 ="Invalid request, user sent is not valid json.";
app.appSettings.userFailMessages.noPrivilege
 ="You do not have the privileges needed to change this user.";

I ran the following code in the console on a page that contains my app to generate autocomplete.js:

var inj;
function allServices(mod, r) {
  if (!r) {
    r = {};
    inj = angular.element(document.querySelector('[data-ng-app]')).injector().get;
  }
  angular.forEach(angular.module(mod).requires, function(m) {
    allServices(m, r)
  });
  angular.forEach(angular.module(mod)._invokeQueue, function(a) {
    try {
      r[a[2][0]] = inj(a[2][0]);
    } catch (e) {
    }
  });
  return r;
};

var output=[];
function addOutput(names,prop){
  if(names.length===1){
    output.push('var ');
  }
  output.push(names.join('.'));
  if(typeof prop === 'object'){
    output.push('={};\n');
    for(thing in prop){
      //TODO: no arrays or route paths
      if(/[0-9\/\\]/.test(thing)){
        continue;
      }
      names.push(thing);
      addOutput(names,prop[thing]);
    }
  }else{
    output.push('=');
    output.push(
      (typeof prop === 'function')?
      prop.toString():
      JSON.stringify(prop)
    );
    output.push(';\n');
  }
  names.pop();
}

function createOutput(){
  allMyServices = allServices('app');
  addOutput(['app'],allMyServices);
  console.log(output.join(''));
}


createOutput();

Upvotes: 1

Related Questions