package org.erlide.scoping;
import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.Arrays;
import java.util.Collection;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.erlide.erlang.Atom;
import org.erlide.erlang.AtomRefTarget;
import org.erlide.erlang.DefineAttribute;
import org.erlide.erlang.ErlangPackage;
import org.erlide.erlang.Expression;
import org.erlide.erlang.Expressions;
import org.erlide.erlang.FunCall;
import org.erlide.erlang.FunRef;
import org.erlide.erlang.FunType;
import org.erlide.erlang.Function;
import org.erlide.erlang.Macro;
import org.erlide.erlang.ModelExtensions;
import org.erlide.erlang.Module;
import org.erlide.erlang.RecordAttribute;
import org.erlide.erlang.RecordExpr;
import org.erlide.erlang.RecordFieldDef;
import org.erlide.erlang.RecordFieldExpr;
import org.erlide.erlang.RecordTuple;
import org.erlide.erlang.RemoteTarget;
import org.erlide.erlang.RemoteType;
import org.erlide.erlang.SpecAttribute;
import org.erlide.erlang.TopType;
import org.erlide.erlang.TypeSig;
import org.erlide.scoping.ErlangLinkCategory;
@SuppressWarnings("all")
public class ErlangLinkingHelper {
@Inject
@Extension
private ModelExtensions _modelExtensions;
@Inject
private ResourceDescriptionsProvider indexProvider;
public ErlangLinkCategory classifyAtom(final Atom obj) {
EObject _eContainer = obj.eContainer();
return this.classifyAtom(obj, _eContainer);
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final EObject context) {
return ErlangLinkCategory.NONE;
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final RemoteTarget context) {
Expression _module = context.getModule();
boolean _equals = Objects.equal(atom, _module);
if (_equals) {
return ErlangLinkCategory.MODULE;
}
Expression _function = context.getFunction();
boolean _equals_1 = Objects.equal(atom, _function);
if (_equals_1) {
boolean _and = false;
Expression _module_1 = context.getModule();
if (!(_module_1 instanceof Atom)) {
_and = false;
} else {
Expression _function_1 = context.getFunction();
_and = (_function_1 instanceof Atom);
}
if (_and) {
return ErlangLinkCategory.FUNCTION_CALL_REMOTE;
}
Expression _module_2 = context.getModule();
boolean _isModuleMacro = this._modelExtensions.isModuleMacro(_module_2);
if (_isModuleMacro) {
return ErlangLinkCategory.FUNCTION_CALL_REMOTE;
}
}
return ErlangLinkCategory.NONE;
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final FunCall context) {
return ErlangLinkCategory.FUNCTION_CALL_LOCAL;
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final FunRef context) {
ErlangLinkCategory _xblockexpression = null;
{
Expression _module = context.getModule();
boolean _equals = Objects.equal(atom, _module);
if (_equals) {
return ErlangLinkCategory.MODULE;
}
Expression _function = context.getFunction();
boolean _equals_1 = Objects.equal(atom, _function);
if (_equals_1) {
Expression _module_1 = context.getModule();
if ((_module_1 instanceof Atom)) {
final EObject parent = context.eContainer();
if ((parent instanceof SpecAttribute)) {
return ErlangLinkCategory.FUNCTION_CALL_REMOTE;
}
return ErlangLinkCategory.FUNCTION_REF_REMOTE;
}
Expression _module_2 = context.getModule();
boolean _equals_2 = Objects.equal(_module_2, null);
if (_equals_2) {
final EObject parent_1 = context.eContainer();
if ((parent_1 instanceof SpecAttribute)) {
return ErlangLinkCategory.FUNCTION_CALL_LOCAL;
}
return ErlangLinkCategory.FUNCTION_REF_LOCAL;
}
Expression _module_3 = context.getModule();
boolean _isModuleMacro = this._modelExtensions.isModuleMacro(_module_3);
if (_isModuleMacro) {
return ErlangLinkCategory.FUNCTION_REF_REMOTE;
}
}
_xblockexpression = ErlangLinkCategory.NONE;
}
return _xblockexpression;
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final RecordExpr context) {
ErlangLinkCategory _xblockexpression = null;
{
Expression _rec = context.getRec();
boolean _equals = Objects.equal(_rec, atom);
if (_equals) {
return ErlangLinkCategory.RECORD;
}
boolean _and = false;
Expression _rec_1 = context.getRec();
if (!(_rec_1 instanceof Atom)) {
_and = false;
} else {
Expression _field = context.getField();
boolean _equals_1 = Objects.equal(_field, atom);
_and = _equals_1;
}
if (_and) {
return ErlangLinkCategory.RECORD_FIELD;
}
_xblockexpression = ErlangLinkCategory.NONE;
}
return _xblockexpression;
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final RecordFieldExpr context) {
ErlangLinkCategory _xblockexpression = null;
{
final EObject parent = context.eContainer();
boolean _matched = false;
if (!_matched) {
if (parent instanceof RecordExpr) {
_matched=true;
Expression _rec = ((RecordExpr)parent).getRec();
if ((_rec instanceof Atom)) {
return ErlangLinkCategory.RECORD_FIELD;
}
}
}
if (!_matched) {
if (parent instanceof RecordTuple) {
_matched=true;
EObject _eContainer = context.eContainer();
EObject _eContainer_1 = _eContainer.eContainer();
if ((_eContainer_1 instanceof RecordExpr)) {
EObject _eContainer_2 = context.eContainer();
EObject _eContainer_3 = _eContainer_2.eContainer();
final RecordExpr expr = ((RecordExpr) _eContainer_3);
Expression _rec = expr.getRec();
if ((_rec instanceof Atom)) {
return ErlangLinkCategory.RECORD_FIELD;
}
}
}
}
_xblockexpression = ErlangLinkCategory.NONE;
}
return _xblockexpression;
}
private ErlangLinkCategory _classifyAtom(final Atom atom, final RemoteType context) {
return ErlangLinkCategory.TYPE_DEF;
}
public boolean isLinkableAtom(final Atom atom) {
ErlangLinkCategory _classifyAtom = this.classifyAtom(atom);
return (!Objects.equal(_classifyAtom, ErlangLinkCategory.NONE));
}
public AtomRefTarget getAtomReference(final Atom atom) {
AtomRefTarget _xblockexpression = null;
{
Resource _eResource = atom.eResource();
final IResourceDescriptions index = this.indexProvider.getResourceDescriptions(_eResource);
Resource _eResource_1 = atom.eResource();
final ResourceSet rset = _eResource_1.getResourceSet();
ErlangLinkCategory _classifyAtom = this.classifyAtom(atom);
_xblockexpression = _classifyAtom.getRef(index, atom, rset);
}
return _xblockexpression;
}
public AtomRefTarget getModuleRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
String _sourceText = this._modelExtensions.getSourceText(atom);
return this._modelExtensions.findModule(index, _sourceText, rset);
}
public AtomRefTarget getLocalCallRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
Function _xblockexpression = null;
{
final EObject parent = atom.eContainer();
Function _switchResult = null;
boolean _matched = false;
if (!_matched) {
if (parent instanceof FunCall) {
_matched=true;
Function _xblockexpression_1 = null;
{
Expressions _args = ((FunCall)parent).getArgs();
EList<Expression> _exprs = null;
if (_args!=null) {
_exprs=_args.getExprs();
}
int _size = 0;
if (_exprs!=null) {
_size=_exprs.size();
}
final int arity = _size;
Module _owningModule = this._modelExtensions.getOwningModule(parent);
Expression _target = ((FunCall)parent).getTarget();
String _sourceText = this._modelExtensions.getSourceText(_target);
_xblockexpression_1 = this._modelExtensions.getFunction(_owningModule, _sourceText, arity);
}
_switchResult = _xblockexpression_1;
}
}
if (!_matched) {
if (parent instanceof FunRef) {
_matched=true;
Function _xblockexpression_1 = null;
{
EObject _eContainer = ((FunRef)parent).eContainer();
final SpecAttribute xparent = ((SpecAttribute) _eContainer);
EList<TypeSig> _signatures = xparent.getSignatures();
TypeSig _head = IterableExtensions.<TypeSig>head(_signatures);
FunType _decl = _head.getDecl();
EList<TopType> _args = _decl.getArgs();
int _size = 0;
if (_args!=null) {
_size=_args.size();
}
final int arity = _size;
Module _owningModule = this._modelExtensions.getOwningModule(parent);
String _sourceText = this._modelExtensions.getSourceText(atom);
_xblockexpression_1 = this._modelExtensions.getFunction(_owningModule, _sourceText, arity);
}
_switchResult = _xblockexpression_1;
}
}
if (!_matched) {
_switchResult = null;
}
_xblockexpression = _switchResult;
}
return _xblockexpression;
}
public AtomRefTarget getRemoteCallRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
AtomRefTarget _xblockexpression = null;
{
EObject _eContainer = atom.eContainer();
final RemoteTarget parent = ((RemoteTarget) _eContainer);
AtomRefTarget _xifexpression = null;
EObject _eContainer_1 = parent.eContainer();
if ((_eContainer_1 instanceof FunCall)) {
AtomRefTarget _xblockexpression_1 = null;
{
EObject _eContainer_2 = parent.eContainer();
final FunCall call = ((FunCall) _eContainer_2);
Expressions _args = call.getArgs();
EList<Expression> _exprs = null;
if (_args!=null) {
_exprs=_args.getExprs();
}
int _size = 0;
if (_exprs!=null) {
_size=_exprs.size();
}
final int arity = _size;
String _xifexpression_1 = null;
Expression _module = parent.getModule();
boolean _isModuleMacro = this._modelExtensions.isModuleMacro(_module);
if (_isModuleMacro) {
Module _owningModule = this._modelExtensions.getOwningModule(atom);
_xifexpression_1 = this._modelExtensions.getName(_owningModule);
} else {
Expression _module_1 = parent.getModule();
_xifexpression_1 = this._modelExtensions.getSourceText(_module_1);
}
final String moduleName = _xifexpression_1;
Expression _function = parent.getFunction();
String _sourceText = this._modelExtensions.getSourceText(_function);
String _plus = (_sourceText + "/");
String _plus_1 = (_plus + Integer.valueOf(arity));
final QualifiedName qname = QualifiedName.create(moduleName, _plus_1);
final Iterable<IEObjectDescription> rfun = index.getExportedObjects(ErlangPackage.Literals.FUNCTION, qname, false);
AtomRefTarget _xifexpression_2 = null;
boolean _isEmpty = IterableExtensions.isEmpty(rfun);
boolean _not = (!_isEmpty);
if (_not) {
IEObjectDescription _head = IterableExtensions.<IEObjectDescription>head(rfun);
URI _eObjectURI = _head.getEObjectURI();
EObject _eObject = rset.getEObject(_eObjectURI, false);
_xifexpression_2 = ((AtomRefTarget) _eObject);
}
_xblockexpression_1 = _xifexpression_2;
}
_xifexpression = _xblockexpression_1;
} else {
Object _xblockexpression_2 = null;
{
EObject _eContainer_2 = parent.eContainer();
String _plus = ("remotecallref : parent.container=" + _eContainer_2);
String _plus_1 = (_plus + " -- ");
EObject _eContainer_3 = parent.eContainer();
String _sourceText = this._modelExtensions.getSourceText(_eContainer_3);
String _plus_2 = (_plus_1 + _sourceText);
InputOutput.<String>println(_plus_2);
_xblockexpression_2 = null;
}
_xifexpression = ((AtomRefTarget)_xblockexpression_2);
}
_xblockexpression = _xifexpression;
}
return _xblockexpression;
}
public AtomRefTarget getRemoteFunRefRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
AtomRefTarget _xblockexpression = null;
{
EObject _eContainer = atom.eContainer();
final FunRef parent = ((FunRef) _eContainer);
Expression _arity = parent.getArity();
final String arity = this._modelExtensions.getSourceText(_arity);
String _xifexpression = null;
Expression _module = parent.getModule();
boolean _isModuleMacro = this._modelExtensions.isModuleMacro(_module);
if (_isModuleMacro) {
Module _owningModule = this._modelExtensions.getOwningModule(atom);
_xifexpression = this._modelExtensions.getName(_owningModule);
} else {
Expression _module_1 = parent.getModule();
_xifexpression = this._modelExtensions.getSourceText(_module_1);
}
final String moduleName = _xifexpression;
Expression _function = parent.getFunction();
String _sourceText = this._modelExtensions.getSourceText(_function);
String _plus = (_sourceText + "/");
String _plus_1 = (_plus + arity);
final QualifiedName qname = QualifiedName.create(moduleName, _plus_1);
final Iterable<IEObjectDescription> rfun = index.getExportedObjects(ErlangPackage.Literals.FUNCTION, qname, false);
AtomRefTarget _xifexpression_1 = null;
boolean _isEmpty = IterableExtensions.isEmpty(rfun);
boolean _not = (!_isEmpty);
if (_not) {
IEObjectDescription _head = IterableExtensions.<IEObjectDescription>head(rfun);
URI _eObjectURI = _head.getEObjectURI();
EObject _eObject = rset.getEObject(_eObjectURI, false);
_xifexpression_1 = ((AtomRefTarget) _eObject);
}
_xblockexpression = _xifexpression_1;
}
return _xblockexpression;
}
public AtomRefTarget getLocalFunRefRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
Function _xblockexpression = null;
{
EObject _eContainer = atom.eContainer();
final FunRef parent = ((FunRef) _eContainer);
Expression _arity = parent.getArity();
final String arity = this._modelExtensions.getSourceText(_arity);
Function _xtrycatchfinallyexpression = null;
try {
Module _owningModule = this._modelExtensions.getOwningModule(parent);
Expression _function = parent.getFunction();
String _sourceText = this._modelExtensions.getSourceText(_function);
int _parseInt = Integer.parseInt(arity);
_xtrycatchfinallyexpression = this._modelExtensions.getFunction(_owningModule, _sourceText, _parseInt);
} catch (final Throwable _t) {
if (_t instanceof Exception) {
final Exception e = (Exception)_t;
return null;
} else {
throw Exceptions.sneakyThrow(_t);
}
}
_xblockexpression = _xtrycatchfinallyexpression;
}
return _xblockexpression;
}
public AtomRefTarget getRecordRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
AtomRefTarget _xblockexpression = null;
{
Module _owningModule = this._modelExtensions.getOwningModule(atom);
final String moduleName = this._modelExtensions.getName(_owningModule);
boolean _equals = Objects.equal(moduleName, null);
if (_equals) {
return null;
}
String _sourceText = this._modelExtensions.getSourceText(atom);
final QualifiedName qname = QualifiedName.create(moduleName, _sourceText);
final Iterable<IEObjectDescription> rfun = index.getExportedObjects(ErlangPackage.Literals.RECORD_ATTRIBUTE, qname, false);
AtomRefTarget _xifexpression = null;
boolean _isEmpty = IterableExtensions.isEmpty(rfun);
boolean _not = (!_isEmpty);
if (_not) {
IEObjectDescription _head = IterableExtensions.<IEObjectDescription>head(rfun);
URI _eObjectURI = _head.getEObjectURI();
EObject _eObject = rset.getEObject(_eObjectURI, false);
_xifexpression = ((AtomRefTarget) _eObject);
}
_xblockexpression = _xifexpression;
}
return _xblockexpression;
}
private RecordExpr getRecordExprForField(final EObject field) {
RecordExpr _switchResult = null;
boolean _matched = false;
if (!_matched) {
if (field instanceof RecordExpr) {
_matched=true;
_switchResult = ((RecordExpr) field);
}
}
if (!_matched) {
EObject _eContainer = field.eContainer();
_switchResult = this.getRecordExprForField(_eContainer);
}
return _switchResult;
}
public AtomRefTarget getRecordFieldRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
RecordFieldDef _xblockexpression = null;
{
final RecordExpr recExpr = this.getRecordExprForField(atom);
Expression _rec = recExpr.getRec();
AtomRefTarget _recordRef = this.getRecordRef(index, ((Atom) _rec), rset);
final RecordAttribute record = ((RecordAttribute) _recordRef);
boolean _equals = Objects.equal(record, null);
if (_equals) {
return null;
}
EList<RecordFieldDef> _fields = record.getFields();
final Function1<RecordFieldDef, Boolean> _function = new Function1<RecordFieldDef, Boolean>() {
@Override
public Boolean apply(final RecordFieldDef it) {
String _name = it.getName();
String _sourceText = ErlangLinkingHelper.this._modelExtensions.getSourceText(atom);
return Boolean.valueOf(Objects.equal(_name, _sourceText));
}
};
_xblockexpression = IterableExtensions.<RecordFieldDef>findFirst(_fields, _function);
}
return _xblockexpression;
}
public AtomRefTarget getTypeRef(final IResourceDescriptions index, final Atom atom, final ResourceSet rset) {
AtomRefTarget _xblockexpression = null;
{
Module _owningModule = this._modelExtensions.getOwningModule(atom);
final String moduleName = this._modelExtensions.getName(_owningModule);
boolean _equals = Objects.equal(moduleName, null);
if (_equals) {
return null;
}
String _sourceText = this._modelExtensions.getSourceText(atom);
final QualifiedName qname = QualifiedName.create(moduleName, _sourceText);
final Iterable<IEObjectDescription> rtyp = index.getExportedObjects(ErlangPackage.Literals.TYPE_ATTRIBUTE, qname, false);
AtomRefTarget _xifexpression = null;
boolean _isEmpty = IterableExtensions.isEmpty(rtyp);
boolean _not = (!_isEmpty);
if (_not) {
IEObjectDescription _head = IterableExtensions.<IEObjectDescription>head(rtyp);
URI _eObjectURI = _head.getEObjectURI();
EObject _eObject = rset.getEObject(_eObjectURI, false);
_xifexpression = ((AtomRefTarget) _eObject);
}
_xblockexpression = _xifexpression;
}
return _xblockexpression;
}
public DefineAttribute getMacroReference(final Macro macro) {
Module _owningModule = this._modelExtensions.getOwningModule(macro);
Collection<DefineAttribute> _allItemsOfType = this._modelExtensions.<DefineAttribute>getAllItemsOfType(_owningModule, DefineAttribute.class);
final Function1<DefineAttribute, Boolean> _function = new Function1<DefineAttribute, Boolean>() {
@Override
public Boolean apply(final DefineAttribute it) {
String _macroName = it.getMacroName();
String _macroName_1 = ErlangLinkingHelper.this.getMacroName(macro);
return Boolean.valueOf(Objects.equal(_macroName, _macroName_1));
}
};
return IterableExtensions.<DefineAttribute>findFirst(_allItemsOfType, _function);
}
public String getMacroName(final Macro macro) {
String _xblockexpression = null;
{
final String txt = this._modelExtensions.getSourceText(macro);
String _xifexpression = null;
boolean _startsWith = txt.startsWith("? ");
if (_startsWith) {
_xifexpression = txt.substring(2);
} else {
_xifexpression = txt;
}
_xblockexpression = _xifexpression;
}
return _xblockexpression;
}
private ErlangLinkCategory classifyAtom(final Atom atom, final EObject context) {
if (context instanceof RemoteType) {
return _classifyAtom(atom, (RemoteType)context);
} else if (context instanceof FunRef) {
return _classifyAtom(atom, (FunRef)context);
} else if (context instanceof FunCall) {
return _classifyAtom(atom, (FunCall)context);
} else if (context instanceof RecordExpr) {
return _classifyAtom(atom, (RecordExpr)context);
} else if (context instanceof RemoteTarget) {
return _classifyAtom(atom, (RemoteTarget)context);
} else if (context instanceof RecordFieldExpr) {
return _classifyAtom(atom, (RecordFieldExpr)context);
} else if (context != null) {
return _classifyAtom(atom, context);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(atom, context).toString());
}
}
}