/*******************************************************************************
* Copyright (c) 2011 Sierra Wireless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.koneki.ldt.core.internal.ast.models;
import java.util.List;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.declarations.Declaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.core.Flags;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.SourceParserUtil;
import org.eclipse.koneki.ldt.core.internal.Activator;
import org.eclipse.koneki.ldt.core.internal.ast.models.api.FunctionTypeDef;
import org.eclipse.koneki.ldt.core.internal.ast.models.api.Item;
import org.eclipse.koneki.ldt.core.internal.ast.models.api.LuaFileAPI;
import org.eclipse.koneki.ldt.core.internal.ast.models.api.RecordTypeDef;
import org.eclipse.koneki.ldt.core.internal.ast.models.api.TypeDef;
import org.eclipse.koneki.ldt.core.internal.ast.models.common.LuaASTNode;
import org.eclipse.koneki.ldt.core.internal.ast.models.common.LuaSourceRoot;
import org.eclipse.koneki.ldt.core.internal.ast.models.dltk.FakeField;
import org.eclipse.koneki.ldt.core.internal.ast.models.dltk.FakeMethod;
import org.eclipse.koneki.ldt.core.internal.ast.models.dltk.IFakeElement;
import org.eclipse.koneki.ldt.core.internal.ast.models.file.LocalVar;
public final class LuaASTModelUtils {
private LuaASTModelUtils() {
}
/**
* Get LuaSourceRoot from ISourceModule <br/>
*
* DLTK Model => AST
*/
public static LuaSourceRoot getLuaSourceRoot(ISourceModule module) {
ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(module);
if (moduleDeclaration instanceof LuaSourceRoot)
return (LuaSourceRoot) moduleDeclaration;
return null;
}
/**
* Get LuaSourceRoot from ISourceModule <br/>
*
* DLTK Model => AST
*/
public static ASTNode getASTNode(final IModelElement modelElement) {
if (modelElement instanceof IFakeElement)
return ((IFakeElement) modelElement).getLuaASTNode();
if (modelElement instanceof ISourceModule)
return getLuaSourceRoot((ISourceModule) modelElement);
if (modelElement instanceof IType)
return getTypeDef((IType) modelElement);
if (modelElement instanceof IField)
return getItem((IField) modelElement);
if (modelElement instanceof IMethod)
return getItem((IMethod) modelElement);
return null;
}
/**
* Get Record type def from {@link ISourceModule} <br/>
*
* DLTK Model => AST
*/
public static TypeDef getTypeDef(IType type) {
LuaSourceRoot luaSourceRoot = getLuaSourceRoot(type.getSourceModule());
LuaFileAPI fileapi = luaSourceRoot.getFileapi();
return fileapi.getTypes().get(type.getElementName());
}
/**
* Get Item from {@link IField} <br/>
*
* DLTK Model => AST
*/
public static Item getItem(IField field) {
IModelElement parent = field.getParent();
if (parent instanceof IType) {
RecordTypeDef typeDef = (RecordTypeDef) getTypeDef((IType) parent);
return typeDef.getFields().get(field.getElementName());
} else if (parent instanceof ISourceModule) {
LuaSourceRoot luaSourceRoot = getLuaSourceRoot((ISourceModule) parent);
try {
if (Flags.isPrivate(field.getFlags())) {
List<LocalVar> localVars = luaSourceRoot.getInternalContent().getContent().getLocalVars();
for (LocalVar localVar : localVars) {
if (localVar.getVar().getName().equals(field.getElementName()))
return localVar.getVar();
}
} else {
return luaSourceRoot.getFileapi().getGlobalvars().get(field.getElementName());
}
} catch (ModelException e) {
Activator.logError("unable to get item from field " + field, e); //$NON-NLS-1$
return null;
}
}
return null;
}
/**
* Get Item from IMethod <br/>
*
* DLTK Model => AST
*/
public static Item getItem(IMethod method) {
IModelElement parent = method.getParent();
if (parent instanceof IType) {
RecordTypeDef typeDef = (RecordTypeDef) getTypeDef((IType) parent);
return typeDef.getFields().get(method.getElementName());
} else if (parent instanceof ISourceModule) {
LuaSourceRoot luaSourceRoot = getLuaSourceRoot((ISourceModule) parent);
try {
if (Flags.isPrivate(method.getFlags())) {
List<LocalVar> localVars = luaSourceRoot.getInternalContent().getContent().getLocalVars();
for (LocalVar localVar : localVars) {
if (localVar.getVar().getName().equals(method.getElementName()))
return localVar.getVar();
}
} else {
return luaSourceRoot.getFileapi().getGlobalvars().get(method.getElementName());
}
} catch (ModelException e) {
Activator.logError("unable to get item from method " + method, e); //$NON-NLS-1$
return null;
}
}
return null;
}
/**
* Get IType from RecordTypeDef <br/>
*
* AST => DLTK Model
*/
public static IType getIType(ISourceModule module, RecordTypeDef recordtypeDef) {
IType type = module.getType(recordtypeDef.getName());
return type;
}
/**
* Get IMember from Item <br/>
*
* AST => DLTK Model
*/
public static IMember getIMember(ISourceModule sourceModule, Item item) {
LuaASTNode parent = item.getParent();
if (LuaASTUtils.isTypeField(item)) {
// support record field
IType iType = getIType(sourceModule, (RecordTypeDef) parent);
if (iType != null) {
try {
for (IModelElement child : iType.getChildren()) {
if (child.getElementName().equals(item.getName()) && child instanceof IMember)
return (IMember) child;
}
} catch (ModelException e) {
Activator.logWarning("unable to get IMember corresponding to the given item " + item, e); //$NON-NLS-1$
}
}
} else if (LuaASTUtils.isLocal(item)) {
// TODO retrieve local var which are in the model (so the local var in the first block)
// support local variable
// ------------------------------------------------------------------------------------
// manage method
TypeDef resolvedtype = LuaASTUtils.resolveTypeLocaly(sourceModule, item);
if (resolvedtype != null && resolvedtype instanceof FunctionTypeDef) {
FunctionTypeDef functionResolvedType = (FunctionTypeDef) resolvedtype;
String[] parametersName = new String[functionResolvedType.getParameters().size()];
for (int i = 0; i < parametersName.length; i++) {
parametersName[i] = functionResolvedType.getParameters().get(i).getName();
}
return new FakeMethod(sourceModule, item.getName(), item.sourceStart(), item.getName().length(), parametersName,
Declaration.AccPrivate, item);
}
// manage field
return new FakeField(sourceModule, item.getName(), item.sourceStart(), item.getName().length(), Declaration.AccPrivate, item);
} else if (LuaASTUtils.isGlobal(item)) {
// support global var
try {
for (IModelElement child : sourceModule.getChildren()) {
if (child.getElementName().equals(item.getName()) && child instanceof IMember)
return (IMember) child;
}
} catch (ModelException e) {
Activator.logWarning("unable to get IMember corresponding to the given item " + item, e); //$NON-NLS-1$
}
} else if (LuaASTUtils.isUnresolvedGlobal(item)) {
return new FakeField(sourceModule, item.getName(), item.sourceStart(), item.getName().length(), Declaration.AccGlobal, item);
}
return null;
}
/**
* Get IModelElement from ASTNode <br/>
*
* AST => DLTK Model
*/
public static IModelElement getIModelElement(ISourceModule sourcemodule, LuaASTNode astNode) {
if (astNode instanceof RecordTypeDef) {
return getIType(sourcemodule, (RecordTypeDef) astNode);
} else if (astNode instanceof Item) {
return getIMember(sourcemodule, (Item) astNode);
}
return null;
}
}