/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sylvanaar.idea.Lua.lang.luadoc.parser.elements;
import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.util.containers.HashSet;
import com.sylvanaar.idea.Lua.lang.luadoc.lexer.ILuaDocElementType;
import com.sylvanaar.idea.Lua.lang.luadoc.lexer.LuaDocLexer;
import com.sylvanaar.idea.Lua.lang.luadoc.psi.api.LuaDocTag;
import com.sylvanaar.idea.Lua.lang.parser.util.ParserUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Set;
import static com.sylvanaar.idea.Lua.lang.luadoc.lexer.LuaDocTokenTypes.LDOC_TAG_PLAIN_VALUE_TOKEN;
import static com.sylvanaar.idea.Lua.lang.luadoc.lexer.LuaDocTokenTypes.LDOC_TAG_VALUE;
/**
* @author ilyas
*/
public class LuaDocTagValueTokenType extends LuaDocChameleonElementType implements ILuaDocElementType {
private static final Set<String> TAGS_WITH_REFERENCES = new HashSet<String>();
private static final Set<String> BUILT_IN_TYPES = new HashSet<String>();
static {
BUILT_IN_TYPES.addAll(Arrays
.asList("table", "number", "boolean", "string", "nil", "userdata", "function", "thread"));
}
static {
TAGS_WITH_REFERENCES.addAll(Arrays.asList("@see", "@field", "@name"));
}
public LuaDocTagValueTokenType() {
super("LDOC_TAG_VALUE_TOKEN");
}
public TagValueTokenType getValueType(@NotNull ASTNode node) {
return isReferenceElement(node.getTreeParent(),
node) ? TagValueTokenType.REFERENCE_ELEMENT : TagValueTokenType.VALUE_TOKEN;
}
public ASTNode parseContents(ASTNode chameleon) {
ASTNode parent = chameleon.getTreeParent();
if (isReferenceElement(parent, chameleon)) {
return parseImpl(chameleon);
}
return getPlainValueToken(chameleon);
}
private static boolean isReferenceElement(ASTNode parent, ASTNode child) {
if (parent != null && child != null) {
PsiElement parentPsi = parent.getPsi();
if (parentPsi instanceof LuaDocTag) {
String name = ((LuaDocTag) parentPsi).getName();
if (TAGS_WITH_REFERENCES.contains(name)) {
return parent.findChildByType(LDOC_TAG_VALUE) == child;
}
}
}
return false;
}
private static ASTNode getPlainValueToken(ASTNode chameleon) {
return new LeafPsiElement(LDOC_TAG_PLAIN_VALUE_TOKEN, chameleon.getChars());
}
private ASTNode parseImpl(ASTNode chameleon) {
final PsiElement parentElement = chameleon.getTreeParent().getPsi();
assert parentElement != null;
final Project project = parentElement.getProject();
final PsiBuilder builder = new PsiBuilderImpl(project, getLanguage(), new LuaDocLexer(), chameleon, chameleon.getText());
PsiBuilder.Marker rootMarker = builder.mark();
if (BUILT_IN_TYPES.contains(chameleon.getText())) {
ParserUtils.advance(builder, 1);
} else {
parseBody(builder);
}
rootMarker.done(this);
return builder.getTreeBuilt().getFirstChildNode();
}
private static void parseBody(PsiBuilder builder) {
//ReferenceElement.parse(builder, false, false, false, false);
while (!builder.eof()) {
builder.advanceLexer();
}
}
public static enum TagValueTokenType {
REFERENCE_ELEMENT, VALUE_TOKEN
}
}