package jetbrains.mps.ide.java.newparser;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.module.ModelAccess;
import java.util.Map;
import java.util.Set;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import java.util.List;
import jetbrains.mps.vfs.IFile;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.messages.IMessageHandler;
import java.util.Collections;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import org.jetbrains.mps.openapi.model.EditableSModel;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import java.io.IOException;
import jetbrains.mps.messages.Message;
import jetbrains.mps.messages.MessageKind;
import jetbrains.mps.project.AbstractModule;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.extapi.model.SModelBase;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.internal.collections.runtime.IMapping;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import org.jetbrains.mps.openapi.model.SReference;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.internal.collections.runtime.ISequence;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.smodel.DynamicReference;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.vfs.IFileUtils;
import org.jetbrains.mps.openapi.model.SNodeReference;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.typesystem.inference.TypeChecker;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.AttributeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.IAttributeDescriptor;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId;
import jetbrains.mps.smodel.StaticReference;
import jetbrains.mps.scope.Scope;
import java.util.Deque;
import jetbrains.mps.internal.collections.runtime.DequeSequence;
import java.util.LinkedList;
import org.jetbrains.mps.openapi.model.SModelReference;
import jetbrains.mps.smodel.SModelInternal;
import jetbrains.mps.baseLanguage.tuples.runtime.Tuples;
import jetbrains.mps.persistence.DefaultModelRoot;
import jetbrains.mps.extapi.persistence.SourceRoot;
import jetbrains.mps.extapi.persistence.datasource.DataSourceFactoryFromName;
import org.jetbrains.mps.openapi.persistence.ModelFactory;
import jetbrains.mps.extapi.persistence.ModelFactoryService;
import org.jetbrains.mps.openapi.model.SModelName;
import jetbrains.mps.persistence.ModelCannotBeCreatedException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.persistence.DataSource;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.persistence.ModelRoot;
import jetbrains.mps.persistence.FilePerRootDataSource;
import org.jetbrains.mps.openapi.persistence.datasource.DataSourceType;
import jetbrains.mps.extapi.persistence.datasource.PreinstalledDataSourceTypes;
import jetbrains.mps.extapi.persistence.SourceRootKinds;
import jetbrains.mps.util.FileUtil;
import jetbrains.mps.baseLanguage.tuples.runtime.MultiTuple;
public class JavaToMpsConverter {
private static final Logger LOG = LogManager.getLogger(JavaToMpsConverter.class);
private SModule myModule;
private SModel myModel;
private boolean myCreatePerRoot;
private boolean myCreateInplace;
private SRepository myRepository;
private ModelAccess myModelAccess;
private JavaParser myJavaParser = new JavaParser();
private Map<String, Set<SNode>> classesPerPackage = MapSequence.fromMap(new HashMap<String, Set<SNode>>());
private Map<String, List<IFile>> filesPerPackage = MapSequence.fromMap(new HashMap<String, List<IFile>>());
private Map<String, IFile> packageDirs = MapSequence.fromMap(new HashMap<String, IFile>());
private List<SModel> myModels;
private List<SNode> myRoots = ListSequence.fromList(new ArrayList<SNode>());
private List<SNode> myAttachedRoots = ListSequence.fromList(new ArrayList<SNode>());
private Map<SNode, SModel> myRootsToModels = MapSequence.fromMap(new HashMap<SNode, SModel>());
private List<IFile> mySuccessfulFiles = ListSequence.fromList(new ArrayList<IFile>());
private boolean wasDefaultPkg = false;
private int myRootCount = 0;
private IMessageHandler myMessageHandler;
public JavaToMpsConverter(SModule module, SRepository repository, IMessageHandler messageHandler) {
this(module, repository, false, false, messageHandler);
}
public Set<SNode> getRootsBuilt() {
return Collections.<SNode>unmodifiableSet(SetSequence.fromSetWithValues(new HashSet<SNode>(), myAttachedRoots));
}
public JavaToMpsConverter(SModule module, SRepository repository, boolean perRoot, boolean inPlace, IMessageHandler messageHandler) {
// currently perRoot==false and inPlace==true doesn't make it in-place
// because of how DefaultModelRoot is implemented
myModule = module;
myCreatePerRoot = perRoot;
myCreateInplace = inPlace;
myRepository = repository;
myModelAccess = repository.getModelAccess();
myMessageHandler = messageHandler;
}
public JavaToMpsConverter(SModel model, SRepository repository, IMessageHandler messageHandler) {
myModel = model;
myModule = model.getModule();
myRepository = repository;
myModelAccess = repository.getModelAccess();
myMessageHandler = messageHandler;
}
public void saveAll() {
ListSequence.fromList(myModels).visitAll(new IVisitor<SModel>() {
public void visit(SModel it) {
((EditableSModel) it).setChanged(true);
((EditableSModel) it).save();
}
});
}
public void convertToMps(List<IFile> files, ProgressMonitor progress) throws JavaParseException, IOException {
progress.start("Converting...", 31);
// first we build AST
ProgressMonitor parseProgress = progress.subTask(1);
parseProgress.start("Parsing...", ListSequence.fromList(files).count());
for (IFile file : ListSequence.fromList(files)) {
try {
parseFile(file);
parseProgress.advance(1);
} catch (JavaParseException e) {
Message msg = new Message(MessageKind.ERROR, String.format("Parse error: %s", e.getMessage()));
if (e.getCause() != null) {
msg.setException(e.getCause());
}
myMessageHandler.handle(msg);
} catch (IOException e) {
myMessageHandler.handle(new Message(MessageKind.ERROR, String.format("IO error when converting (java->mps) file %s", file.getName())).setException(e));
}
}
parseProgress.done();
int rootCount = 0;
// now we attach the models and try to resolve
myModelAccess.runWriteAction(new Runnable() {
public void run() {
((AbstractModule) myModule).addDependency(PersistenceFacade.getInstance().createModuleReference("6354ebe7-c22a-4a0f-ac54-50b52ab9b065(JDK)"), false);
if (myModel == null) {
myModels = ListSequence.fromList(new ArrayList<SModel>());
for (String pakage : MapSequence.fromMap(classesPerPackage).keySet()) {
final SModel model = getModel(pakage, MapSequence.fromMap(packageDirs).get(pakage));
if (model == null) {
continue;
}
Set<SNode> roots = MapSequence.fromMap(classesPerPackage).get(pakage);
SetSequence.fromSet(roots).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
MapSequence.fromMap(myRootsToModels).put(it, model);
}
});
ListSequence.fromList(mySuccessfulFiles).addSequence(ListSequence.fromList(MapSequence.fromMap(filesPerPackage).get(pakage)));
ListSequence.fromList(myAttachedRoots).addSequence(SetSequence.fromSet(roots));
ListSequence.fromList(myModels).addElement(model);
}
} else {
// todo maybe do something clever with packages <-> java imports
// with regard to model where we put it all
for (SNode root : ListSequence.fromList(myRoots)) {
// todo be more accurate with duplicates
MapSequence.fromMap(myRootsToModels).put(root, myModel);
}
myModels = Sequence.fromIterable(Sequence.<SModel>singleton(myModel)).toListSequence();
myAttachedRoots = myRoots;
}
}
});
IncrementalModelAccess modelAccess;
if (myModelAccess.isCommandAction()) {
modelAccess = IncrementalModelAccess.INSIDE_COMMAND_OR_UPDATE_MODE;
} else if (myModel != null) {
// import into single already existing model; use proper command for replacing nodes
modelAccess = new IncrementalModelAccessWithCommand(myModelAccess, myModels, myMessageHandler);
} else {
modelAccess = new IncrementalModelAccessWithoutCommand(myModelAccess, myModels, myMessageHandler);
}
// actually attach roots
modelAccess.replaceNodes(new Runnable() {
public void run() {
ListSequence.fromList(myModels).visitAll(new IVisitor<SModel>() {
public void visit(SModel it) {
((SModelBase) it).addLanguage(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"));
((SModelBase) it).addLanguage(MetaAdapterFactory.getLanguage(0xf280165065d5424eL, 0xbb1b463a8781b786L, "jetbrains.mps.baseLanguage.javadoc"));
}
});
MapSequence.fromMap(myRootsToModels).visitAll(new IVisitor<IMapping<SNode, SModel>>() {
public void visit(IMapping<SNode, SModel> it) {
SModel m = it.value();
SNode root = it.key();
SModelOperations.addRootNode(m, root);
}
});
}
});
myRootCount = myAttachedRoots.size();
ProgressMonitor resolveProgress = progress.subTask(30);
tryResolveRefs(myAttachedRoots, FeatureKind.CLASS, resolveProgress, modelAccess);
progress.done();
}
public void tryResolveRefs(Iterable<SNode> nodes, FeatureKind level, ProgressMonitor progress) {
tryResolveRefs(nodes, level, progress, IncrementalModelAccess.INSIDE_COMMAND_OR_UPDATE_MODE);
}
private void tryResolveRefs(Iterable<SNode> nodes, FeatureKind level, ProgressMonitor progress, IncrementalModelAccess modelAccess) {
// 11 - number of progress.subTask() below
progress.start("Resolving...", 11);
if (FeatureKind.CLASS.equals(level)) {
resolveUpdatePass("top level references", nodes, new _FunctionTypes._return_P1_E0<Iterable<SReference>, SNode>() {
public Iterable<SReference> invoke(SNode node) {
return getTopLevelRefs(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")));
}
}, progress.subTask(1), modelAccess);
}
if (FeatureKind.CLASS.equals(level) || FeatureKind.CLASS_CONTENT.equals(level)) {
resolveUpdatePass("field/method type references", nodes, new _FunctionTypes._return_P1_E0<Iterable<SReference>, SNode>() {
public Iterable<SReference> invoke(SNode node) {
return getFieldAndMethodTypeRefs(SNodeOperations.cast(node, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x112574373bdL, "jetbrains.mps.baseLanguage.structure.ClassifierMember")));
}
}, progress.subTask(1), modelAccess);
}
// this happens on the level of expressions, but relies on top-level references (from class and method
// declarations) having been resolved
JavaParser.tryResolveUnknowns(myAttachedRoots, progress.subTask(1), modelAccess);
resolveUpdatePass("type references", nodes, new _FunctionTypes._return_P1_E0<Iterable<SReference>, SNode>() {
public Iterable<SReference> invoke(SNode node) {
return getVarTypeRefs(node);
}
}, progress.subTask(1), modelAccess);
resolveUpdatePass("variable references", nodes, new _FunctionTypes._return_P1_E0<Iterable<SReference>, SNode>() {
public Iterable<SReference> invoke(SNode node) {
return getVariableRefs(node);
}
}, progress.subTask(1), modelAccess);
resolveUpdatePass("dot operands", nodes, new _FunctionTypes._return_P1_E0<ISequence<SReference>, SNode>() {
public ISequence<SReference> invoke(SNode node) {
return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression"), false, new SAbstractConcept[]{})).translate(new ITranslator2<SNode, SReference>() {
public Iterable<SReference> translate(SNode it) {
return deepReferences(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand")));
}
});
}
}, progress.subTask(1), modelAccess);
resolveUpdatePass("dot operations", nodes, new _FunctionTypes._return_P1_E0<ISequence<SReference>, SNode>() {
public ISequence<SReference> invoke(SNode node) {
return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression"), false, new SAbstractConcept[]{})).translate(new ITranslator2<SNode, SReference>() {
public Iterable<SReference> translate(SNode it) {
if (Sequence.fromIterable(deepReferences(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand")))).any(new IWhereFilter<SReference>() {
public boolean accept(SReference it) {
return (SReference) it instanceof DynamicReference;
}
})) {
return ListSequence.fromList(new ArrayList<SReference>());
} else {
if (SNodeOperations.isInstanceOf(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46b36c4L, "operation")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b483d77aL, "jetbrains.mps.baseLanguage.structure.FieldReferenceOperation"))) {
return Sequence.<SReference>singleton(SNodeOperations.getReference(SNodeOperations.cast(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46b36c4L, "operation")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b483d77aL, "jetbrains.mps.baseLanguage.structure.FieldReferenceOperation")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b483d77aL, 0x116b484a653L, "fieldDeclaration")));
} else if (SNodeOperations.isInstanceOf(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46b36c4L, "operation")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x118154a6332L, "jetbrains.mps.baseLanguage.structure.InstanceMethodCallOperation"))) {
return Sequence.<SReference>singleton(SNodeOperations.getReference(SNodeOperations.cast(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46b36c4L, "operation")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x118154a6332L, "jetbrains.mps.baseLanguage.structure.InstanceMethodCallOperation")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration")));
} else {
return ListSequence.fromList(new ArrayList<SReference>());
}
}
}
});
}
}, progress.subTask(1), modelAccess);
resolveUpdatePass("classifiers in static access", nodes, new _FunctionTypes._return_P1_E0<List<SReference>, SNode>() {
public List<SReference> invoke(SNode node) {
List<SReference> result = ListSequence.fromList(new ArrayList<SReference>());
ListSequence.fromList(result).addSequence(ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, "jetbrains.mps.baseLanguage.structure.StaticMethodCall"), false, new SAbstractConcept[]{})).select(new ISelector<SNode, SReference>() {
public SReference select(SNode it) {
return SNodeOperations.getReference(it, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, 0x10a7588b546L, "classConcept"));
}
}));
ListSequence.fromList(result).addSequence(ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, "jetbrains.mps.baseLanguage.structure.StaticFieldReference"), false, new SAbstractConcept[]{})).select(new ISelector<SNode, SReference>() {
public SReference select(SNode it) {
return SNodeOperations.getReference(it, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, 0x10a75869f9bL, "classifier"));
}
}));
return result;
}
}, progress.subTask(1), modelAccess);
resolveUpdatePass("static member references", nodes, new _FunctionTypes._return_P1_E0<List<SReference>, SNode>() {
public List<SReference> invoke(SNode node) {
List<SReference> result = ListSequence.fromList(new ArrayList<SReference>());
ListSequence.fromList(result).addSequence(ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, "jetbrains.mps.baseLanguage.structure.StaticMethodCall"), false, new SAbstractConcept[]{})).select(new ISelector<SNode, SReference>() {
public SReference select(SNode it) {
return SNodeOperations.getReference(it, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"));
}
}));
ListSequence.fromList(result).addSequence(ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, "jetbrains.mps.baseLanguage.structure.StaticFieldReference"), false, new SAbstractConcept[]{})).select(new ISelector<SNode, SReference>() {
public SReference select(SNode it) {
return SNodeOperations.getReference(it, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"));
}
}));
return result;
}
}, progress.subTask(1), modelAccess);
resolveUpdatePass("remaining references", nodes, new _FunctionTypes._return_P1_E0<Iterable<SReference>, SNode>() {
public Iterable<SReference> invoke(SNode node) {
return deepReferences(node);
}
}, progress.subTask(1), modelAccess);
codeTransformPass(nodes, progress.subTask(1), modelAccess);
removeJavaImportsPass(nodes, progress.subTask(1), modelAccess);
progress.done();
}
public List<IFile> getSuccessfulFiles() {
return mySuccessfulFiles;
}
public List<SModel> getModels() {
return myModels;
}
private void parseFile(IFile file) throws JavaParseException, IOException {
String contents = IFileUtils.getTextContents(file);
JavaParser.JavaParseResult parseResult = myJavaParser.parseCompilationUnit(contents);
String pkg = parseResult.getPackage();
if (pkg == null) {
// default package (i.e. none), bad
if (!(wasDefaultPkg)) {
myMessageHandler.handle(new Message(MessageKind.ERROR, String.format("default package is not supported in java source directory input (first such file in dir: %s)", file.getName())));
wasDefaultPkg = true;
}
return;
}
IFile dir = file.getParent();
if (!(DirParser.checkPackageMatchesSourceDirectory(pkg, dir))) {
myMessageHandler.handle(new Message(MessageKind.ERROR, String.format("package %s doesn't match directory %s (in file %s)", pkg, dir.getPath(), file.getName())));
return;
}
IFile currentDir = MapSequence.fromMap(packageDirs).get(pkg);
// if it's already set, leave it as is
// it means one package is present in more than one dir, but we will have only one model
// and it has to be somewhere
if (currentDir == null) {
MapSequence.fromMap(packageDirs).put(pkg, dir);
}
Iterable<SNode> roots = parseResult.getNodes();
Set<SNode> classesInPackage = MapSequence.fromMap(classesPerPackage).get(pkg);
if (classesInPackage == null) {
classesInPackage = SetSequence.fromSet(new HashSet<SNode>(Sequence.fromIterable(roots).count()));
MapSequence.fromMap(classesPerPackage).put(pkg, classesInPackage);
}
SetSequence.fromSet(classesInPackage).addSequence(Sequence.fromIterable(roots));
List<IFile> files = MapSequence.fromMap(filesPerPackage).get(pkg);
if (files == null) {
files = ListSequence.fromList(new ArrayList<IFile>());
MapSequence.fromMap(filesPerPackage).put(pkg, files);
}
ListSequence.fromList(files).addElement(file);
ListSequence.fromList(myRoots).addSequence(Sequence.fromIterable(roots));
myRootCount += Sequence.fromIterable(roots).count();
}
private Set<SReference> myVisitedRefs = SetSequence.fromSet(new HashSet<SReference>());
private void resolveUpdatePass(String name, final Iterable<SNode> nodes, final _FunctionTypes._return_P1_E0<? extends Iterable<SReference>, ? super SNode> extractor, final ProgressMonitor progress, IncrementalModelAccess modelAccess) {
final Map<SNodeReference, List<SReference>> resolveMap = MapSequence.fromMap(new HashMap<SNodeReference, List<SReference>>());
progress.start(name, Sequence.fromIterable(nodes).count() + 1);
modelAccess.accessModel(new Runnable() {
public void run() {
for (SNode node : Sequence.fromIterable(nodes)) {
if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept"))) {
progress.step("class: " + SPropertyOperations.getString(SNodeOperations.cast(node, MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept")), MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")));
}
Iterable<SReference> refs = extractor.invoke(node);
resolveRefs(refs, resolveMap);
SetSequence.fromSet(myVisitedRefs).addSequence(Sequence.fromIterable(refs));
progress.advance(1);
}
}
});
progress.step("updating references...");
modelAccess.replaceReferences(new Runnable() {
public void run() {
updateReference(resolveMap);
}
});
progress.advance(1);
progress.done();
}
private void codeTransformPass(final Iterable<SNode> nodes, final ProgressMonitor progress, IncrementalModelAccess modelAccess) {
progress.start("Code transforms", Sequence.fromIterable(nodes).count() * 5 + 1);
final Wrappers._T<TypeChecker> typeChecker = new Wrappers._T<TypeChecker>(TypeChecker.getInstance());
// all this can be replaced by one map old -> new
final List<SNode> toReplaceWithArrayLength = ListSequence.fromList(new ArrayList<SNode>());
final List<SNode> toReplaceWithArrayClone = ListSequence.fromList(new ArrayList<SNode>());
final Map<SNode, SNode> enumConstRefs = MapSequence.fromMap(new HashMap<SNode, SNode>());
final Map<SNode, SNode> staticMethodQualifiers = MapSequence.fromMap(new HashMap<SNode, SNode>());
final Map<SNode, SNode> staticFieldQualifiers = MapSequence.fromMap(new HashMap<SNode, SNode>());
modelAccess.accessModel(new Runnable() {
public void run() {
for (SNode node : Sequence.fromIterable(nodes)) {
for (SNode fieldRefOp : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b483d77aL, "jetbrains.mps.baseLanguage.structure.FieldReferenceOperation"), false, new SAbstractConcept[]{}))) {
SReference fieldRef = SNodeOperations.getReference(fieldRefOp, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b483d77aL, 0x116b484a653L, "fieldDeclaration"));
if (!((fieldRef instanceof DynamicReference && "length".equals((((DynamicReference) fieldRef).getResolveInfo()))))) {
continue;
}
SNode operand = SLinkOperations.getTarget(SNodeOperations.cast(SNodeOperations.getParent(fieldRefOp), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand"));
Iterable<SReference> operandRefs = SNodeOperations.getReferences(operand);
if (Sequence.fromIterable(operandRefs).any(new IWhereFilter<SReference>() {
public boolean accept(SReference it) {
return it instanceof DynamicReference;
}
})) {
continue;
}
SNode operandType = typeChecker.value.getTypeOf(operand);
if (SNodeOperations.isInstanceOf(operandType, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940d819f7L, "jetbrains.mps.baseLanguage.structure.ArrayType"))) {
ListSequence.fromList(toReplaceWithArrayLength).addElement(fieldRefOp);
}
}
progress.advance(1);
for (SNode imco : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x118154a6332L, "jetbrains.mps.baseLanguage.structure.InstanceMethodCallOperation"), false, new SAbstractConcept[]{}))) {
SReference fieldRef = SNodeOperations.getReference(imco, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"));
if (!((fieldRef instanceof DynamicReference && "clone".equals((((DynamicReference) fieldRef).getResolveInfo()))))) {
continue;
}
SNode operand = SLinkOperations.getTarget(SNodeOperations.cast(SNodeOperations.getParent(imco), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand"));
Iterable<SReference> operandRefs = SNodeOperations.getReferences(operand);
if (Sequence.fromIterable(operandRefs).any(new IWhereFilter<SReference>() {
public boolean accept(SReference it) {
return it instanceof DynamicReference;
}
})) {
continue;
}
SNode operandType = typeChecker.value.getTypeOf(operand);
if (SNodeOperations.isInstanceOf(operandType, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940d819f7L, "jetbrains.mps.baseLanguage.structure.ArrayType"))) {
ListSequence.fromList(toReplaceWithArrayClone).addElement(imco);
}
}
progress.advance(1);
for (SNode localCall : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x6c6b6a1e379f9404L, "jetbrains.mps.baseLanguage.structure.LocalMethodCall"), false, new SAbstractConcept[]{}))) {
SNode smc = transformLocalCall(localCall);
if ((smc == null)) {
continue;
}
MapSequence.fromMap(staticMethodQualifiers).put(localCall, smc);
}
progress.advance(1);
typeChecker.value = TypeChecker.getInstance();
for (SNode swicthCase : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x10ef02cdd1bL, "jetbrains.mps.baseLanguage.structure.SwitchCase"), false, new SAbstractConcept[]{}))) {
SNode subst = transformUnqualifedEnumUnderSwitch(swicthCase, typeChecker.value);
if ((subst == null)) {
continue;
}
MapSequence.fromMap(enumConstRefs).put(SNodeOperations.cast(SLinkOperations.getTarget(swicthCase, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x10ef02cdd1bL, 0x10ef02d67cfL, "expression")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference")), subst);
}
progress.advance(1);
for (SNode varRef : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference"), false, new SAbstractConcept[]{}))) {
SNode exp = transformLocalNameRef(varRef);
if ((exp != null)) {
MapSequence.fromMap(staticFieldQualifiers).put(varRef, exp);
continue;
}
SNode subst = transformUnqualifedEnum(varRef);
if ((subst == null)) {
continue;
}
MapSequence.fromMap(enumConstRefs).put(varRef, subst);
}
progress.advance(1);
}
}
});
progress.step("updating models...");
modelAccess.replaceNodes(new Runnable() {
public void run() {
for (SNode fieldRefOp : ListSequence.fromList(toReplaceWithArrayLength)) {
SNodeOperations.replaceWithNewChild(fieldRefOp, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1197781411dL, "jetbrains.mps.baseLanguage.structure.ArrayLengthOperation"));
}
for (SNode imco : ListSequence.fromList(toReplaceWithArrayClone)) {
SNodeOperations.replaceWithNewChild(imco, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x483ee9d7f09580d6L, "jetbrains.mps.baseLanguage.structure.ArrayCloneOperation"));
}
for (IMapping<SNode, SNode> pair : MapSequence.fromMap(enumConstRefs)) {
SNodeOperations.replaceWithAnother(pair.key(), pair.value());
}
for (IMapping<SNode, SNode> pair : MapSequence.fromMap(staticMethodQualifiers)) {
SNodeOperations.replaceWithAnother(pair.key(), pair.value());
}
for (IMapping<SNode, SNode> pair : MapSequence.fromMap(staticFieldQualifiers)) {
SNodeOperations.replaceWithAnother(pair.key(), pair.value());
}
}
});
progress.advance(1);
progress.done();
}
private void removeJavaImportsPass(final Iterable<SNode> nodes, final ProgressMonitor progress, IncrementalModelAccess modelAccess) {
progress.start("Removing java imports", Sequence.fromIterable(nodes).count() + 1);
final Map<SNode, Iterable<SNode>> toRemove = MapSequence.fromMap(new HashMap<SNode, Iterable<SNode>>());
modelAccess.accessModel(new Runnable() {
public void run() {
for (SNode node : Sequence.fromIterable(nodes)) {
progress.advance(1);
if (!(SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")))) {
continue;
}
if ((AttributeOperations.getAttribute(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")), new IAttributeDescriptor.NodeAttribute(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports"))) == null)) {
continue;
}
MapSequence.fromMap(toRemove).put(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")), getImportsToRemove(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"))));
}
}
});
modelAccess.replaceNodes(new Runnable() {
public void run() {
for (SNode node : SetSequence.fromSet(MapSequence.fromMap(toRemove).keySet())) {
Iterable<SNode> imps = MapSequence.fromMap(toRemove).get(node);
Sequence.fromIterable(imps).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
SNodeOperations.deleteNode(it);
}
});
SNode importAnnotation = AttributeOperations.getAttribute(node, new IAttributeDescriptor.NodeAttribute(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports")));
if (ListSequence.fromList(SLinkOperations.getChildren(importAnnotation, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, 0x64c0181e6020a7L, "entries"))).isEmpty()) {
SNodeOperations.deleteNode(importAnnotation);
}
}
}
});
progress.advance(1);
progress.done();
}
private SNode transformUnqualifedEnum(SNode varRef) {
// FIXME share or re-use code with the corresponding NonTypesystemRule
if (!(SConceptOperations.isExactly(SNodeOperations.asSConcept(SNodeOperations.getConcept(varRef)), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference")))) {
return null;
}
SReference ref = SNodeOperations.getReference(varRef, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"));
if (!(ref instanceof DynamicReference)) {
return null;
}
if (ref.getTargetNode() != null) {
return null;
}
// now we can try to search
SNode gateway = SConceptOperations.createNewNode(SNodeOperations.asInstanceConcept(MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x70ea1dc4c5721865L, "jetbrains.mps.baseLanguage.structure.IYetUnresolved")));
String enumConstName = ((DynamicReference) ref).getResolveInfo();
for (SNode enclosingEnum : ListSequence.fromList(SNodeOperations.getNodeAncestors(varRef, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass"), false))) {
SNode enumConstRef = makeEnumConstRef(enclosingEnum, enumConstName);
if (enumConstRef != null) {
return enumConstRef;
}
}
SNode root = SNodeOperations.getContainingRoot(varRef);
if (!(SNodeOperations.isInstanceOf(root, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")))) {
return null;
}
SNode javaImports = AttributeOperations.getAttribute(SNodeOperations.cast(root, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")), new IAttributeDescriptor.NodeAttribute(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports")));
if ((javaImports == null)) {
return null;
}
for (SNode singleNameImport : Sequence.fromIterable(((Iterable<SNode>) BHReflection.invoke(javaImports, SMethodTrimmedId.create("staticSingleName", MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports"), "4ykJ8Y6iJRa"))))) {
if (!(enumConstName.equals(((String) BHReflection.invoke(singleNameImport, SMethodTrimmedId.create("lastToken", MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x5a98df4004080866L, "jetbrains.mps.baseLanguage.structure.Tokens"), "17WpDCYLyrY")))))) {
continue;
}
String enumClassCandidateName = ((String) BHReflection.invoke(singleNameImport, SMethodTrimmedId.create("withoutLastToken", MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x5a98df4004080866L, "jetbrains.mps.baseLanguage.structure.Tokens"), "5ll4uk6512$")));
SNode enumClassCandidate = ((SNode) BHReflection.invoke(gateway, SMethodTrimmedId.create("findClass", MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x70ea1dc4c5721865L, "jetbrains.mps.baseLanguage.structure.IYetUnresolved"), "4ykJ8Y83bdr"), varRef, enumClassCandidateName));
if ((enumClassCandidate == null)) {
// seems like there is no need to continue
// we had import of the form: import static <class>.<ourName>
// if we meet <ourName> in java code then it must strictly reference this import, not any other
return null;
}
if (!(SNodeOperations.isInstanceOf(enumClassCandidate, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")))) {
return null;
}
SNode result = makeEnumConstRef(SNodeOperations.cast(enumClassCandidate, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")), enumConstName);
if (result != null) {
return null;
}
}
for (SNode onDemandImport : Sequence.fromIterable(((Iterable<SNode>) BHReflection.invoke(javaImports, SMethodTrimmedId.create("staticOnDemand", MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports"), "4ykJ8Y6iCVz"))))) {
SNode claz = ((SNode) BHReflection.invoke(gateway, SMethodTrimmedId.create("findClass", MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x70ea1dc4c5721865L, "jetbrains.mps.baseLanguage.structure.IYetUnresolved"), "4ykJ8Y83bdr"), varRef, SPropertyOperations.getString(onDemandImport, MetaAdapterFactory.getProperty(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x5a98df4004080866L, 0x1996ec29712bdd92L, "tokens"))));
if ((claz == null)) {
continue;
}
if (!(SNodeOperations.isInstanceOf(claz, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")))) {
continue;
}
SNode result = makeEnumConstRef(SNodeOperations.cast(claz, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")), enumConstName);
if (result != null) {
return null;
}
}
return null;
}
private SNode makeEnumConstRef(SNode enumClass, final String constName) {
// Q: maybe not findFirst, but rather fail if there are more than one...
SNode enumConst = ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(enumClass, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, 0xfc367503acL, "enumConstant"))).findFirst(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return constName.equals(SPropertyOperations.getString(it, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")));
}
});
if ((enumConst == null)) {
return null;
}
SNode result = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc37588bc8L, "jetbrains.mps.baseLanguage.structure.EnumConstantReference"));
SLinkOperations.setTarget(result, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc37588bc8L, 0x10a758428feL, "enumClass"), SNodeOperations.cast(enumClass, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")));
SLinkOperations.setTarget(result, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc37588bc8L, 0xfc37588bcaL, "enumConstantDeclaration"), enumConst);
return result;
}
private SNode transformUnqualifedEnumUnderSwitch(SNode switchCase, TypeChecker typeChecker) {
// FIXME share or re-use code with the corresponding NonTypesystemRule
SNode caseExp = SLinkOperations.getTarget(switchCase, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x10ef02cdd1bL, 0x10ef02d67cfL, "expression"));
if (!(SNodeOperations.isInstanceOf(caseExp, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference")))) {
return null;
}
SReference ref = SNodeOperations.getReference(SNodeOperations.cast(caseExp, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"));
if (!(ref instanceof DynamicReference)) {
return null;
}
final String enumConstName = ((DynamicReference) ref).getResolveInfo();
SNode scrutenee = SLinkOperations.getTarget(SNodeOperations.getNodeAncestor(caseExp, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x10ef02a8c6aL, "jetbrains.mps.baseLanguage.structure.SwitchStatement"), false, false), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x10ef02a8c6aL, 0x10ef02ec241L, "expression"));
if ((scrutenee == null)) {
return null;
}
SNode scruteneeType = typeChecker.getTypeOf(scrutenee);
if (!(SNodeOperations.isInstanceOf(scruteneeType, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType")))) {
return null;
}
SNode claz = SLinkOperations.getTarget(SNodeOperations.cast(scruteneeType, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, 0x101de490babL, "classifier"));
if (!(SNodeOperations.isInstanceOf(claz, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")))) {
return null;
}
SNode enumConst = ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(claz, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, 0xfc367503acL, "enumConstant"))).findFirst(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return SPropertyOperations.getString(it, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")).equals(enumConstName);
}
});
SNode enumConstRef = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc37588bc8L, "jetbrains.mps.baseLanguage.structure.EnumConstantReference"));
SLinkOperations.setTarget(enumConstRef, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc37588bc8L, 0x10a758428feL, "enumClass"), SNodeOperations.cast(claz, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc367070a5L, "jetbrains.mps.baseLanguage.structure.EnumClass")));
SLinkOperations.setTarget(enumConstRef, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfc37588bc8L, 0xfc37588bcaL, "enumConstantDeclaration"), enumConst);
return enumConstRef;
}
private SNode transformLocalCall(SNode localCall) {
// FIXME share or re-use code with the corresponding NonTypesystemRule
SReference ref = SNodeOperations.getReference(localCall, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"));
if (!(ref instanceof StaticReference)) {
return null;
}
SNode target = ref.getTargetNode();
if (!(SNodeOperations.isInstanceOf(target, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf0aL, "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration")))) {
return null;
}
Scope staticMethodScope = Scope.getScope(SNodeOperations.getParent(localCall), localCall, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf0aL, "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration"));
if (staticMethodScope.contains(target)) {
return null;
}
// it's out of scope, let's make it StaticMethodCall
SNode smc = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, "jetbrains.mps.baseLanguage.structure.StaticMethodCall"));
SLinkOperations.setTarget(smc, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, 0x10a7588b546L, "classConcept"), SNodeOperations.getNodeAncestor(target, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept"), false, false));
SLinkOperations.setTarget(smc, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"), SNodeOperations.cast(target, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf0aL, "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration")));
for (SNode arg : ListSequence.fromList(SLinkOperations.getChildren(localCall, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301aeL, "actualArgument")))) {
ListSequence.fromList(SLinkOperations.getChildren(smc, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301aeL, "actualArgument"))).addElement(SNodeOperations.copyNode(arg));
}
for (SNode arg : ListSequence.fromList(SLinkOperations.getChildren(localCall, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0x4500f31eb02a7788L, "typeArgument")))) {
ListSequence.fromList(SLinkOperations.getChildren(smc, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0x4500f31eb02a7788L, "typeArgument"))).addElement(SNodeOperations.copyNode(arg));
}
return smc;
}
private SNode transformLocalNameRef(SNode varRef) {
// it's either EnumConstReference or StaticFieldReference
// FIXME share or re-use code with the corresponding NonTypesystemRule
SReference ref = SNodeOperations.getReference(varRef, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"));
if (!(ref instanceof StaticReference)) {
return null;
}
SNode target = ref.getTargetNode();
if (!(SNodeOperations.isInstanceOf(target, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf93c84351fL, "jetbrains.mps.baseLanguage.structure.StaticFieldDeclaration")))) {
return null;
}
// now check whether it's in another class
SNode thisClass = SNodeOperations.getNodeAncestor(varRef, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"), false, false);
SNode thatClass = SNodeOperations.getNodeAncestor(target, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"), false, false);
// it should be ok to use ==, I think
if (thisClass == thatClass) {
// same class, such local method call is ok in baseLanguage
return null;
}
// different class, let's make this reference non-local, but qualified
SNode sfr = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, "jetbrains.mps.baseLanguage.structure.StaticFieldReference"));
SLinkOperations.setTarget(sfr, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, 0x10a75869f9bL, "classifier"), thatClass);
SLinkOperations.setTarget(sfr, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"), SNodeOperations.cast(target, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf93c84351fL, "jetbrains.mps.baseLanguage.structure.StaticFieldDeclaration")));
return sfr;
}
private Iterable<SNode> getImportsToRemove(SNode root) {
// FIXME share or re-use code with the corresponding NonTypesystemRule
final Map<String, SNode> importsByName = MapSequence.fromMap(new HashMap<String, SNode>());
ListSequence.fromList(SLinkOperations.getChildren(AttributeOperations.getAttribute(root, new IAttributeDescriptor.NodeAttribute(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports"))), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, 0x64c0181e6020a7L, "entries"))).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return !(SPropertyOperations.getBoolean(it, MetaAdapterFactory.getProperty(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x64c0181e603bcfL, 0x64c0181e603bd0L, "onDemand")));
}
}).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
MapSequence.fromMap(importsByName).put(((String) BHReflection.invoke(it, SMethodTrimmedId.create("lastToken", MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x5a98df4004080866L, "jetbrains.mps.baseLanguage.structure.Tokens"), "17WpDCYLyrY"))), it);
}
});
boolean unknownPresent = false;
boolean dynRefsPresent = false;
Set<SNode> retain = SetSequence.fromSet(new HashSet<SNode>());
Deque<SNode> stack = DequeSequence.fromDequeNew(new LinkedList<SNode>());
DequeSequence.fromDequeNew(stack).pushElement(root);
while (DequeSequence.fromDequeNew(stack).isNotEmpty()) {
SNode node = DequeSequence.fromDequeNew(stack).popElement();
DequeSequence.fromDequeNew(stack).addSequence(ListSequence.fromList(SNodeOperations.getChildren(node)));
if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x70ea1dc4c5721865L, "jetbrains.mps.baseLanguage.structure.IYetUnresolved"))) {
unknownPresent = true;
break;
}
Iterable<? extends SReference> refs = node.getReferences();
for (SReference ref : Sequence.fromIterable(refs)) {
if (!(ref instanceof DynamicReference)) {
continue;
}
dynRefsPresent = true;
String resolveInfo = ((DynamicReference) ref).getResolveInfo();
SetSequence.fromSet(retain).addElement(MapSequence.fromMap(importsByName).get(resolveInfo));
}
}
// retain all imports if 'unknown' concepts still present
if (unknownPresent) {
return null;
}
// on the other hand, if everything is resolved, remove all imports altogether
if (dynRefsPresent == false) {
// quick-fix
return SLinkOperations.getChildren(AttributeOperations.getAttribute(root, new IAttributeDescriptor.NodeAttribute(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, "jetbrains.mps.baseLanguage.structure.JavaImports"))), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x53f7c33f069862f2L, 0x64c0181e6020a7L, "entries"));
}
// removing only those single-type imports that didn't get into retain set
// quick fix
Iterable<SNode> unneeded = Sequence.fromIterable(MapSequence.fromMap(importsByName).values()).subtract(SetSequence.fromSet(retain));
return unneeded;
}
private Iterable<SReference> getTopLevelRefs(SNode node) {
final List<SReference> refs = ListSequence.fromList(new ArrayList<SReference>());
if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept"))) {
ListSequence.fromList(refs).addSequence(ListSequence.fromList(SNodeOperations.getReferences(SLinkOperations.getTarget(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, 0x10f6353296dL, "superclass")))));
ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, 0xff2ac0b419L, "implementedInterface"))).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(it)));
}
});
} else if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101edd46144L, "jetbrains.mps.baseLanguage.structure.Interface"))) {
ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101edd46144L, "jetbrains.mps.baseLanguage.structure.Interface")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101edd46144L, 0x101eddadad7L, "extendedInterface"))).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(it)));
}
});
}
for (SNode inner : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"), false, new SAbstractConcept[]{}))) {
if (SNodeOperations.isInstanceOf(inner, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1107e0cb103L, "jetbrains.mps.baseLanguage.structure.AnonymousClass"))) {
continue;
}
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(getTopLevelRefs(inner)));
}
return refs;
}
private Iterable<SReference> getFieldAndMethodTypeRefs(SNode node) {
List<SReference> refs = ListSequence.fromList(new ArrayList<SReference>());
Iterable<SNode> members = (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")) ? SLinkOperations.getChildren(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, 0x4a9a46de59132803L, "member")) : Sequence.<SNode>singleton(SNodeOperations.cast(node, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x112574373bdL, "jetbrains.mps.baseLanguage.structure.ClassifierMember"))));
for (SNode member : Sequence.fromIterable(members)) {
if (SNodeOperations.isInstanceOf(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37a7f6eL, "jetbrains.mps.baseLanguage.structure.VariableDeclaration"))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(SLinkOperations.getTarget(SNodeOperations.cast(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37a7f6eL, "jetbrains.mps.baseLanguage.structure.VariableDeclaration")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x450368d90ce15bc3L, 0x4ed4d318133c80ceL, "type")))));
} else if (SNodeOperations.isInstanceOf(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x6c6b6a1e379f9408L, "jetbrains.mps.baseLanguage.structure.MethodDeclaration"))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(SLinkOperations.getTarget(SNodeOperations.cast(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, "jetbrains.mps.baseLanguage.structure.BaseMethodDeclaration")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1fdL, "returnType")))));
for (SNode param : ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, "jetbrains.mps.baseLanguage.structure.BaseMethodDeclaration")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1feL, "parameter")))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(SLinkOperations.getTarget(param, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x450368d90ce15bc3L, 0x4ed4d318133c80ceL, "type")))));
}
for (SNode thrws : ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, "jetbrains.mps.baseLanguage.structure.BaseMethodDeclaration")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0x10f383d6949L, "throwsItem")))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(thrws)));
}
} else if (SNodeOperations.isInstanceOf(member, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(getFieldAndMethodTypeRefs(member)));
}
}
return refs;
}
private Iterable<SReference> getVarTypeRefs(SNode node) {
List<SReference> refs = ListSequence.fromList(new ArrayList<SReference>());
for (SNode block : ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b200L, "jetbrains.mps.baseLanguage.structure.StatementList"), false, new SAbstractConcept[]{}))) {
for (SNode varDecl : ListSequence.fromList(SNodeOperations.getNodeDescendants(block, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c37a7f6eL, "jetbrains.mps.baseLanguage.structure.VariableDeclaration"), false, new SAbstractConcept[]{}))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(SLinkOperations.getTarget(varDecl, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x450368d90ce15bc3L, 0x4ed4d318133c80ceL, "type")))));
}
}
return refs;
}
private Iterable<SReference> getVariableRefs(SNode node) {
return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference"), false, new SAbstractConcept[]{})).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return !(SNodeOperations.isInstanceOf(it, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, "jetbrains.mps.baseLanguage.structure.StaticFieldReference")));
}
}).select(new ISelector<SNode, SReference>() {
public SReference select(SNode it) {
return SNodeOperations.getReference(SNodeOperations.cast(it, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"));
}
});
}
private Iterable<SReference> getDotExpLeftParts(SNode node) {
return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression"), false, new SAbstractConcept[]{})).translate(new ITranslator2<SNode, SReference>() {
public Iterable<SReference> translate(SNode it) {
return deepReferences(SLinkOperations.getTarget(it, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand")));
}
});
}
private void resolveRefs(Iterable<SReference> refs, Map<SNodeReference, List<SReference>> result) {
for (SReference ref : refs) {
if (!(ref instanceof DynamicReference)) {
continue;
}
if (SetSequence.fromSet(myVisitedRefs).contains((SReference) ref)) {
continue;
}
SNode target = ref.getTargetNode();
if (target == null) {
continue;
}
SNode source = ref.getSourceNode();
SModelReference targetModel = target.getModel().getReference();
SReference staticRef = StaticReference.create(ref.getRole(), source, targetModel, target.getNodeId(), ((DynamicReference) ref).getResolveInfo());
List<SReference> nodeRefs = MapSequence.fromMap(result).get(source.getReference());
if (nodeRefs == null) {
nodeRefs = ListSequence.fromList(new ArrayList<SReference>());
MapSequence.fromMap(result).put(source.getReference(), nodeRefs);
}
ListSequence.fromList(nodeRefs).addElement((SReference) staticRef);
}
}
private void updateReference(Map<SNodeReference, List<SReference>> refMap) {
for (SNodeReference nodeRef : SetSequence.fromSet(MapSequence.fromMap(refMap).keySet())) {
final SNode node = nodeRef.resolve(myRepository);
if (node == null) {
continue;
}
final SModel sourceModel = node.getModel();
ListSequence.fromList(MapSequence.fromMap(refMap).get(nodeRef)).visitAll(new IVisitor<SReference>() {
public void visit(SReference it) {
SModelReference targetModelRef = it.getTargetSModelReference();
if (!(sourceModel.getReference().equals(targetModelRef))) {
// avoiding self-import
((SModelInternal) sourceModel).addModelImport(targetModelRef, true);
}
node.setReference(it.getRole(), it);
}
});
}
}
public static Iterable<SReference> deepReferences(SNode node) {
List<SReference> refs = ListSequence.fromList(new ArrayList<SReference>());
ListSequence.fromList(refs).addSequence(ListSequence.fromList(SNodeOperations.getReferences(node)));
for (SNode child : ListSequence.fromList(SNodeOperations.getChildren(node))) {
ListSequence.fromList(refs).addSequence(Sequence.fromIterable(deepReferences(child)));
}
return refs;
// generator for yield broken?
}
private SModel getModel(String pkgFqName, IFile pkgDir) {
for (SModel model : Sequence.fromIterable(myModule.getModels())) {
// not handling stereotype on purpose: if there's my.pkg@java_stub, it shouldn't prevent us
// from creating my.pkg
if (pkgFqName.equals(model.getModelName())) {
return model;
}
}
return createModel(pkgFqName, pkgDir);
}
private SModel createModel(String pkgFqName, IFile pkgDir) {
SModel modelDescr;
if (myCreateInplace) {
Tuples._2<DefaultModelRoot, SourceRoot> place = getRootContainingDir(pkgDir);
DefaultModelRoot modelRoot = place._0();
SourceRoot sourceRoot = place._1();
if (modelRoot == null) {
myMessageHandler.handle(new Message(MessageKind.ERROR, "Cannot convert to MPS in-place: java sources are not under proper model root"));
return null;
}
try {
DataSourceFactoryFromName dataSourceFactory = new JavaToMpsConverter.MyDataSourceFactory(pkgDir);
ModelFactory modelFactory = ModelFactoryService.getInstance().getDefaultModelFactory(dataSourceFactory.getType());
SModelName newModelName = new SModelName(pkgFqName);
modelDescr = modelRoot.createModel(newModelName, sourceRoot, dataSourceFactory, modelFactory);
} catch (ModelCannotBeCreatedException e) {
myMessageHandler.handle(new Message(MessageKind.ERROR, "Failed to create model " + pkgFqName, e.getMessage()));
return null;
}
} else {
DefaultModelRoot modelRoot = getFirstRootToCreateModel(pkgFqName);
if (modelRoot == null) {
myMessageHandler.handle(new Message(MessageKind.ERROR, "Failed to find model root to create model in"));
return null;
}
modelDescr = modelRoot.createModel(pkgFqName);
}
if (modelDescr == null) {
myMessageHandler.handle(new Message(MessageKind.ERROR, String.format("Failed to create model for package %s", pkgFqName)));
return null;
}
modelDescr.load();
return modelDescr;
}
private static final class MyDataSourceFactory implements DataSourceFactoryFromName {
private final IFile myPkgDir;
public MyDataSourceFactory(IFile pkgDir) {
myPkgDir = pkgDir;
}
@NotNull
@Override
public DataSource create(@NotNull SModelName name, @NotNull SourceRoot sourceRoot, @Nullable ModelRoot root) {
return new FilePerRootDataSource(myPkgDir, root);
}
@NotNull
@Override
public DataSourceType getType() {
return PreinstalledDataSourceTypes.FOLDER;
}
}
@Nullable
private DefaultModelRoot getFirstRootToCreateModel(String packageName) {
for (ModelRoot root : Sequence.fromIterable(myModule.getModelRoots())) {
if (!(root instanceof DefaultModelRoot)) {
continue;
}
if (root.canCreateModel(packageName)) {
return (DefaultModelRoot) root;
}
}
return null;
}
private Tuples._2<DefaultModelRoot, SourceRoot> getRootContainingDir(IFile dir) {
// returns modelRoot and sourceRoot within
for (ModelRoot modelRoot : Sequence.fromIterable(myModule.getModelRoots())) {
// or maybe more general: file based model root?
if (!(modelRoot instanceof DefaultModelRoot)) {
continue;
}
for (SourceRoot sourceRoot : ListSequence.fromList(((DefaultModelRoot) modelRoot).getSourceRoots(SourceRootKinds.SOURCES))) {
if (FileUtil.isSubPath(sourceRoot.getAbsolutePath().getPath(), dir.getPath())) {
return MultiTuple.<DefaultModelRoot,SourceRoot>from(((DefaultModelRoot) modelRoot), sourceRoot);
}
}
}
return MultiTuple.<DefaultModelRoot,SourceRoot>from((DefaultModelRoot) null, (SourceRoot) null);
}
}