Getter/setter "is used reflectively but not in MirrorsUsed" warning after dart2js compilation - dart

In my class, I have getters and setters which are working thanks to NoSuchMethod - that is, they're not explicitly defined. After I compile and run the js, I get the following error in the browser console:
Warning: 'closes_in=' is used reflectively but not in MirrorsUsed. This will break minified code.
In this case, closes_in= is an example of such a setter and there are some other warnings related to other getters/setters too. I do have a #MirrorsUsed with the name of the library/class included and the resulting compiled js is actually smaller than it was without using #MirrorsUsed statements.
However, if a -m flag is passed to dart2js, then when the js program runs it fails - as predicted by the warning message.
Thus, I have two questions:
1. How do I write my #MirrorsUsed statement so that the warning goes away?
2. If it's not possible, how do I suppress the warning message? (because if it's not possible to solve the problem, then my only option would be to NOT minify the file then).

Related

Identifier shadows elements in Dart:core

If an identifier is defined in the current dart file, then that identifier shadows elements with the same identifier that are defined in other files included using the import directive. When using such an identifier in the current file, no errors occur, the version from the current file is used.
If some id is defined in file 1 and file 2, but is not defined in the current file, then an error will occur when trying to apply the identifier, which can be eliminated by using import prefixes or show, hide commands.
The logic described above is clear. But when working with the dart:core library, the following error may occur. Let's consider the cause of the error using the print function as an example.
If the print function is not defined in the current file and that function is defined in one of the import files, then the dart:core version of the library will be grayed out. No compilation errors that require an import prefix or the show/hide command will be generated.
The described situation can lead to confusion. The same applies to some other dart:core libraries. There are examples below.
// test2.dart
void print() {
}
// test.dart
import 'test2.dart';
void main() {
// some useful function from test2.dart
print2();
// static error due to inappropriate argument types,
// not due to collision with print function from dart:core
print('work is done');
}
This error persists when explicitly including the dart:core file.
In connection with what has been said, there are the following questions.
Will the dart developers read my message, or where do they need to forward it to read it?
Is this really a bug or was it meant to be? I propose to correct it so that the language is more simple and understandable.
I expected that if an identifier in one of the files matches an identifier from the dart:core library, the behavior will be the same as if a simple other package, file.
The rules for name conflicts are special for names coming from platform (dart:) libraries.
Normally if you import different declarations with the same name through two different imports, it's a conflict. You get an error if you try to refer to the name, because the compiler cannot figure out which one you mean.
However, if you import different declarations with the same name, and some, but not all, come from dart: libraries, then the declarations from the dart: libraries are ignored, and the non-platform libraries take precedence. (And if there is only one declaration from a non-dart: library, it just works as normal.)
The reason for this exception is that Dart libraries typically come from packages, where you can control which version of the library you get.
You won't get new declarations without doing a dart pub update or similar. That means that a new name conflict are only introduced at times where you are actively developing, and you can then handle.
Platform libraries come from the SDK, and your SDK can be updated independently of the packages you are working on. Even if you tested your application thoroughly and locked all your dependencies to specific version that you know will work, it might end up being run on a newer SDK.
Because of that, adding new declarations to the platform libraries was considered more dangerous than adding them to normal packages. To avoid it being practically impossible to add anything to the platform libraries, it was instead decided to not make such new conflicts into errors.
If the platform libraries introduce a new declaration, it should not affect your imports. It won't introduce a new conflict.
(It can cause other errors, because no API change in Dart is ever entirely safe, but at least it won't cause import conflicts.)

Prevent ArmClang to add calls to Standard C library

I am evaluating Keil Microvision IDE on STM32H753.
I am doing compiler comparison between ARMCC5 and AC6 in the different optimisation levels. AC6 is based on Clang.
My code is not using memcpy and I have unchecked "Use MicroLIB" in the project settings , However a basic byte per byte copy loop in my code is replaced by a memcpy with AC6 (only in "high" optimisation levels). It doesn't happen with ARMCC5.
I tried using compilation options to avoid that, as described here: -ffreestanding and -disable-simplify-libcalls, at both compiler and linker levels but it didn't change (for the second option, I get an error message saying that the option is not supported).
In the ARMCLANG reference guide i've found the options -nostdlib -nostdlibinc that prevent (??) the compiler to use any function of a standard lib.
However I still need the math.h function.
Do you know how to prevent clang to use functions from the Standard C Lib that are not explicitely called in the code ?
EDIT: here is a quick and dirty reproduceable example:
https://godbolt.org/z/AX8_WV
Please do not discuss the quality of this example, I know it is dumb !!, I know about memset, etc... It is just to understand the issue
gcc know a lot about the memcpy, memset and similar functions and even they are called "the builtin functions". If you do not want those functions to be used by default just use the command line option -fno-builtin
https://godbolt.org/z/a42m4j

Xcode 5 weird errors

Something strange is going on with my Xcode 5. All of a sudden I'm getting Undeclared Identifier errors for all the values in my Constants.h file, which is imported in my Prefix.pch file.
Two things are weird here:
This hasn't happened before.
When I do build and run, the build succeeds and the app runs with no problems.
I tried restarting Xcode and the simulator, and even restarting the whole machine. No luck.
What's going on? How can I get rid of these false errors?
EDIT following rmaddy's request. The error is Use of undeclared identifier kOffsetFromTop (for example, there are other similar errors with different constants.)
I don't really want to post my entire constants file, but the constant in question is defined like this:
static int const kOffsetFromTop = 20;
When this happens I normally do the following
Comment out the import from the .pch
Clean all ⌘⌥⇧K
Delete derived data
Build
Then uncomment the import from the .pch and build again. I'm not sure which step is actually sorting the issue but this normally gets me going again.
Multiple points here :
You have a warning, not an error. A warning is just that, it warns you but does not prevent the code to compile. That is just to warning you that something is odd or unexpected, or to tell you that what you wrote may not be actually what you were intended, because the compiler finds it odd or not standard.
You didn't have the warning before probably because it wasn't activated by default in previous versions of Xcode. The latest version of Xcode5 activates more warnings (which is a good thing, as it warns you about more things that could go wrong in your code and encourage you to fix them), hence this new one you have but didn't have before.
As I understand what you describe, tour usage of a constant is incorrect (and that's probably why Xcode emits a warning).
The correct way to declare a constant that you want to be accessible from multiple files is to:
Declare it (define its existence and type) in a header (or in your pch) like this: extern <type> const <name>;
And define it (give it a value) only in one implementation file (like your main.m, your AppDelegate.m, some Constants.m file, whatever) like this: <type> const <name> = <value>
Some details and reminders about constants declaration (also valid in standard C)
You use static <type> const <name> = <value>; in an implementation file only, when the constant is local to the file and does not need to be used by other files. In that case, you declare it typically in the .m file in which you will use it, and other files won't have access to it (which is quite what the static keyword means, actually (making the constant attached/local to the file).
In that matter, you should never declare a constant that way in a header file (and especially not in your .pch file), because header (and pre-compiled header) files will be included multiple times. If you do that, this would declare as many independent constants as the number of implementation files you include your headers into (this has evil side effects especially for pointers/objects, for exemple declaring an NSString* const that way -- for, say, using it as a notification name of error domain -- will create multiple string constants, with the same value but different addresses, which will probably not behave like you will expect)
When you need to declare a constant that you need to use / be accessible from multiple implementation files, so declaring this constant in a header file so that it is known to all implementation fiels that includes this header, you need to only declare it in the header, and not making it static (at this would run against the purpose of having the same constant for all files instead of multiple independent instances of the constant) but instead indicate extern to let the compiler know that its definition (value) is set elsewhere. Hence the solution given above.

Xcode 5 unit test seeing wrong class

I am running into a bizarre situation where a unit test's execution is behaving differently than the normal execution of a piece of code.
In particular, I am using a library called JSONModel, and when I am attempting to deserialize an object from a JSON string, one line in particular is causing problems when I step through the executing test case:
if ( [[property.type class] isSubclassOfClass:[JSONModel class]] ) ...
If I put a breakpoint before (or after) this line and execute:
expr [[property.type class] isSubclassOfClass:[JSONModel class]]
...in the debugger, it prints \x01 as the value (i.e. true), however when I actually step the instruction pointer, it behaves as though it is false, going instead into the else block. Again, typing the expression into the debugger again shows it as true even still.
I'm curious if anyone has seen similar behavior before and has any suggestions as to what could possibly be going wrong. I'm quite certain I'm not including different definitions for anything, unless Xcode has different internal cocoa class implementations for testing.
Update: Here's some even weirder evidence: I've added some NSLog statements to get an idea for how the execution is seeing things. If I log property.type.superclass I get JSONModel back (as expected); however if I log property.type.superclass == [JSONModel class] I get false!
To me this is indicating that the JSONModel the unit test execution is seeing is somehow a different JSONModel class that I'm seeing at runtime (and what it should be seeing). However, how that is happening I can't figure out.
Could this be caused by a forward class declaration or something like that?
Well I seem to have discovered a "solution" by experimentation. It turns out if I replace [JSONModel class] with NSClassFromString(#"JSONModel") it works swimmingly!
Now why this is I cannot say, and will give the answer to whoever can explain it!
I had the exact same problem, here's what was happening.
As expected with this kind of behaviour, it was an issue with the class being duplicated. As with you, [instance class] and NSClassFromString would return different values. However, the class were identical in all points : same ivar, same methods (checked with the obj runtime). No warning was displayed at compile, link and/or runtime
In my case, the tests were about a static library used in my main application (Bar.app).
Basically, I had 3 targets:
libFoo
libFooTests
Bar.app
The tests were performing on the device, and not on simulator. As such, they needed to be logic tests, and not unit tests, and had to be loaded into an application. The bundle loader was my main app, Bar.app.
Only additional linker flag was -ObjC
Now, Bar.app was linking libFoo.
It turns out, libFooTests was also linking libFoo.
When injecting libFooTests in the test host (Bar.app), symbols were duplicated, but no warning were presented to me. This is how this particular class got duplicated.
Simply removing libFoo from the list of libraries to link against in libFooTests did the trick.

F# Suppress Warnings

Sometimes I get annoying pattern matching and indent warnings when compiling F#. Is there a way to disable warnings? I'm pretty OCD over warnings.
In case you forget, you can type
let rec x = lazy(x.Value)
and get the warning
This and other recursive references to
the object(s) being defined will be
checked for initialization-soundness
at runtime through the use of a
delayed reference. This is because you
are defining one or more recursive
objects, rather than recursive
functions. This warning may be
suppressed by using '#nowarn "40"' or
'--nowarn:40'.
which shows that you can use either the compiler flag --nowarn on the command-line, or use the hash-directive #nowarn in your code. The warning number for each warning will be part of the build output (the Visual Studio error list does not display the numbers, so if in VS, build and then inspect the build output). Also, if inside VS, you can go to the project properties page, "Build" tab, and use the "warning level" selector and "suppress warnings" field (a semicolon-delimited list of numbers) to control which warnings are diplayed via the VS UI.
(BTW, I believe #nowarn only turns off the warning in the current file, whereas --nowarn turns it off for the entire project being compiled.)
See: Compiler Options (F#)
--nowarn:<int-list>:
Disable specific warnings listed by
number. Separate each warning number
by a comma. You can discover the
warning number for any warning from
the compilation output.
This compiler option is equivalent to
the C# compiler option of the same
name. For more information, see
/nowarn (C# Compiler Options).

Resources