Annotate getter from the property - annotations

In kotlin, we can define
var text: String
which will have a getter and a setter. It's easy to remove the setter by changing it to val, but what if we have a property that should only have the setter and no getter? Is there any way to create an annotation that we can apply to text that will deprecate the getter so others cannot use it?
The end goal is to be able to use the property syntax rather than call setText
Current workaround I am aware of that achieves a similar result:
var text: String
#Deprecated(level = DeprecationLevel.ERROR, message = "Non readable property")
get() = nonReadable()
set() ...
I would like to know if it's possible to define something similar to
#SetterOnly
var text: String
set() ...

I can tell you that there is no way to complete this feature in kotlin now. since the bug KT-3110 is not marked as Fixed.
I have test the following java code in kotlin at below, it only can access setter via setText:
public class Property {
public void setText(String text) {/**/}
private String getText() { return "foo"; }
}
which means you can't remove the getter/make the getter's visibility down. so it is impossible to get rid of the getter like as kotlin-allopen plugin. so one possible solution you can do is write your own kapt plugin to throws a compile-time error, for example:
#SetOnly var text:String = "foo";

If you don't want this property to be used externally, why dont you declare it as
private var text :String =""

Related

Non-static method cannot be called statically [duplicate]

Im trying to load my model in my controller and tried this:
return Post::getAll();
got the error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
The function in the model looks like this:
public function getAll()
{
return $posts = $this->all()->take(2)->get();
}
What's the correct way to load the model in a controller and then return it's contents?
You defined your method as non-static and you are trying to invoke it as static. That said...
1.if you want to invoke a static method, you should use the :: and define your method as static.
// Defining a static method in a Foo class.
public static function getAll() { /* code */ }
// Invoking that static method
Foo::getAll();
2.otherwise, if you want to invoke an instance method you should instance your class, use ->.
// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }
// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();
Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:
$foos = Foo::all()->take(10)->get();
In that code we are statically calling the all method via Facade. After that, all other methods are being called as instance methods.
Why not try adding Scope? Scope is a very good feature of Eloquent.
class User extends Eloquent {
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeWomen($query)
{
return $query->whereGender('W');
}
}
$users = User::popular()->women()->orderBy('created_at')->get();
Eloquent #scopes in Laravel Docs
TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10); instead of MyModel::find(10);.
To the best of my knowledge, starting PhpStorm 2017.2 code inspection fails for methods such as MyModel::where(), MyModel::find(), etc (check this thread), and this could get quite annoying.
One (elegant) way to get around this is to explicitly call ::query() wherever it makes sense to. This will let you benefit from free auto-completion and a nice formatting/indentating for your queries.
Examples
BAD
Snippet where inspection complains about static method calls
// static call complaint
$myModel = MyModel::find(10);
// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_foo', true)
->where('is_bar', false)
->get();
GOOD
Well formatted code with no complaints
// no complaint
$myModel = MyModel::query()->find(10);
// a nicely formatted and indented query with no complaints
$myFilteredModels = MyModel::query()
->where('is_foo', true)
->where('is_bar', false)
->get();
Just in case this helps someone, I was getting this error because I completely missed the stated fact that the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:
public function scopeRecentFirst($query)
{
return $query->orderBy('updated_at', 'desc');
}
You should call it like:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Note that the prefix scope is not present in the call.
Solution to the original question
You called a non-static method statically. To make a public function static in the model, would look like this:
public static function {
}
In General:
Post::get()
In this particular instance:
Post::take(2)->get()
One thing to be careful of, when defining relationships and scope, that I had an issue with that caused a 'non-static method should not be called statically' error is when they are named the same, for example:
public function category(){
return $this->belongsTo('App\Category');
}
public function scopeCategory(){
return $query->where('category', 1);
}
When I do the following, I get the non-static error:
Event::category()->get();
The issue, is that Laravel is using my relationship method called category, rather than my category scope (scopeCategory). This can be resolved by renaming the scope or the relationship. I chose to rename the relationship:
public function cat(){
return $this->belongsTo('App\Category', 'category_id');
}
Please observe that I defined the foreign key (category_id) because otherwise Laravel would have looked for cat_id instead, and it wouldn't have found it, as I had defined it as category_id in the database.
You can give like this
public static function getAll()
{
return $posts = $this->all()->take(2)->get();
}
And when you call statically inside your controller function also..
I've literally just arrived at the answer in my case.
I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.
Hope that help?
Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.
For use the syntax like return Post::getAll(); you should have a magic function __callStatic in your class where handle all static calls:
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}

A way to read a String as dart code inside flutter?

