blob: 08a2d0ab706837a04058d524ba30a87e7c25dcd0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2013 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/eplv10.html
*
* Contributors:
* Sierra Wireless initial API and implementation
*******************************************************************************/
package org.eclipse.ldt.core.internal.ast.parser;
import java.util.List;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.declarations.Declaration;
import org.eclipse.dltk.compiler.IElementRequestor;
import org.eclipse.dltk.compiler.IElementRequestor.FieldInfo;
import org.eclipse.dltk.compiler.IElementRequestor.MethodInfo;
import org.eclipse.dltk.compiler.IElementRequestor.TypeInfo;
import org.eclipse.dltk.compiler.ISourceElementRequestor;
import org.eclipse.dltk.compiler.SourceElementRequestVisitor;
import org.eclipse.ldt.core.internal.ast.models.LuaASTUtils;
import org.eclipse.ldt.core.internal.ast.models.api.ExternalTypeRef;
import org.eclipse.ldt.core.internal.ast.models.api.FunctionTypeDef;
import org.eclipse.ldt.core.internal.ast.models.api.InlineTypeRef;
import org.eclipse.ldt.core.internal.ast.models.api.InternalTypeRef;
import org.eclipse.ldt.core.internal.ast.models.api.Item;
import org.eclipse.ldt.core.internal.ast.models.api.LuaFileAPI;
import org.eclipse.ldt.core.internal.ast.models.api.Parameter;
import org.eclipse.ldt.core.internal.ast.models.api.PrimitiveTypeRef;
import org.eclipse.ldt.core.internal.ast.models.api.RecordTypeDef;
import org.eclipse.ldt.core.internal.ast.models.api.TypeDef;
import org.eclipse.ldt.core.internal.ast.models.file.Block;
/**
* traverse the Lua AST of a file to extract the DLTK model.
*/
public class LuaSourceElementRequestorVisitor extends SourceElementRequestVisitor {
private LuaFileAPI luafileapi = null;
private Block firstBlock = null;
public LuaSourceElementRequestorVisitor(ISourceElementRequestor requesor) {
super(requesor);
}
/**
* @see org.eclipse.dltk.ast.ASTVisitor#visit(org.eclipse.dltk.ast.ASTNode)
*/
@Override
public boolean visit(ASTNode s) throws Exception {
if (s instanceof Item)
return visit((Item) s);
else if (s instanceof RecordTypeDef)
return visit((RecordTypeDef) s);
else if (s instanceof LuaFileAPI)
return visit((LuaFileAPI) s);
else if (s instanceof Block)
return visit((Block) s);
return super.visit(s);
}
/**
* @see org.eclipse.dltk.ast.ASTVisitor#visit(org.eclipse.dltk.ast.ASTNode)
*/
@Override
public boolean endvisit(ASTNode s) throws Exception {
if (s instanceof RecordTypeDef)
return endvisit((RecordTypeDef) s);
else if (s instanceof LuaFileAPI)
return endvisit((LuaFileAPI) s);
else if (s instanceof Item)
return endvisit((Item) s);
return super.endvisit(s);
}
public boolean visit(LuaFileAPI luaAPI) throws Exception {
luafileapi = luaAPI;
return true;
}
public boolean endvisit(LuaFileAPI luaAPI) throws Exception {
// HACK we need the lua fileapi when we traverse the internal content
// so we do no set it to null at end visiting anymore.
// see LuaSourceRoot.LuaFile.traverse(ASTVisitor)
// luafileapi = null;
return true;
}
public boolean visit(Block block) throws Exception {
if (firstBlock == null) {
firstBlock = block;
return true;
}
return false;
}
public boolean visit(Item item) throws Exception {
// an item could be transform in a method or a field
TypeDef resolvedType = LuaASTUtils.resolveTypeLocaly(luafileapi, item);
if (resolvedType instanceof FunctionTypeDef) {
// we manage a METHOD
MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo();
FunctionTypeDef funtionTypeDef = (FunctionTypeDef) resolvedType;
// extract parameters
List<Parameter> params = funtionTypeDef.getParameters();
String[] parametersName = new String[params.size()];
for (int i = 0; i < params.size(); i++) {
Parameter param = (Parameter) params.get(i);
parametersName[i] = param.getName();
}
// set METHOD information
methodInfo.name = item.getName();
methodInfo.parameterNames = parametersName;
methodInfo.nameSourceStart = item.sourceStart();
methodInfo.nameSourceEnd = item.sourceEnd() - 1;
methodInfo.declarationStart = item.sourceStart();
// calculate modifiers
int modifiers = 0; // define kind modifier
// define visibility
if (LuaASTUtils.isPrivate(item)) {
modifiers |= Declaration.AccPrivate;
} else if (LuaASTUtils.isModule(luafileapi, item)) {
modifiers |= Declaration.AccModule;
} else if (LuaASTUtils.isPublic(item)) {
modifiers |= Declaration.AccPublic;
}
methodInfo.modifiers = modifiers;
// store method info
this.fRequestor.enterMethod(methodInfo);
return true;
} else {
// we manage a FIELD
FieldInfo fieldinfo = new IElementRequestor.FieldInfo();
// set FIELD information
fieldinfo.name = item.getName();
fieldinfo.nameSourceStart = item.sourceStart();
fieldinfo.nameSourceEnd = item.sourceEnd() - 1;
fieldinfo.declarationStart = item.sourceStart();
// calculate modifiers
int modifiers = 0; // define kind modifier
// define visibility
if (LuaASTUtils.isPrivate(item)) {
modifiers |= Declaration.AccPrivate;
} else if (LuaASTUtils.isModule(luafileapi, item)) {
modifiers |= Declaration.AccModule;
} else if (LuaASTUtils.isPublic(item)) {
modifiers |= Declaration.AccPublic;
}
if (resolvedType instanceof RecordTypeDef)
modifiers |= Declaration.AccInterface;
fieldinfo.modifiers = modifiers;
// calculate type
if (item.getType() instanceof PrimitiveTypeRef || item.getType() instanceof InternalTypeRef || item.getType() instanceof ExternalTypeRef
|| item.getType() instanceof InlineTypeRef)
fieldinfo.type = item.getType().toReadableString();
// store field info
this.fRequestor.enterField(fieldinfo);
return true;
}
}
public boolean endvisit(Item item) throws Exception {
int declarationEnd = item.sourceEnd();
this.fRequestor.exitField(declarationEnd);
return true;
}
public boolean visit(RecordTypeDef type) throws Exception {
if (!LuaASTUtils.isInlineTypeDef(type)) {
RecordTypeDef recordtype = (RecordTypeDef) type;
// set TYPE Information
TypeInfo typeinfo = new IElementRequestor.TypeInfo();
typeinfo.name = recordtype.getName();
typeinfo.declarationStart = type.sourceStart();
typeinfo.nameSourceStart = type.sourceStart();
typeinfo.nameSourceEnd = type.sourceEnd() - 1;
if (type.getSupertype() != null) {
typeinfo.superclasses = new String[] { type.getSupertype().toReadableString() };
}
// calculate modifiers
int modifiers = 0; // define kind modifier
// define visibility
if (LuaASTUtils.isModule(luafileapi, recordtype)) {
modifiers |= Declaration.AccModule;
} else {
modifiers |= Declaration.AccPublic;
}
typeinfo.modifiers = modifiers;
this.fRequestor.enterType(typeinfo);
}
return true;
}
public boolean endvisit(RecordTypeDef type) throws Exception {
if (!LuaASTUtils.isInlineTypeDef(type)) {
int declarationEnd = type.sourceEnd();
this.fRequestor.exitType(declarationEnd);
}
return true;
}
}