/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2014-2014 TiVo Inc.
* Copyright 2014-2014 AS3Boyan
* Copyright 2014-2014 Elias Ku
*
* 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.intellij.plugins.haxe.lang.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
/**
* @author: Srikanth.Ganapavarapu
*/
public abstract class HaxeParameterPsiMixinImpl extends AbstractHaxeNamedComponent implements HaxeParameterPsiMixin {
private static final Logger LOG = Logger.getInstance("#com.intellij.plugins.haxe.lang.psi.impl.HaxeParameterBase");
public HaxeParameterPsiMixinImpl(ASTNode node) {
super(node);
}
public HaxeParameterPsiMixinImpl(PsiParameter parameter) {
super(parameter.getNode());
}
public HaxeParameterPsiMixinImpl(HaxeParameter parameter) {
super(parameter.getNode());
}
@Override
@NotNull
public PsiElement getDeclarationScope() {
// Lifted, lock, stock, and barrel from PsiParameterImpl.java
// which was for the Java language.
// TODO: Need to verify against the Haxe language spec.
// Are there other situations?
final PsiElement parent = getParent();
if (parent == null) return this;
if (parent instanceof PsiParameterList) {
return parent.getParent();
}
if (parent instanceof PsiForeachStatement) {
return parent;
}
if (parent instanceof PsiCatchSection) {
return parent;
}
PsiElement[] children = parent.getChildren();
//noinspection ConstantConditions
if (children != null) {
ext:
for (int i = 0; i < children.length; i++) {
if (children[i].equals(this)) {
for (int j = i + 1; j < children.length; j++) {
if (children[j] instanceof PsiCodeBlock) return children[j];
}
break ext;
}
}
}
LOG.error("Code block not found among parameter' (" + this + ") parent' (" + parent + ") children: " + Arrays.asList(children));
return null;
}
@Override
public boolean isVarArgs() {
// In Haxe (http://old.haxe.org/doc/cross/reflect), there are no
// varargs parameters, but the function is made to accept variable
// arguments. So, at this level it's always false.
return false;
}
@Nullable
@Override
public PsiTypeElement getTypeElement() {
// Lifted, lock, stock, and barrel from PsiParameterImpl.java
// which was for the Java language.
// TODO: Broken. Needs re-implementation.
// Need to verify against the Haxe language spec.
// Are there other situations?
// XXX: This won't work. The children are further down the tree, not at the child level.
for (PsiElement child = getFirstChild(); child != null; child = child.getNextSibling()) {
if (child instanceof PsiTypeElement) {
//noinspection unchecked
return (PsiTypeElement)child;
}
}
// PsiTypeElement t = (HaxeType) PsiTreeUtil.findChildOfType(this, HaxeType.class);
return null;
}
@NotNull
@Override
public PsiType getType() {
// The Haxe language variable type (int, float, etc.), not the psi token type.
PsiTypeElement el = getTypeElement();
PsiType type = null != el ? el.getType() : PsiType.VOID;
return null != type ? type : PsiType.VOID;
}
@Nullable
@Override
public PsiExpression getInitializer() {
// XXX: this may need to be implemented for refactoring functionality
return null;
}
@Override
public boolean hasInitializer() {
// XXX: this may need to be implemented for refactoring functionality
return false;
}
@Override
public void normalizeDeclaration() throws IncorrectOperationException {
// XXX: this may need to be implemented for refactoring functionality
}
@Nullable
@Override
public Object computeConstantValue() {
// XXX: this may need to be implemented for refactoring functionality
return null;
}
@Nullable
@Override
public PsiIdentifier getNameIdentifier() {
final HaxeComponentName componentName = getComponentName();
return componentName != null ? componentName.getIdentifier() : null;
}
@NotNull
@Override
public HaxeModifierList getModifierList() {
HaxeModifierList haxePsiModifierList = new HaxeModifierListImpl(this.getNode());
// Triplicated code! HaxeMethodPsiMixinImpl + HaxeParameterPsiMixinImpl + HaxePsiFieldImpl
if (isStatic()) {
haxePsiModifierList.setModifierProperty(HaxePsiModifier.STATIC, true);
}
if (isInline()) {
haxePsiModifierList.setModifierProperty(HaxePsiModifier.INLINE, true);
}
if (isPublic()) {
haxePsiModifierList.setModifierProperty(HaxePsiModifier.PUBLIC, true);
}
else {
haxePsiModifierList.setModifierProperty(HaxePsiModifier.PRIVATE, true);
}
// XXX: make changes to bnf, and add code to detect any other missing annotations/modifiers
// that can be applied to an identifier declaration... set appropriate elements as above.
// E.g. see AbstractHaxeClassPsi
return haxePsiModifierList;
}
@Override
public boolean hasModifierProperty(@HaxePsiModifier.ModifierConstant @NonNls @NotNull String name) {
return getModifierList().hasModifierProperty(name);
}
}