I want to build a method to dynamically save attributes on a specific object
given the attribute name and the value to save I call the "save()" function to update the global targetObj
var targetObj = targetClass();
save(String attribute, String value){
targetObj.attribute = value;
print(targetObj.attribute);
}
But I'm getting the following error:
Class 'targetClass' has no instance setter 'attribute='.
Receiver: Instance of 'targetClass'
Tried calling: attribute="Foo"
The only thing that I can think of is that "attribute" due to being type String results in an error.
That lead me to think if there is a way to read a String as code, something like eval for php.
As #Randal mentioned, you cannot create class..method at runtime. Still, you can try something like this.
A certain class
class Foo {
dynamic bar1;
dynamic bar2;
// ...
}
Your save method
save(Foo fooObject, String attribute, dynamic value) {
if ("bar1" == attribute) fooObject.bar1 = value;
else if ("bar2" == attribute) fooObject.bar2 == value;
// ...
}
Dart (and thus flutter) does not have a way to compile and execute code at runtime (other than dart:mirrors, which is deprecated). You can build additional code that derives from other code using the various builder mechanisms, although it can be rather complicated to implement (and use!).

Hiding property setters by class in Swift

I would like to hide some property setters and initializers on my Swift model objects. These are reference data that the server provides, and under no circumstances should they be created or modified by the application. This is simple enough in Swift.
However, there is application in my project (a separate target) that needs to break this rule. It is a tool I use to populate the data in bulk, so of course needs to be able to initialize new model objects and set their properties.
What are my options for accomplishing this? I would rather not use a completely new project since it will mean a lot of code duplication. Is there some language-level way to keep this mutability hidden from one application but available to another?
If you declare a property with the let keyword. It can then only be set in the init of the type.
You can also declare a private setter to make the property readonly from the caller of the type but read/write inside the type
struct Foo {
private(set) var bar: Bool = true
func toggle() {
bar.toggle()
}
}
var foo = Foo()
let barState = foo.bar // This works
foo.toggle() // This works too
foo.bar.toggle() // This will make a compile time error

AS3 - Private Object. Make property as read only

I have a object property in my Class which is private and marked as read-only.
private var readOnlyObj:Object;
I can only access it with a get method:
public function get readOnly(){ return readOnlyObj }
I can access it by:
var objClass = new MyClass();
trace(objClass.readOnly)
And if i'll try to modify it:
objClass.readOnly = new Object();
I'll get an error:
Error# Property is read only.
Now my question is:
How do I set the properties of my readOnlyObj as read-only?
If I have set the object in the constructor:
readOnlyObj["property1"] = 0;
And modify that property by:
objClass.readOnly["property1"] = 2;
It is valid. I want set the property1 to a read-only property. Is this possible? Thank You!
You can do this by returning a duplicate of the original object and not the object itself.
The transform properties of DisplayObjects work like this: you can get the object property from a get function and can modify the object, but such modification has no effect until you pass the modified object back to the set function.
In your case, there's no way to give the object back (no setter) and by returning a copy (commonly called 'clone') from the getter, there is no way to modify the object property from outside, because the returned reference reference the newly created independent clone, essentially making the internal object constant.
What you are asking is not possible and only yield the answer "no" if on the other hand you asked about how to achieve that functionality then there would be a few answer possible.
First of all given your code and the problem at hand it is clear that you misunderstand the class scope. You set:
private var readOnlyObj:Object;
As read only while it's really not the object you want to protect, it's its properties. So readOnlyObj should really not even be visible and accessible.
Now that readOnlyObj is private and not accessible, you can put together a simple method to retrieve properties:
public function getProperty(name:String):*
{
if(readOnlyObj[name] != undefined)
{
return readOnlyObj[name];
}
return null;
}
It might also be useful to know how to put together a public setter that cannot be used externally.
Create an internal Boolean variable (only with true package), then internally set that variable to true before setting the property then set it back to false. Since externally that boolean cannot be set you end up with a public setter that cannot be used externally.
internal var allowSetter:Boolean;
public function set whatever(value:*):void
{
if(allowSetter)
{
//set property ect...
allowSetter = false;
}
}
You can't really do this, at least in the way you describe. You can of course make your readOnly object a custom class instance that only has read-only properties, but you can't freeze a dynamic Object instance.

Eclipse JDT static field modifiers

I want to get the information about a field modifier. To be precise, I want to find out is the field a static one. For example, I want to examine the following code:
ASTParser parser = ASTParser.newParser(AST.JLS3);
How can I infer that the JLS3 is static field? I used getModifiers with Modifier.isStatic when analyzing methods and it worked fine. However, now I am not able to get the information that JLS3 in above code snippet is a static field. Is there something I am missing?
EDIT:
This is the code that I am using:
private boolean visit(SimpleName name){
boolean isStatic = Modifier.isStatic(name.resolveTypeBinding().getModifiers());
...
return true;
}
isStatic is false in the case of JLS3.
That's obviously wrong, use name.resolveBinding() instead of name.resolveTypeBinding() --- so you should get an object of type IVariableBinding.
name.resolveTypeBinding() returns the binding for the type of the field, but not the binding of field itself, which is not what you want here.