Undeclared type: createM3FromEclipseProject (Rascal) - import

In the following module, I tried to add myModel for debugging purpose to see the AST.
module FlowGraphsAndClassDiagrams
import analysis::flow::ObjectFlow;
import lang::java::flow::JavaToObjectFlow;
// Added to check the M3 model
import lang::java::jdt::m3::AST;
import List;
import Relation;
import lang::java::m3::Core;
import IO;
import vis::Figure;
import vis::Render;
import analysis::m3::TypeSymbol;
alias OFG = rel[loc from, loc to];
//To view the M3 model from the whole eclipse project
alias myModel = createM3FromEclipseProject(loc project);
....
When I import the above module in the rascal console, I get the following error:
Reloading module FlowGraphsAndClassDiagrams
|console:///|:Could not load FlowGraphsAndClassDiagrams
|console:///|:could not reimport FlowGraphsAndClassDiagrams
|project://my_project/src/FlowGraphsAndClassDiagrams.rsc|(428,26,<18,16>,<18,42>): Undeclared type: createM3FromEclipseProject
Advice: |http://tutor.rascal-mpl.org/Errors/Static/UndeclaredType/UndeclaredType.html|
I don't understand what the mistake is.

I think the problem lies with
alias myModel = createM3FromEclipseProject(loc project);
What are you trying to achieve with this alias? I think you don't want to use an alias, instead you want to do this:
m = createM3FromEclipseProject(|project://eLib|);
println(m);

http://tutor.rascal-mpl.org/Rascal/Rascal.html#/Rascal/Declarations/Alias/Alias.html
You can use alias to create a new name for types, while createM3FromEclipseProject(loc project) seems to be a declaration of a function. If you want to call a function, which you seem to be doing, you need to provide a variable/value as parameter: createM3FromEclipseProject(|project://eLib|) if you want to "create an M3" from eclipse project "eLib".

Both answers are right, you can't use aliases for global variables. If you want to make an global variable (which in most cases we advice against), you have to give the type of that variable. We only allow type inference for local variables.
So in your specific case it should be:
M3 myModel = createM3FromEclipseProject(|project://eLib|);
In most cases you want to do this in your main method instead of at module import time.

Related

Same class name for two packages

I import google_maps_flutter and augmented_reality_plugin_wikitude
Both uses the same name class as CameraPosition.
I don't use CameraPostion class for google_maps_futter.
How can I avoid name comflict??
lib/main.dart:6:1: Error: 'CameraPosition' is imported from both 'package:google_maps_flutter/google_maps_flutter.dart' and 'package:augmented_reality_plugin_wikitude/startupConfiguration.dart'.
import 'package:augmented_reality_plugin_wikitude/startupConfiguration.dart'
You can use as keyword to reference all the respective variables and methods.
For Ex:
import 'package:google_maps_flutter/google_maps_flutter.dart' as cp1;
import 'package:augmented_reality_plugin_wikitude/startupConfiguration.dart' as cp2;
Now, to use CameraPosition or other methods from google_maps_flutter you can use "cp1" reference like cp1.method1().
Similarly, to use CameraPosition or other methods from augmented_reality_plugin you can use "cp2" reference like cp2.method1().
The as keyword's main purpose are typecast and to specify the library prefixes. So this is the best solution for your use case.
Hide CameraPosition from google_maps_flutter while importing
import 'package:google_maps_flutter/google_maps_flutter.dart' hide CameraPosition;
There are 2 ways you could fix this:
Specify an import prefix like import '../../something.dart' as st;
Then use it something like this: st.ImportedClass some = st.ImportedClass();
It also supports import '../../something.dart' show thisthing hide thatthing;
Absolute imports
import 'package:my_lib/shared/something.dart
You can avoid such conflicts by importing one of them in another name. So while importing one of two, let's say you can import google_maps as
import 'package:google_maps_flutter/google_maps_flutter.dart' as gmaps;
So CameraPosition from google maps plugin will be accessed using gmaps.CameraPosition, so there will no longer be any conflicts.

Wait for import before parsing next import's dependencies

I am converting some code to ES6 syntax using JSPM/SystemJS/BabelJS.
I have the following:
// main.js:
console.log('foo');
import * as Backbone from 'backbone';
import * as Cocktail from 'backbone.cocktail';
Cocktail.patch(Backbone);
console.log('bar');
import Application from 'background/application';
console.log('application:', Application);
// application.js:
console.log('baz');
export default {};
This code outputs baz foo bar application: {}.
I would like to output: foo bar baz application: {} such that Cocktail.patch is ran before any code in application.js
I am able to achieve this by re-writing my code as:
// main.js:
console.log('foo');
import * as Backbone from 'backbone';
import * as Cocktail from 'backbone.cocktail';
Cocktail.patch(Backbone);
console.log('bar');
System.import('background/application').then(function(Application){
console.log('application:', Application.default);
});
// application.js:
console.log('baz');
export default {};
However, this feels convoluted and incorrect. It's leveraging SystemJS explicitly rather than ES6 import/export syntax. How can I wait before parsing application.js using ES6 syntax?
import is not actually an expression, it is just mark for compiler, which modules should be imported before this code will run. This is similar to how var definition works. All variables is defined before all expressions in that scope, this is named variable hoisting.
So if you want to be sure, that your code will run before imports, you can move it into separate module
// setup.js
console.log('foo');
// backbone-patch.js
import * as Backbone from 'backbone';
import * as Cocktail from 'backbone.cocktail';
Cocktail.patch(Backbone);
console.log('bar');
// application.js:
console.log('baz');
export default {};
// main.js:
import './setup';
import './backbone-patch'
import Application from './application';
console.log('application:', Application);
Imports will be loaded in order of appearance and you will get the desired result
ES2015 (AKA ES6) imports are statically analyzed. They are not executed in the standard flow of a JavaScript code, but are rather analyzed and executed before any of the importing code is executed.
Using System.import makes the import "dynamic" and occur at runtime, thus allowing you to control the actual timing / order of events.

Usage of the `import` statement

Can someone explain me how the import statement works ?
For example I have a type User in the myapp/app/models package:
package models
type User struct {
// exportod fields
}
I have a type Users in the myapp/app/controllers package:
package controllers
import (
_ "myapp/app/models"
"github.com/revel/revel"
)
type Users struct {
*revel.Controller
}
func (c Users) HandleSubmit(user *User) revel.Result {
// Code here
}
This gives me the following error:
undefined: User
I tried to change the imports to the following code:
import (
. "advorts/app/models"
"github.com/revel/revel"
)
But get this error:
undefined: "myapp/app/controllers".User
Which I don't understand either. So, what is the difference between import . "something" and import "something" ? How to properly import my model in my case ?
Each package has a set of types, functions, variables, etc. Let's call them entities. Each entity can be either exported (its name start with an Uppercase letter), or unexported (its name start with a lowercase letter).
A package can only access the exported entites of another package. To do this, it needs to import it, which will make the exported entites available with the package name as identifier. Example:
import "github.com/revel/revel"
will get all exported entites of the revel package, which will be available using revel. prefix. As in revel.Controller, which is the Controller type defined in the revel package.
You can alias a package identifier by prefixing the import path with the wanted identifier. Example:
import rev "github.com/revel/revel"
will import all revel entites with the identifier rev. So revel.Controller becomes rev.Controller. It is useful if you have multiple package with the same name, or a package with an absurdly long name.
As a bonus, you can import a package anonymously, by aliasing it to the blank identifier:
import _ "github.com/revel/revel"
which will import the package, but not give you access to the exported entities. It is useful for things like drivers, which you need to import but never access. A frequent example is the database drivers, which register themselves to the database/sql package so you never need to access them directly.
And as a bonus' bonus, you can also import locally a package, by aliasing it with the . identifier. The exported entites will then be available without identifier, as if you defined them in the same package.
How to properly import your packages is up to you. The general convention is to never alias if you can manage it, to hide the package that you don't need to access but still need to import (database drivers), and that's all. You really never need to import locally a package, even if some tutorials or frameworks do it for simplicity's sake.

When exactly do you need to import in java?

The following unexpectedly compiled and ran without a problem:
import info.gridworld.actor.Actor;
import java.util.ArrayList;
public class ChameleonKid extends ChameleonCritter
{
public ArrayList<Actor> getActors()
{
ArrayList<Actor> actors = getGrid().getNeighbors(getLocation());
ArrayList<Actor> frontBack = new ArrayList<Actor>();
for(Actor i : actors)
if(getLocation().getDirectionToward(i.getLocation())==getDirection())
frontBack.add(i);
return frontBack;
}
}
The method getLocation() in the Actor class returns an instance of Location. And then I call the getDirectionToward() method of the Location class. getLocation().getDirectionToward(i.getLocation()). How does this work? I never imported the Location class. How am I able to work with it and call its methods? If that is how it works, when would I need to import a class? Only if I am instantiating it?
I am using Java 7.
Say you have two methods, one returning foo.Location and the other returning bar.Location (two completely different classes happening to have the same name, but in different packages - completely valid):
foo.Location getFooLocation();
bar.Location getBarLocation();
When you can both of these methods in the same class and chain some methods, you don't need an import:
if(getFooLocation().onlyInFoo()) {
//...
}
if(getBarLocation().onlyInBar()) {
//...
}
It works because the compiler is completely sure which version (from which package) of Location are you using and it knows where onlyInFoo() and onlyInBar are available.
But suppose you need a local variable:
Location location;
// much later
location = getFooLocation();
Now the compiler doesn't really know Location do you mean, so you must help him either by proceeding class name with package:
foo.Location location;
or by importing that class:
import foo.Location;
You should now ask: what if I want to have local variable of both foo.Location and bar.Location? Well, you can't import them both, obviously:
//WRONG
import foo.Location;
import bar.Location;
What you can do is again: either don't import at all and use fully qualified names:
foo.Location location1;
bar.Location location;
...or import just one location:
import foo.Location;
//...
Location location1; //foo.Location
bar.Location location2;
The reason why you don't need to import that class is because of the fact that you are not explicitly using that class. Actor is the one actually using the Location class locally. You are never holding a reference to the Location class and so, you are able to keep using it dynamically. However, if you wanted to hold a reference (eg Location l = getLocation();), you would have to import Location since the compiler has to link l with Location, but has no idea where to find it.

Why does my Scala enumeration break when I move it to another package?

Enumeration code looks like the following
package com.mydomain
object Market extends Enumeration {
type Market = Value
val ASX, LSE = Value
}
I try to use as follows
import com.mydomain.Market._
.
.
.
if (Market.ASX == currentMarket) {
...
}
This was working when everything was in the same package. When I moved to a new package I now get
not found: value Market
If you import Market, you have ASX and LSE directly available to you. You don't have Market.ASX available--that would be if you had object Market available, which is what would happen if you did import com.mydomain._.
Being inside package com.mydomain causes com.mydomain._ to be loaded just like you imported it, so that's why you can say Market.ASX when you're in the same package.
When you write code in a different package, you need to either import com.mydomain._ and then use Market.ASX, or import com.mydomain.Market._ and then use ASX.