use of com.intellij.psi.impl.light.LightElement in project intellij-community by JetBrains.
the class ExpressionGenerator method visitReferenceExpression.
@Override
public void visitReferenceExpression(@NotNull GrReferenceExpression referenceExpression) {
final GrExpression qualifier = referenceExpression.getQualifier();
final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
final String referenceName = referenceExpression.getReferenceName();
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
writeThisOrSuperRef(referenceExpression, qualifier, referenceName);
return;
}
if (ResolveUtil.isClassReference(referenceExpression)) {
// just delegate to qualifier
LOG.assertTrue(qualifier != null);
qualifier.accept(this);
return;
}
if (resolved instanceof PsiClass) {
builder.append(((PsiClass) resolved).getQualifiedName());
if (PsiUtil.isExpressionUsed(referenceExpression)) {
builder.append(".class");
}
return;
}
//don't try to resolve local vars that are provided my this generator (they are listed in myUsedVarNames)
if (resolved == null && qualifier == null && context.myUsedVarNames.contains(referenceName)) {
builder.append(referenceName);
return;
}
//all refs in script that are not resolved are saved in 'binding' of the script
if (qualifier == null && (resolved == null || resolved instanceof GrBindingVariable || resolved instanceof LightElement && !(resolved instanceof ClosureSyntheticParameter)) && (referenceExpression.getParent() instanceof GrIndexProperty || !(referenceExpression.getParent() instanceof GrCall)) && PsiUtil.getContextClass(referenceExpression) instanceof GroovyScriptClass) {
final GrExpression thisExpr = factory.createExpressionFromText("this", referenceExpression);
thisExpr.accept(this);
builder.append(".getBinding().getProperty(\"").append(referenceExpression.getReferenceName()).append("\")");
return;
}
final IElementType type = referenceExpression.getDotTokenType();
GrExpression qualifierToUse = qualifier;
if (type == GroovyTokenTypes.mMEMBER_POINTER) {
LOG.assertTrue(qualifier != null);
builder.append("new ").append(GroovyCommonClassNames.ORG_CODEHAUS_GROOVY_RUNTIME_METHOD_CLOSURE).append('(');
qualifier.accept(this);
builder.append(", \"").append(referenceName).append("\")");
return;
}
if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
LOG.assertTrue(qualifier != null);
String qualifierName = createVarByInitializer(qualifier);
builder.append('(').append(qualifierName).append(" == null ? null : ");
qualifierToUse = factory.createReferenceExpressionFromText(qualifierName, referenceExpression);
}
if (resolveResult.isInvokedOnProperty()) {
//property-style access to accessor (e.g. qual.prop should be translated to qual.getProp())
LOG.assertTrue(resolved instanceof PsiMethod);
LOG.assertTrue(GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod) resolved));
invokeMethodOn(((PsiMethod) resolved), qualifierToUse, GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, resolveResult.getSubstitutor(), referenceExpression);
} else {
if (qualifierToUse != null) {
qualifierToUse.accept(this);
builder.append('.');
}
if (resolved instanceof PsiNamedElement && !(resolved instanceof GrBindingVariable)) {
final String refName = ((PsiNamedElement) resolved).getName();
if (resolved instanceof GrVariable && context.analyzedVars.toWrap((GrVariable) resolved)) {
//this var should be wrapped by groovy.lang.Reference. so we add .get() tail.
builder.append(context.analyzedVars.toVarName((GrVariable) resolved));
if (!PsiUtil.isAccessedForWriting(referenceExpression)) {
builder.append(".get()");
}
} else {
builder.append(refName);
}
} else {
//unresolved reference
if (referenceName != null) {
if (PsiUtil.isAccessedForWriting(referenceExpression)) {
builder.append(referenceName);
} else {
PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
PsiType qualifierType = PsiImplUtil.getQualifierType(referenceExpression);
GroovyResolveResult[] candidates = qualifierType != null ? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression, stringType) : GroovyResolveResult.EMPTY_ARRAY;
final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
if (method != null) {
builder.append("getProperty(\"").append(referenceName).append("\")");
} else {
builder.append(referenceName);
}
}
} else {
final PsiElement nameElement = referenceExpression.getReferenceNameElement();
if (nameElement instanceof GrExpression) {
((GrExpression) nameElement).accept(this);
} else if (nameElement != null) {
builder.append(nameElement.toString());
}
}
}
}
if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
builder.append(')');
}
}
use of com.intellij.psi.impl.light.LightElement in project intellij-community by JetBrains.
the class ResolverProcessor method getElementInfo.
@NotNull
private static String getElementInfo(@NotNull PsiElement element) {
String text;
if (element instanceof LightElement) {
final PsiElement context = element.getContext();
text = context instanceof LightElement ? context.toString() : context != null ? context.getText() : null;
} else {
text = element.getText();
}
return "invalid resolve candidate: " + element.getClass() + ", text: " + text;
}
use of com.intellij.psi.impl.light.LightElement in project intellij-community by JetBrains.
the class GroovyLanguageInjectionSupport method doInject.
private static boolean doInject(@NotNull String languageId, @NotNull PsiElement psiElement, @NotNull PsiLanguageInjectionHost host) {
final PsiElement target = getTopLevelInjectionTarget(psiElement);
final PsiElement parent = target.getParent();
final Project project = psiElement.getProject();
if (parent instanceof GrReturnStatement) {
final GrControlFlowOwner owner = ControlFlowUtils.findControlFlowOwner(parent);
if (owner instanceof GrOpenBlock && owner.getParent() instanceof GrMethod) {
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, (PsiMethod) owner.getParent(), -1, host, languageId);
}
} else if (parent instanceof GrMethod) {
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, (GrMethod) parent, -1, host, languageId);
} else if (parent instanceof GrAnnotationNameValuePair) {
final PsiReference ref = parent.getReference();
if (ref != null) {
final PsiElement resolved = ref.resolve();
if (resolved instanceof PsiMethod) {
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, (PsiMethod) resolved, -1, host, languageId);
}
}
} else if (parent instanceof GrArgumentList && parent.getParent() instanceof GrMethodCall) {
final PsiMethod method = ((GrMethodCall) parent.getParent()).resolveMethod();
if (method != null) {
final int index = GrInjectionUtil.findParameterIndex(target, ((GrMethodCall) parent.getParent()));
if (index >= 0) {
return JavaLanguageInjectionSupport.doInjectInJavaMethod(project, method, index, host, languageId);
}
}
} else if (parent instanceof GrAssignmentExpression) {
final GrExpression expr = ((GrAssignmentExpression) parent).getLValue();
if (expr instanceof GrReferenceExpression) {
final PsiElement element = ((GrReferenceExpression) expr).resolve();
if (element != null) {
return doInject(languageId, element, host);
}
}
} else {
if (parent instanceof PsiVariable) {
Processor<PsiLanguageInjectionHost> fixer = getAnnotationFixer(project, languageId);
if (JavaLanguageInjectionSupport.doAddLanguageAnnotation(project, (PsiModifierListOwner) parent, host, languageId, fixer))
return true;
} else if (target instanceof PsiVariable && !(target instanceof LightElement)) {
Processor<PsiLanguageInjectionHost> fixer = getAnnotationFixer(project, languageId);
if (JavaLanguageInjectionSupport.doAddLanguageAnnotation(project, (PsiModifierListOwner) target, host, languageId, fixer))
return true;
}
}
return false;
}
use of com.intellij.psi.impl.light.LightElement in project android by JetBrains.
the class StringResourceSafeDeleteProcessorDelegate method getElementsToSearch.
@NotNull
@Override
public Collection<? extends PsiElement> getElementsToSearch(@NotNull PsiElement element, @Nullable Module module, @NotNull Collection<PsiElement> elementsToDelete) {
if (element instanceof XmlTag) {
XmlTag tag = (XmlTag) element;
XmlAttribute attribute = tag.getAttribute(ATTR_NAME);
assert attribute != null;
Collection<PsiElement> elements = new ArrayList<>();
// Find usages of the string element's name attribute value, such as @string/string_name references in XML files
elements.add(attribute.getValueElement());
// R.string.string_name references in Java files that are not LightElements
Collection<PsiField> fields = Arrays.stream(AndroidResourceUtil.findResourceFieldsForValueResource(tag, true)).filter(field -> !(field instanceof LightElement)).collect(Collectors.toList());
elements.addAll(fields);
return elements;
} else if (element instanceof XmlAttributeValue) {
return getElementsToSearch(element.getParent().getParent(), module, elementsToDelete);
} else {
return Collections.emptyList();
}
}
use of com.intellij.psi.impl.light.LightElement in project android by JetBrains.
the class AndroidResourceRenameResourceProcessor method findExistingNameConflicts.
@Override
public void findExistingNameConflicts(final PsiElement originalElement, String newName, final MultiMap<PsiElement, String> conflicts) {
ResourceType type = getResourceType(originalElement);
if (type == null) {
return;
}
PsiElement element = LazyValueResourceElementWrapper.computeLazyElement(originalElement);
if (element == null) {
return;
}
AndroidFacet facet = AndroidFacet.getInstance(element);
if (facet == null) {
return;
}
// First check to see if the new name is conflicting with an existing resource
if (element instanceof PsiFile) {
// The name of a file resource is the name of the file without the extension.
// So when dealing with a file, we must first remove the extension in the name
// before checking if it is already used.
newName = AndroidCommonUtils.getResourceName(type.getName(), newName);
}
AppResourceRepository appResources = AppResourceRepository.getAppResources(facet, true);
if (appResources.hasResourceItem(type, newName)) {
boolean foundElements = false;
PsiField[] resourceFields = AndroidResourceUtil.findResourceFields(facet, type.getName(), newName, true);
String message = String.format("Resource @%1$s/%2$s already exists", type, newName);
if (resourceFields.length > 0) {
// Use find usages to find the actual declaration location such that they can be shown in the conflicts view
AndroidFindUsagesHandlerFactory factory = new AndroidFindUsagesHandlerFactory();
if (factory.canFindUsages(originalElement)) {
FindUsagesHandler handler = factory.createFindUsagesHandler(resourceFields[0], false);
if (handler != null) {
PsiElement[] elements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements());
for (PsiElement e : elements) {
if (e instanceof LightElement) {
// AndroidLightField does not work in the conflicts view; UsageInfo throws NPE
continue;
}
conflicts.putValue(e, message);
foundElements = true;
}
}
}
}
if (!foundElements) {
conflicts.putValue(originalElement, message);
}
}
// Next see if the renamed resource is also defined externally, in which case we should ask the
// user if they really want to continue. Despite the name of this method ("findExistingNameConflicts")
// and the dialog used to show the message (ConflictsDialog), this isn't conflict specific; the
// dialog title simply says "Problems Detected" and the label for the text view is "The following
// problems were found". We need to use this because it's the only facility in the rename processor
// which lets us ask the user whether to continue and to have the answer either bail out of the operation
// or to resume.
// See if this is a locally defined resource (you can't rename fields from libraries such as appcompat)
// e.g. ?attr/listPreferredItemHeightSmall
String name = getResourceName(originalElement);
if (name != null) {
Project project = facet.getModule().getProject();
List<ResourceItem> all = appResources.getResourceItem(type, name);
if (all == null) {
all = Collections.emptyList();
}
List<ResourceItem> local = ProjectResourceRepository.getProjectResources(facet, true).getResourceItem(type, name);
if (local == null) {
local = Collections.emptyList();
}
HtmlBuilder builder = null;
if (local.size() == 0 && all.size() > 0) {
builder = new HtmlBuilder(new StringBuilder(300));
builder.add("Resource is also only defined in external libraries and cannot be renamed.");
} else if (local.size() < all.size()) {
// This item is also defined in one of the libraries, not just locally: we can't rename it. Should we
// display some sort of warning?
builder = new HtmlBuilder(new StringBuilder(300));
builder.add("The resource ").beginBold().add(PREFIX_RESOURCE_REF).add(type.getName()).add("/").add(name).endBold();
builder.add(" is defined outside of the project (in one of the libraries) and cannot ");
builder.add("be updated. This can change the behavior of the application.").newline().newline();
builder.add("Are you sure you want to do this?");
}
if (builder != null) {
appendUnhandledReferences(project, facet, all, local, builder);
conflicts.putValue(originalElement, builder.getHtml());
}
}
}
Aggregations