FSharpLint, how to use the rule "InterfaceNamesMustBeginWithI" in SuppressMessageAttribute? - visual-studio-code

[<SuppressMessage("NameConventions","InterfaceNamesMustBeginWithI")>] //No effect
[<SuppressMessage("NameConventions","InterfaceNames")>] //It's working
module Test=
type [<AllowNullLiteral>] MutationEvent =
abstract attrChange: float with get, set
...
Also, failed to search source code about "InterfaceNamesMustBeginWithI".

The name of the rule is InterfaceNames, so you can suppress it thus:
[<SuppressMessage("","InterfaceNames")>]
module Test =
...
Also note that the first argument to SuppressMessage is not used by fsharplint, so it can be anything (although not null, strangely enough!)
There are pointers to InterfaceNamesMustBeginWithI in the documentation, but this is not correct.

Related

How to select and set a covering/covered annotation as a feature in RUTA

I have a Ruta rule that looks something like this, where dep is a DKPro imported Dependency type.
dep{}->{MyItem{->
SETFEATURE("Display", "displayedValue"),
SETFEATURE("Lemma", dep.Dependent.lemma.value),
SETFEATURE("Parent", dep.Governor)};};
The first two actions work. The problem I have is in the third action SETFEATURE("Parent", dep.Governor). dep.Governor returns a Token type but my feature requires another type that happens to share the same location as the Governor. In other words I want my own type, not dep.Governor, that has already annotated that governing word.
I am unsure how to recover an annotation (my annotation) that occupies the same space as the dep.Governor. Ideally I would like to recover it as a variable so that I can reuse it for other features to do something like this.
a:MyItem [that overlaps dep.Governor]
dep{}->{MyItem{->SETFEATURE("Parent", a)};};
Here is a more precise example
d:dep.Dependency{->
MyItem,
MyItem.Display = "Ignore",
MyItem.Lemma = d.Dependent.lemma.value,
MyItem.LanguageParent = d,
};
The line MyItem.LanguageParent = d produces this Ruta error
Trying to access value of feature "type.MyItem:LanguageParent" as "type.MyItem", but range of feature is "de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency"
I am sure there is a cleaner way than this, but for now, I am converting the type using a block function and saving it into an annotation variable.
BLOCK(ConvertTokenToMyItem) Token{IS(MyItem)} {
varMyItem:MyItem;
}
Then I use it
d:dep.Dependency{->
MyItem,
MyItem.Display = "Ignore",
MyItem.Lemma = d.Dependent.lemma.value,
MyItem.LanguageParent = varMyItem,
};

Supporting "recursive objects" in lua

I'm fairly new to lua and have the following problem with an assignment from a class:
We currently extend lua to support objects and inheritance. The Syntax for that is
Class{'MyClass',
attribute1 = String,
attribute2 = Number
}
Class{'MySubClass', MyClass,
attribute3 = Number
}
This works perfectly fine. The real problem lies within the next task: We should support "recursive types", that means a call like
Class{'MyClass', attribute = MyClass}
should result in an class with a field of the same type as the class. When this "class-constructor" is called the variable MyClass is nil, thats why the parameter table doesnt't have an entry attribute. How is it possible to access this attribute?
My first thought was using some kind of nil-table which gets returned every time the global __index is called with an unset key. This nil-table should behave like the normal nil, but can be checked for in the "class-constructor". The problem with this approach are comparisons like nil == unknown. This should return true, but as the __eq meta method of the nil-table is never called we cannot return true.
Is there another approach I'm currently just ignoring? Any hint is greatly appreciated.
Thanks in advance.
Edit:
Here the relevant part of the "testfile". The test by which the code is rated in class is another one and gets published later.
three = 3
print( three == 3 , "Should be true")
print( unknown == nil , "Should be true" )
Class{'AClass', name = String, ref = AClass}
function AClass:write()
print("AClass:write(), name of AClass:", self.name)
end
aclass = AClass:create("A. Class")
aclass:write()
Since MyClass is just a lookup in the global table (_G), you could mess with its metatable's __index to return a newly-defined MyClass object (which you would later need to fill with the details).
However, while feasible, such an implementation is
wildly unsafe, as you could end up with an undefined class (or worse, you may end up inadvertantly creating an infinite lookup loop. Trust me, I've been there)
very hard to debug, as every _G lookup for a non-existing variable will now return a newly created class object instead of nil (this problem could somewhat be reduced by requiring that class names start with an uppercase character)
If you go that route, be sure to also override __newindex.
How about providing the argument in string form?
Class{'MyClass', attribute = 'MyClass'}
Detect strings inside the implementation of Class and process them with _G[string] after creating the class
Or alternatively, use a function to delay the lookup:
Class{'MyClass', attribute = function() return MyClass end}

How to pass parameters to a Progress program using database field dynamic-based rules?

I have in my database a set of records that concentrates information about my .W's, e.g. window name, parent directory, file name, procedure type (for internal treatments purposes), used to build my main menu. With this data I'm developing a new start procedure for the ERP that I maintain and using the opportunity in order to rewrite some really outdated functions and programs and implement new functionalities. Until now, I hadn't any problems but when I started to develop the .P procedure which will check the database register of a program that was called from the menu of this new start procedure - to check if it needs to receive fixed parameters to be run and its data types - I found a problem that I can't figure out a solution.
In this table, I have stored in one of the fields the parameters needed by the program, each with his correspondent data type. The problem is on how to pass different data types to procedures based only on the stored data. I tried to pre-convert data using a CASE clause and an include to check the parameter field for correct parameter sending but the include doesn't work as I've expected.
My database field is stored as this:
Description | DATATYPE | Content
I've declared some variables and converted properly the stored data into their correct datatype vars.
DEF VAR c-param-exec AS CHAR NO-UNDO EXTENT 9 INIT ?.
DEF VAR i-param-exec AS INT NO-UNDO EXTENT 9 INIT ?.
DEF VAR de-param-exec AS DEC NO-UNDO EXTENT 9 INIT ?.
DEF VAR da-param-exec AS DATE NO-UNDO EXTENT 9 INIT ?.
DEF VAR l-param-exec AS LOG NO-UNDO EXTENT 9 INIT ?.
DEF VAR i-count AS INT NO-UNDO.
blk-count:
DO i-count = 0 TO 8:
IF TRIM(programa.parametro[i-count]) = '' THEN
LEAVE blk-count.
i-count = i-count + 1.
CASE ENTRY(2,programa.parametro[i-count],CHR(1)):
WHEN 'CHARACTER' THEN
c-param-exec[i-count] = ENTRY(3,programa.parametro[i-count],CHR(1)).
WHEN 'INTEGER' THEN
i-param-exec[i-count] = INT(ENTRY(3,programa.parametro[i-count],CHR(1))).
WHEN 'DECIMAL' THEN
de-param-exec[i-count] = DEC(ENTRY(3,programa.parametro[i-count],CHR(1))).
WHEN 'DATE' THEN
da-param-exec[i-count] = DATE(ENTRY(3,programa.parametro[i-count],CHR(1))).
WHEN 'LOGICAL' THEN
l-param-exec[i-count] = (ENTRY(3,programa.parametro[i-count],CHR(1)) = 'yes').
OTHERWISE
c-param-exec[i-count] = ENTRY(3,programa.parametro[i-count],CHR(1)).
END CASE.
END.
Then I tried to run the program using an include to pass parameters (in this example, the program have 3 INPUT parameters).
RUN VALUE(c-prog-exec) ({util\abrePrograma.i 1},
{util\abrePrograma.i 2},
{util\abrePrograma.i 3}).
Here is my abrePrograma.i
/* abrePrograma.i */
(IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'CHARACTER' THEN c-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'INTEGER' THEN i-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'DECIMAL' THEN de-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'DATE' THEN da-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'LOGICAL' THEN l-param-exec[{1}] ELSE
c-param-exec[{1}])
If I suppress the 2nd, 3rd, 4th and 5th IF's from the include or use only one data type in all IF's (e.g. only CHAR, only DATE, etc.) the program works properly and executes like a charm but I need to call some old programs, which expects different datatypes in its INPUT parameters and using the programs as described OpenEdge doesn't compile the caller, triggering the error number 223.
---------------------------
Erro (Press HELP to view stack trace)
---------------------------
** Tipos de dados imcompativeis em expressao ou atribuicao. (223)
** Nao entendi a linha 86. (196)
---------------------------
OK Ajuda
---------------------------
Can anyone help me with this ?
Thanks in advance.
Looks as if you're trying to use variable parameter definitions.
Have a look at the "create call" statement in the ABL reference.
http://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvref/call-object-handle.html#wwconnect_header
Sample from the documentation
DEFINE VARIABLE hCall AS HANDLE NO-UNDO.
CREATE CALL hCall.
/* Invoke hello.p non-persistently */
hCall:CALL-NAME = "hello.p".
/* Sets CALL-TYPE to the default */
hCall:CALL-TYPE = PROCEDURE-CALL-TYPE
hCall:NUM-PARAMETERS = 1.
hCall:SET-PARAMETER(1, "CHARACTER", "INPUT", "HELLO WORLD").
hCall:INVOKE.
/* Clean up */
DELETE OBJECT hCall.
The best way to get to the bottom of those kind of preprocessor related issues is to do a compile with preprocess listing followed by a syntax check on the preprocessed file. Once you know where the error is in the resulting preprocessed file you have to find out which include / define caused the code that won't compile .
In procedure editor
compile source.w preprocess source.pp.
Open source.pp in the procedure editor and do syntax check
look at original source to find include or preprocessor construct that resulted in the code that does not compile.
Okay, I am getting a little bit lost (often happens to me with lots of preprocessors) but am I missing that on the way in and out of the database fields you are storing values as characters, right? So when storing a parameter in the database you have to convert it to Char and on the way out of the database you have convert it back to its correct data-type. To not do it one way or the other would cause a type mismatch.
Also, just thinking out loud (without thinking it all the way through) wonder if using OOABL (Object Oriented ABL) depending on if you Release has it available wouldn't make it easier by defining signatures for the different datatypes and then depending on which type of input or output parameter you call it with, it will use the correct signature and correct conversion method.
Something like:
METHOD PUBLIC VOID storeParam(input cParam as char ):
dbfield = cParam.
RETURN.
END METHOD.
METHOD PUBLIC VOID storeParam(input iParam as int ):
dbfield = string(iParam).
RETURN.
END METHOD.
METHOD PUBLIC VOID storeParam(input dParam as date ):
dbfield = string(dParam).
RETURN.
END METHOD.
just a thought.

Why is generic instantiation syntax disallowed in Hack?

From the docs:
Note: HHVM allows syntax such as $x = Vector<int>{5,10};, but Hack
disallows the syntax in this situation, instead opting to infer
it.
Is there a specific reason for this? Isn't this a violation of the fail-fast rule?
There are some situations in which this would cause error to be deffered, which in turn leads to harder backtracing.
For example:
<?hh // strict
function main() : void {
$myVector = new Vector([]); // no generic syntax
$myVector->addAll(require 'some_external_source.php');
}
The above code causes no errors until it is used in a context where the statically-typed collection is actually in place:
class Foo
{
public ?Vector<int> $v;
}
$f = new Foo();
$f->v = $myVector;
Now there is an error if the vector contains something else then int. But one must trace back the error to the point where the flawed data was actually imported. This would not be necessary if one could instantiate the vector using generic syntax in the first place:
$myVector = new Vector<int>([]);
$myVector->addAll(require 'some_external_source.php'); // fail immediately
I work on the Hack type system and typechecker at Facebook. This question has been asked a few times internally at FB, and it's good to have a nice, externally-visible place to have an answer to it written down.
So first of all, your question is premised on the following code:
<?hh // strict
function main() : void {
$myVector = new Vector([]); // no generic syntax
$myVector->addAll(require 'some_external_source.php');
}
However, that code does not pass the typechecker due to the usage of require outside toplevel, and so any result of actually executing it on HHVM is undefined behavior, rendering this whole discussion moot for that code.
But it's still a legitimate question for other potential pieces of code that do actually typecheck, so let me go ahead and actually answer it. :)
The reason that it's unsupported is because the typechecker is actually able to infer the generic correctly, unlike many other languages, and so we made the judgement call that the syntax would get in the way, and decided to disallow it. It turns out that if you just don't worry about, we'll infer it right, and still give useful type errors. You can certainly come up with contrived code that doesn't "fail fast" in the way you want, but it's, well, contrived. Take for example this fixup of your example:
<?hh // strict
function main(): void {
$myVector = Vector {}; // I intend this to be a Vector<int>
$myVector[] = 0;
$myVector[] = 'oops'; // Oops! Now it's inferred to be a Vector<mixed>
}
You might argue that this is bad, because you intended to have a Vector<int> but actually have a Vector<mixed> with no type error; you would have liked to be able to express this when creating it, so that adding 'oops' into it would cause such an error.. But there is no type error only because you never actually tried to use $myVector! If you tried to pull out any of its values, or return it from the function, you'd get some sort of type compatibility error. For example:
<?hh // strict
function main(): Vector<int> {
$myVector = Vector {}; // I intend this to be a Vector<int>
$myVector[] = 0;
$myVector[] = 'oops'; // Oops! Now it's inferred to be a Vector<mixed>
return $myVector; // Type error!
}
The return statement will cause a type error, saying that the 'oops' is a string, incompatible with the int return type annotation -- exactly what you wanted. So the inference is good, it works, and you don't ever actually need to explicitly annotate the type of locals.
But why shouldn't you be able to if you really want? Because annotating only generics when instantiating new objects isn't really the right feature here. The core of what you're getting at with "but occasionally I really want to annotate Vector<int> {}" is actually "but occasionally I really want to annotate locals". So the right language feature is not to let you write $x = Vector<int> {}; but let you explicitly declare variables and write Vector<int> $x = Vector {}; -- which also allows things like int $x = 42;. Adding explicit variable declarations to the language is a much more general, reasonable addition than just annotating generics at object instantiation. (It's however not a feature being actively worked on, nor can I see it being such in the near to medium term future, so don't get your hopes up now. But leaving the option open is why we made this decision.)
Furthermore, allowing either of these syntaxes would be actively misleading at this point in time. Generics are only enforced by the static typechecker and are erased by the runtime. This means that if you get untyped values from PHP or Hack partial mode code, the runtime cannot possibly check the real type of the generic. Noting that untyped values are "trust the programmer" and so you can do anything with them in the static typechecker too, consider the following code, which includes the hypothetical syntax you propose:
<?hh // partial
function get_foo() /* unannotated */ {
return 'not an int';
}
<?hh // strict
function f(): void {
$v = Vector<int> {};
$v[] = 1; // OK
// $v[] = 'whoops'; // Error since explicitly annotated as Vector<int>
// No error from static typechecker since get_foo is unannotated
// No error from runtime since generics are erased
$v[] = get_foo();
}
Of course, you can't have unannotated values in 100% strict mode code, but we have to think about how it interacts with all potential usages, including untyped code in partial mode or even PHP.

Scala problem with jMock expectations and returning a value from mock

Solved. IntelliJ didn't highlight the fact that my imports were incomplete.
Hi,
I have a simple Scala program that I'm trying to develop using jMock. Setting basic expectations works nicely but for some reason Scala does not understand my attempt to return a value from a mock object. My maven build spews out the following error
TestLocalCollector.scala:45: error: not found: value returnValue
one (nodeCtx).getParameter("FilenameRegex"); will( returnValue(regex))
^
And the respective code snippets are
#Before def setUp() : Unit = { nodeCtx = context.mock(classOf[NodeContext]) }
...
// the value to be returned
val regex = ".*\\.data"
...
// setting the expectations
one (nodeCtx).getParameter("FilenameRegex"); will( returnValue(regex))
To me it sounds that Scala is expecting that the static jMock method returnValue would be a val? What am I missing here?
Are you sure about the ';'?
one (nodeCtx).getParameter("FilenameRegex") will( returnValue(regex))
might work better.
In this example you see a line like:
expect {
one(blogger).todayPosts will returnValue(List(Post("...")))
}
with the following comment:
Specify what the return value should be in the same expression by defining "will" as Scala infix operator.
In the Java equivalent we would have to make a separate method call (which our favorite IDE may insist on putting on the next line!)
one(blogger).todayPosts; will(returnValue(List(Post("..."))))
^
|
-- semicolon only in the *Java* version
The OP explains it himself:
the returnValue static method was not visible, thus the errors.
And the will method just records an action on the latest mock operation, that's why it can be on the next line or after the semicolon :)
import org.jmock.Expectations
import org.jmock.Expectations._
...
context.checking(
new Expectations {
{ oneOf (nodeCtx).getParameter("FilenameRegex") will( returnValue(".*\\.data") ) }
}
)