blob: 20b4ad2311f62b15b9422c6b00b887309fba67e8 [file] [log] [blame]
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.groovy.configSlurper;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.extensions.GroovyMapContentProvider;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import java.util.*;
/**
* @author Sergey Evdokimov
*/
public class ConfigSlurperMapContentProvider extends GroovyMapContentProvider {
@Nullable
private static Pair<ConfigSlurperSupport.PropertiesProvider, List<String>> getInfo(@NotNull GrExpression qualifier,
@Nullable PsiElement resolve) {
if (!GroovyPsiManager.isInheritorCached(qualifier.getType(), GroovyCommonClassNames.GROOVY_UTIL_CONFIG_OBJECT)) {
return null;
}
GrExpression resolvedQualifier = qualifier;
PsiElement resolveResult = resolve;
List<String> path = new ArrayList<String>();
while (resolveResult == null) {
if (!(resolvedQualifier instanceof GrReferenceExpression)) return null;
GrReferenceExpression expr = (GrReferenceExpression)resolvedQualifier;
path.add(expr.getReferenceName());
resolvedQualifier = expr.getQualifierExpression();
if (resolvedQualifier instanceof GrReferenceExpression) {
resolveResult = ((GrReferenceExpression)resolvedQualifier).resolve();
}
else if (resolvedQualifier instanceof GrMethodCall) {
resolveResult = ((GrMethodCall)resolvedQualifier).resolveMethod();
}
else {
return null;
}
}
Collections.reverse(path);
ConfigSlurperSupport.PropertiesProvider propertiesProvider = null;
for (ConfigSlurperSupport slurperSupport : ConfigSlurperSupport.EP_NAME.getExtensions()) {
propertiesProvider = slurperSupport.getConfigSlurperInfo(resolvedQualifier, resolveResult);
if (propertiesProvider != null) break;
}
if (propertiesProvider == null) return null;
return Pair.create(propertiesProvider, path);
}
@Override
protected Collection<String> getKeyVariants(@NotNull GrExpression qualifier, @Nullable PsiElement resolve) {
Pair<ConfigSlurperSupport.PropertiesProvider, List<String>> info = getInfo(qualifier, resolve);
if (info == null) return Collections.emptyList();
final Set<String> res = new HashSet<String>();
info.first.collectVariants(info.second, new PairConsumer<String, Boolean>() {
@Override
public void consume(String variant, Boolean isFinal) {
res.add(variant);
}
});
return res;
}
@Override
public PsiType getValueType(@NotNull GrExpression qualifier, @Nullable PsiElement resolve, @NotNull final String key) {
Pair<ConfigSlurperSupport.PropertiesProvider, List<String>> info = getInfo(qualifier, resolve);
if (info == null) return null;
final Ref<Boolean> res = new Ref<Boolean>();
info.first.collectVariants(info.second, new PairConsumer<String, Boolean>() {
@Override
public void consume(String variant, Boolean isFinal) {
if (variant.equals(key)) {
res.set(isFinal);
}
else if (variant.startsWith(key) && variant.length() > key.length() && variant.charAt(key.length()) == '.') {
res.set(false);
}
}
});
if (res.get() != null && !res.get()) {
return JavaPsiFacade.getElementFactory(qualifier.getProject()).createTypeByFQClassName(GroovyCommonClassNames.GROOVY_UTIL_CONFIG_OBJECT, qualifier.getResolveScope());
}
return null;
}
}