Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated file messages_all.dart produce an ERROR: 'lib' isn't a function. #492

Closed
dbacinski opened this issue Apr 6, 2017 · 17 comments
Closed

Comments

@dbacinski
Copy link

dbacinski commented Apr 6, 2017

File generated by command intl_translation:generate_from_arb fails to compile with an error 'lib' isn't a function. messages_all.dart:29

Command:

pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/strings.dart lib/i18n/*.arb

messages_all.dart:

// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that looks up messages for specific locales by
// delegating to the appropriate library.

import 'dart:async';

import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
import 'package:intl/src/intl_helpers.dart';

import 'messages_en.dart' as messages_en;

Map<String, Function> _deferredLibraries = {
  'en': () => new Future.value(null),
};

MessageLookupByLibrary _findExact(localeName) {
  switch (localeName) {
    case 'en':
      return messages_en.messages;
    default:
      return null;
  }
}

/// User programs should call this before using [localeName] for messages.
Future initializeMessages(String localeName) {
  var lib = _deferredLibraries[Intl.canonicalizedLocale(localeName)];
  var load = lib == null ? new Future.value(false) : lib(); // <-- HERE
  return load.then((_) {
    initializeInternalMessageLookup(() => new CompositeMessageLookup());
    messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
  });
}

bool _messagesExistFor(String locale) {
  var messages;
  try {
    messages = _findExact(locale);
  } catch (e) {}
  return messages != null;
}

MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
  var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
      onFailure: (_) => null);
  if (actualLocale == null) return null;
  return _findExact(actualLocale);
}

@dbacinski dbacinski changed the title Generate file does not compile: ERROR: 'lib' isn't a function. Generated file messages_all.dart does not compile: ERROR: 'lib' isn't a function. Apr 6, 2017
@alan-knight
Copy link
Contributor

Yes, the problem is that even though you said --no-use-deferred-loading it's generating an initialize that's trying to do a deferred load. Simple workaround is use deferred loading temporarily. Slightly more complicated, I think if you hand-edit the generated code and have it only do the then() part, that should work.

@dbacinski
Copy link
Author

dbacinski commented Apr 6, 2017

The same result for command:

pub run intl_translation:generate_from_arb --output-dir=lib/i18n lib/strings.dart lib/i18n/*.arb

messages_all.dart:

// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that looks up messages for specific locales by
// delegating to the appropriate library.

import 'dart:async';

import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
import 'package:intl/src/intl_helpers.dart';

import 'messages_en.dart' deferred as messages_en;

Map<String, Function> _deferredLibraries = {
  'en': () => messages_en.loadLibrary(),
};

MessageLookupByLibrary _findExact(localeName) {
  switch (localeName) {
    case 'en':
      return messages_en.messages;
    default:
      return null;
  }
}

/// User programs should call this before using [localeName] for messages.
Future initializeMessages(String localeName) {
  var lib = _deferredLibraries[Intl.canonicalizedLocale(localeName)];
  var load = lib == null ? new Future.value(false) : lib();
  return load.then((_) {
    initializeInternalMessageLookup(() => new CompositeMessageLookup());
    messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
  });
}

bool _messagesExistFor(String locale) {
  var messages;
  try {
    messages = _findExact(locale);
  } catch (e) {}
  return messages != null;
}

MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
  var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
      onFailure: (_) => null);
  if (actualLocale == null) return null;
  return _findExact(actualLocale);
}

Only difference between those two modes is:

import 'messages_en.dart' deferred as messages_en;

Map<String, Function> _deferredLibraries = {
  'en': () => messages_en.loadLibrary(),
};

@dbacinski
Copy link
Author

dbacinski commented Apr 6, 2017

I have changed implementation of initializeMessages and it works.

/// User programs should call this before using [localeName] for messages.
void initializeMessages(String localeName) {
  initializeInternalMessageLookup(() => new CompositeMessageLookup());
  messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
}

But it seams more like a workaround:)

@alan-knight
Copy link
Contributor

Yes, it's certainly a workaround.

When you say you're compiling this, what are you using to compile it? The error message that something isn't a function doesn't seem like one that comes from the VM. I'd expect the error message that something doesn't have the method 'call'. But also, it seems like there's no way that lib is not in fact a function. So this may actually be a bug or limitation of the thing you're using to compile. Possibly something doesn't think that Function is a function and wants something more specific.

@dbacinski
Copy link
Author

IntelliJ IDEA 2016.3.4
Build #IU-163.12024.16, built on January 31, 2017
JRE: 1.8.0_112-release-408-b6 x86_64
Dart Plugin Version: 163.13137
Flutter Plugin Version: 12.0

The error occurs in IntelliJ in Dart Analysis tab.

screen shot 2017-04-07 at 07 33 32

@dbacinski dbacinski changed the title Generated file messages_all.dart does not compile: ERROR: 'lib' isn't a function. Generated file messages_all.dart produce an ERROR: 'lib' isn't a function. Apr 7, 2017
@alan-knight
Copy link
Contributor

You could try upgrading your Dart plugin. I have 163.15188.8

I pasted your code directly in and it doesn't complain for me in WebStorm 2016.3.5 with that plugin and Flutter 12.1 (although I wouldn't expect Flutter to make a difference).

@jgroman
Copy link

jgroman commented May 19, 2017

I have the same problem even with Dart plugin 171.4424.63 and Flutter 13.1
The error message comes from dartanalyzer tool (https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) with strong static and strict call checking enabled:

C:\Users\Jerry\IdeaProjects\flutter_news>dartanalyzer -v --strong --enable-strict-call-checks ./lib/i18n/fnews_messages_all.dart
Analyzing lib\i18n\fnews_messages_all.dart...
Using default analysis options
    error - 'lib' isn't a function at lib\i18n\fnews_messages_all.dart:29:54 - invocation_of_non_function
            Try correcting the name to match an existing function, or define a method or function named 'lib'.
1 error found.

dartanalyzer help regarding strict call checking points to this issue: dart-lang/sdk#21938
It is possible to force dartanalyzer to ignore this "error" by adding:

  // ignore: invocation_of_non_function
  var load = lib == null ? new Future.value(false) : lib();

Maybe it would be possible to add this to autogenerated messages_all as a better workaround?

@alan-knight
Copy link
Contributor

Ah, it's the enable-strict-call-checks which does it, causing the analyzer to emit a false positive.

Adding a null check wouldn't help. The problem is that with strict call checking it doesn't think something of type Function can be called. An appropriate fix would be a more specific type on the map. But not using enable-strict-call-checks would also work.

@alan-knight
Copy link
Contributor

From the other bug, it seems like the behavior of that option is likely to change anyway.

@jgroman
Copy link

jgroman commented May 19, 2017

Seems that both options need to be present otherwise dartanalyzer does not emit this error. This setting is hardwired somewhere in IDEA Dart plugin with no obvious way to change it.
I mean null check is alrady present in generated code, I was thinking about only adding the comment line which supresses static call check for the lib() call.

@jgroman
Copy link

jgroman commented May 19, 2017

Seems that code analysis can be configured using config file: https://www.dartlang.org/guides/language/analysis-options
I guess we can just exclude generated files from analysis then.

@alan-knight
Copy link
Contributor

It's not obvious where that option would be set. @devoncarew , do you know? It doesn't seem to appear in any relevant source code.

Excluding generated files from analysis seems reasonable.

@devoncarew
Copy link
Member

Yes, you can use excludes: to ignore certain files, and you can ignore specific warnings entirely. Without looking into the specific cause of the error above though, you may be better off just changing the code so you don't encounter the error. /cc @bwilkerson

@jgroman
Copy link

jgroman commented May 20, 2017

Seems that excluding is currently broken in dartanalyzer: dart-lang/sdk#26212 and also it is acting up in IDEA: dart-lang/sdk#28754
I am quite new to Dart so I might be missing something but how about replacing lib() with Function.apply(lib, null)? Analyzer seems to be happy with this construct.

@bwilkerson
Copy link
Member

Yes, there does appear to be a problem with exclude. I saw it the other day but it went away when I restarted the server, so there might be a work-around.

@jgroman
Copy link

jgroman commented May 20, 2017

Yep, restart helps, but as soon as I open any analysis_options "excluded" file in editor, analyzer server analyzes it anyway.
I believe I finally found working exclude by setting up lib/i18n folder as excluded in Project Module settings:
idea_exclude
Also did a few tests with Function.apply(lib,null) in both deffered and non-deferred modes and it seems to be working fine.

@alan-knight
Copy link
Contributor

Published a 0.15.0 that should fix this, among other things.

@mosuem mosuem transferred this issue from dart-archive/intl_translation Apr 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants