GetSymbolInfo().Symbol returning null on AttributeSyntax - roslyn

I have a custom attribute I'm using to test a Roslyn code analyzer I'm writing:
[AttributeUsage( validOn: AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = true )]
public class DummyAttribute : Attribute
{
public DummyAttribute( string arg1, Type arg2 )
{
}
public int TestField;
}
which decorates another test class:
[Dummy( "", typeof( string ) )]
[Dummy( "test", typeof( int ) )]
[Dummy( "test", typeof( int ) )]
public class J4JLogger<TCalling> : IJ4JLogger<TCalling>
{
But when I call GetSymbolInfo() on it with the semantic model it's defined in:
model.GetSymbolInfo( attrNode ).Symbol
the value of Symbol is null.
What's odd is that the GetSymbolInfo() call works perfectly well for attribute classes defined in the Net Core library (e.g., AttributeUsage).
Both Dummy and J4JLogger are defined in the same project. I create my compilation unit by parsing the files individually (e.g., J4JLogger is parsed and analyzed separately from Dummy) so when I'm parsing J4JLogger there is no reference to the assembly containing both J4JLogger and Dummy.
Could the problem be that model doesn't actually contain the Dummy class I think it does? Is there a way to check what's in the semantic model? Do I have to include a reference to the assembly whose source file I'm analyzing in the semantic model?
Corrected Parsing Logic
My original parsing logic parsed each file into a syntax tree independent of all its sister source files. The correct way to parse source files -- at least when they depend on each other -- is something like this:
protected virtual (CompilationUnitSyntax root, SemanticModel model) ParseMultiple( string primaryPath, params string[] auxPaths )
{
if( !IsValid )
return (null, null);
CSharpCompilation compilation;
SyntaxTree primaryTree;
var auxFiles = auxPaths == null || auxPaths.Length == 0
? new List<string>()
: auxPaths.Distinct().Where( p => !p.Equals( primaryPath, StringComparison.OrdinalIgnoreCase ) );
try
{
var auxTrees = new List<SyntaxTree>();
primaryTree = CSharpSyntaxTree.ParseText( File.ReadAllText( primaryPath ) );
auxTrees.Add( primaryTree );
foreach( var auxFile in auxFiles )
{
var auxTree = CSharpSyntaxTree.ParseText( File.ReadAllText( auxFile ) );
auxTrees.Add( auxTree );
}
compilation = CSharpCompilation.Create( ProjectDocument.AssemblyName )
.AddReferences( GetReferences().ToArray() )
.AddSyntaxTrees( auxTrees );
}
catch( Exception e )
{
Logger.Error<string>( "Configuration failed, exception message was {0}", e.Message );
return (null, null);
}
return (primaryTree.GetCompilationUnitRoot(), compilation.GetSemanticModel( primaryTree ));
}
A minor gotcha is that AddSyntaxTrees() does not appear to be incremental; you need to add all the relevant syntax trees in one call to AddSyntaxTrees().

Turns out the problem was that you have to include all the source files that reference each other (e.g., Dummy and J4JLogger in my case) in the compilation unit because otherwise the "internal" references (e.g., decorating J4JLogger with Dummy) won't resolve. I've annotated the question with how I rewrote my parsing logic.

Related

How to get paths of newly added files in watchmode the webpack plugin?

I need to write a custom webpack plugin which will process newly added svg files in the src code in watchMode or recompile mode. But in my plugin compiler.modifiedFiles does not have the path of newly added files. It only contains the path till the folder where file is created. When I modify existing file it contains the filepath. In compiler, I found only modifiedFiles and removedFiles apis.
I am using webpack5.
Please let me know how can I get the path of newly added File in recompile scenario.
Here is sample code I am using
compiler.hooks.thisCompilation.tap( PLUGIN_NAME, ( compilation ) => {
compilation.hooks.finishModules.tapAsync( PLUGIN_NAME,
async( modules, callback ) => {
const modifiedSVGFiles = this.getModifiedSVGFiles( compilation.compiler );
this.getModifiedSVGFiles function
getModifiedSVGFiles( compiler ) {
const watchMode = compiler.watchMode;
let modifiedSVGFiles = {};
if( watchMode ) {
const modifiedFiles = compiler.modifiedFiles;
modifiedFiles && modifiedFiles.forEach( ( key, value ) => {
if( value.endsWith( '.svg' ) ) {
const key = `image/${basename( value )}`;
if( !modifiedSVGFiles[ key ] ) {
modifiedSVGFiles[ key ] = value;
}
}
} );
}
return modifiedSVGFiles;
}
Thanks
Prasad

parse and replace a list of object in kotlin

I am currently having a list of obeject defined as:
fun updateList(tools: List<Tool>, updateTools: List<Updated>){
... code below
}
the Tool data class is defined as:
data class Tool(
var id: String = ""
var description: String = ""
var assignedTo: String = ""
)
the Updated data class is defined as:
data class Updated(
var id: String = ""
var assignedTo: String = ""
)
Basically, I parse the list updateTools and if I found a id match in tools, I update the assignedTo field from the Tool type object from tools by the one from updateTools
fun updateList(tools: List<Tool>, updateTools: List<Updated>){
updateTools.forEach{
val idToSearch = it.id
val nameToReplace = it.name
tools.find(){
if(it.id == idToSearch){it.name=nameToReplace}
}
}
return tools
}
it's not working but I do not see how to make it easier to work. I just started kotlin and I feel that it's not the good way to do it
any idea ?
Thanks
First of all:
you're not assigning assignedTo, you're assigning name...
in the predicate passed to find, which
should only return a Boolean value to filter elements, and
should probably not have any side effects,
those should be done later with a call to i.e. forEach.
Additionally, your constructor parameters to the data class are normal parameters, and as such, need commas between them!
Your last code block, corrected, would be:
updateTools.forEach {
val idToSearch = it.id
val nameToReplace = it.name
tools.find { it.id == idToSearch }.forEach { it.assignedTo = nameToReplace }
}
return tools
I'd do it like this (shorter):
updateTools.forEach { u -> tools.filter { it.id == u.id }.forEach { it.assignedTo = u.name } }
This loops through each update, filters tools for tools with the right ID, and sets the name of each of these tools.
I use forEach as filter returns a List<Tool>.
If you can guarantee that id is unique, you can do it like this instead:
updateTools.forEach { u -> tools.find { it.id == u.id }?.assignedTo = u.name }
firstOrNull returns the first element matching the condition, or null if there is none. Edit: it seems find is firstOrNull - its implementation just calls firstOrNull.
The ?. safe call operator returns null if the left operand is null, otherwise, it calls the method.
For = and other operators which return Unit (i.e. void, nothing), using the safe call operator simply does nothing if the left operand is null.
If we combine these, it effectively sets the name of the first element which matches this condition.
First, you're missing comma after properties in your data classes, so it should be:
data class Tool(
var id: String = "",
var description: String = "",
var assignedTo: String = ""
)
data class Updated(
var id: String = "",
var assignedTo: String = ""
)
As for second problem, there're probably number of ways to do that, but I've only corrected your idea:
fun updateList(tools: List<Tool>, updateTools: List<Updated>): List<Tool> {
updateTools.forEach{ ut ->
tools.find { it.id == ut.id }?.assignedTo = ut.assignedTo
}
return tools
}
Instead of assigning values to variables, you can name parameter for forEach and use it in rest of the loop.

How set a copy field with Boolean value base on other field in SOLR?

I defined a copyField and called it:"IsIntranet" and i know my users in intranet using 192.168.* Ip
I wanna set value true if my regex matched in IsIntranet copy field and if not i set false to that
this is my regex (192\.168\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
how can i do such a thing?
If you need any more information i can Edit my Question.
Thank you.
It seems you are looking for a conditional copyField.
You can do this by creating a subclass of UpdateRequestProcessorFactory.
You can then override the processAdd method to add to your isIntranet field if it matches the regex.
public void processAdd(AddUpdateCommand cmd) throws IOException {
SolrInputDocument doc = cmd.getSolrInputDocument();
Object v = doc.getFieldValue( "ip" );
if( v != null ) {
String regexPattern = "(192\.168\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
if( Pattern.matches(regexPattern, v) ) {
doc.addField( "IsIntranet", true );
}
}
super.processAdd(cmd);
}
You can find the whole example here.

List object properties from a instance in Jena

How can I list all Object Properties associated to a instance in Jena?
For example:
A Person has an Object Property called "hasVehicle" which is associated with a class Vehicle
The appropriate Jena method is OntClass.listDeclaredProperties. There are some nuances to be aware of; the Jena RDF frames how-to explains in detail.
Update
OK, I've looked at your code sample, and read your description, and I'm afraid I don't understand what you want to do. What I've done is re-write your code sample so that it does something that I guess you might want, based on your description in the comment:
package test;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
public class LeandroTest
{
public static String NS = "http://www.owl-ontologies.com/TestProject.owl#";
public static void main( String[] args ) {
OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null );
FileManager.get().readModel( m, "./src/main/resources/project-test.owl" );
OntClass equipe = m.getOntClass( NS + "Equipe" );
OntProperty nome = m.getOntProperty( NS + "nome" );
for (ExtendedIterator<? extends OntResource> instances = equipe.listInstances(); instances.hasNext(); ) {
OntResource equipeInstance = instances.next();
System.out.println( "Equipe instance: " + equipeInstance.getProperty( nome ).getString() );
// find out the resources that link to the instance
for (StmtIterator stmts = m.listStatements( null, null, equipeInstance ); stmts.hasNext(); ) {
Individual ind = stmts.next().getSubject().as( Individual.class );
// show the properties of this individual
System.out.println( " " + ind.getURI() );
for (StmtIterator j = ind.listProperties(); j.hasNext(); ) {
Statement s = j.next();
System.out.print( " " + s.getPredicate().getLocalName() + " -> " );
if (s.getObject().isLiteral()) {
System.out.println( s.getLiteral().getLexicalForm() );
}
else {
System.out.println( s.getObject() );
}
}
}
}
}
}
This gives the following output, by first listing all resources of rdf:type #Equipe, then for each of those it lists the resources in the model that link to that Equipe, then for of those linked resources it lists all of the RDF the properties. I don't think that's a particularly useful thing to do, but hopefully it will show you some patterns for traversing RDF graphs in Jena.
Equipe instance: Erica
Equipe instance: Etiene
http://www.owl-ontologies.com/TestProject.owl#EtapaExecucao_01
EtapaExecucao_DataModificao -> 2010-03-29T10:54:05
caso_de_teste -> http://www.owl-ontologies.com/TestProject.owl#CasoDeTeste_01
EtapaExecucao_StatusTeste -> Passou
EtapaExecucao_Reprodutibilidade -> Sempre
type -> http://www.owl-ontologies.com/TestProject.owl#EtapaExecucao
EtapaExecucao_VersaoDefeitoSurgiu -> Release ICAMMH_01.00
EtapaExecucao_Severidade -> Minimo
EtapaExecucao_VersaoDefeitoCorrigiu -> Release ICAMMH_02.00
DataExecucao -> 2009-07-10T09:42:02
EtapaExecucao_StatusDoDefeito -> Nao sera corrigido
EtapaExecucao_DataSubmissao -> 2009-06-30T09:43:01
Tipos_Fases -> http://www.owl-ontologies.com/TestProject.owl#FaseTesteExecucao
EtapaExecucao_Resolucao -> Fechado
executor_do_teste -> http://www.owl-ontologies.com/TestProject.owl#Etiene
EtapaExecucao_PrioridadeCorrecao -> Normal
Equipe instance: Fabio
Equipe instance: Melis
Some general suggestions, particularly if you have any follow-up questions:
ask specific questions, it's very hard to answer a vague unclear question;
provide runnable code if possible: you can take my code below, drop it into a code environment like Eclipse and try it out
provide the code and data in the question, not linked off on pastebin
take some time to reduce the code and data to the minimum form necessary to show the problem: your Protégé file was over 600 lines long

Reflection on EmberJS objects? How to find a list of property keys without knowing the keys in advance

Is there a way to retrieve the set-at-creations properties of an EmberJS object if you don't know all your keys in advance?
Via the inspector I see all the object properties which appear to be stored in the meta-object's values hash, but I can't seem to find any methods to get it back. For example object.getProperties() needs a key list, but I'm trying to create a generic object container that doesn't know what it will contain in advance, but is able to return information about itself.
I haven't used this in production code, so your mileage may vary, but reviewing the Ember source suggests two functions that might be useful to you, or at least worth reviewing the implementation:
Ember.keys: "Returns all of the keys defined on an object or hash. This is useful when inspecting objects for debugging. On browsers that support it, this uses the native Object.keys implementation." Object.keys documentation on MDN
Ember.inspect: "Convenience method to inspect an object. This method will attempt to convert the object into a useful string description." Source on Github
I believe the simple answer is: you don't find a list of props. At least I haven't been able to.
However I noticed that ember props appear to be prefixed __ember, which made me solve it like this:
for (f in App.model) {
if (App.model.hasOwnProperty(f) && f.indexOf('__ember') < 0) {
console.log(f);
}
};
And it seems to work. But I don't know whether it's 100% certain to not get any bad props.
EDIT: Adam's gist is provided from comments. https://gist.github.com/1817543
var getOwnProperties = function(model){
var props = {};
for(var prop in model){
if( model.hasOwnProperty(prop)
&& prop.indexOf('__ember') < 0
&& prop.indexOf('_super') < 0
&& Ember.typeOf(model.get(prop)) !== 'function'
){
props[prop] = model[prop];
}
}
return props;
}
Neither of these answers are reliable, unfortunately, because any keys paired with a null or undefined value will not be visible.
e.g.
MyClass = Ember.Object.extend({
name: null,
age: null,
weight: null,
height: null
});
test = MyClass.create({name: 'wmarbut'});
console.log( Ember.keys(test) );
Is only going to give you
["_super", "name"]
The solution that I came up with is:
/**
* Method to get keys out of an object into an array
* #param object obj_proto The dumb javascript object to extract keys from
* #return array an array of keys
*/
function key_array(obj_proto) {
keys = [];
for (var key in obj_proto) {
keys.push(key);
}
return keys;
}
/*
* Put the structure of the object that you want into a dumb JavaScript object
* instead of directly into an Ember.Object
*/
MyClassPrototype = {
name: null,
age: null,
weight: null,
height: null
}
/*
* Extend the Ember.Object using your dumb javascript object
*/
MyClass = Ember.Object.extend(MyClassPrototype);
/*
* Set a hidden field for the keys the object possesses
*/
MyClass.reopen({__keys: key_array(MyClassPrototype)});
Using this method, you can now access the __keys field and know which keys to iterate over. This does not, however, solve the problem of objects where the structure isn't known before hand.
I use this:
Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)
None of those answers worked with me. I already had a solution for Ember Data, I was just after one for Ember.Object. I found the following to work just fine. (Remove Ember.getProperties if you only want the keys, not a hash with key/value.
getPojoProperties = function (pojo) {
return Ember.getProperties(pojo, Object.keys(pojo));
},
getProxiedProperties = function (proxyObject) {
// Three levels, first the content, then the prototype, then the properties of the instance itself
var contentProperties = getPojoProperties(proxyObject.get('content')),
prototypeProperties = Ember.getProperties(proxyObject, Object.keys(proxyObject.constructor.prototype)),
objectProperties = getPojoProperties(proxyObject);
return Ember.merge(Ember.merge(contentProperties, prototypeProperties), objectProperties);
},
getEmberObjectProperties = function (emberObject) {
var prototypeProperties = Ember.getProperties(emberObject, Object.keys(emberObject.constructor.prototype)),
objectProperties = getPojoProperties(emberObject);
return Ember.merge(prototypeProperties, objectProperties);
},
getEmberDataProperties = function (emberDataObject) {
var attributes = Ember.get(emberDataObject.constructor, 'attributes'),
keys = Ember.get(attributes, 'keys.list');
return Ember.getProperties(emberDataObject, keys);
},
getProperties = function (object) {
if (object instanceof DS.Model) {
return getEmberDataProperties(object);
} else if (object instanceof Ember.ObjectProxy) {
return getProxiedProperties(object);
} else if (object instanceof Ember.Object) {
return getEmberObjectProperties(object);
} else {
return getPojoProperties(object);
}
};
In my case Ember.keys(someObject) worked, without doing someObject.toJSON().
I'm trying to do something similar, i.e. render a generic table of rows of model data to show columns for each attribute of a given model type, but let the model describe its own fields.
If you're using Ember Data, then this may help:
http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute
You can iterate the attributes of the model type and get meta data associated with each attribute.
This worked for me (from an ArrayController):
fields: function() {
var doc = this.get('arrangedContent');
var fields = [];
var content = doc.content;
content.forEach(function(attr, value) {
var data = Ember.keys(attr._data);
data.forEach(function(v) {
if( typeof v === 'string' && $.inArray(v, fields) == -1) {
fields.push(v);
}
});
});
return fields;
}.property('arrangedContent')