[groovy] add and use compilation phase hint for fields

This commit is contained in:
Daniil Ovchinnikov
2018-01-18 19:54:18 +03:00
parent 5980853e28
commit adb375c02b
4 changed files with 53 additions and 5 deletions
@@ -1,5 +1,4 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.psi.util;
import com.intellij.openapi.diagnostic.Logger;
@@ -37,10 +36,12 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.GrTypeDefinitionImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrScriptField;
import org.jetbrains.plugins.groovy.lang.resolve.CollectClassMembersUtil;
import org.jetbrains.plugins.groovy.lang.resolve.CompilationPhaseHint;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.*;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyClassImplUtilKt.processPhase;
import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtilKt.isAnnotationResolve;
import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtilKt.shouldProcessTypeParameters;
@@ -199,6 +200,10 @@ public class GrClassImplUtil {
@NotNull PsiElement place) {
if (isAnnotationResolve(processor)) return true; //don't process class members while resolving annotation
if (processor.getHint(CompilationPhaseHint.HINT_KEY) != null) {
return processPhase(grType, processor, state);
}
if (shouldProcessTypeParameters(processor)) {
for (final PsiTypeParameter typeParameter : grType.getTypeParameters()) {
if (!ResolveUtil.processElement(processor, typeParameter, state)) return false;
@@ -0,0 +1,26 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.psi.util
import com.intellij.psi.ResolveState
import com.intellij.psi.scope.PsiScopeProcessor
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
import org.jetbrains.plugins.groovy.lang.resolve.CompilationPhaseHint
import org.jetbrains.plugins.groovy.lang.resolve.CompilationPhaseHint.Phase.CONVERSION
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.processElement
import org.jetbrains.plugins.groovy.lang.resolve.shouldProcessFields
fun GrTypeDefinition.processPhase(processor: PsiScopeProcessor, state: ResolveState): Boolean {
val hint = requireNotNull(processor.getHint(CompilationPhaseHint.HINT_KEY))
return when (hint.beforePhase()) {
CONVERSION -> processBeforeConversion(processor, state)
}
}
private fun GrTypeDefinition.processBeforeConversion(processor: PsiScopeProcessor, state: ResolveState): Boolean {
if (processor.shouldProcessFields()) {
for (codeField in codeFields) { // raw field nodes as appear after parsing
if (!processElement(processor, codeField, state)) return false
}
}
return true
}
@@ -0,0 +1,17 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
public interface CompilationPhaseHint {
Key<CompilationPhaseHint> HINT_KEY = Key.create("groovy.compilation.phase");
enum Phase {
CONVERSION
}
@NotNull
Phase beforePhase();
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
@file:Suppress("LoopToCallChain")
package org.jetbrains.plugins.groovy.lang.resolve
@@ -68,6 +66,8 @@ fun PsiScopeProcessor.shouldProcessDynamicProperties(): Boolean {
fun PsiScopeProcessor.shouldProcessLocals(): Boolean = shouldProcess(GroovyResolveKind.VARIABLE)
fun PsiScopeProcessor.shouldProcessFields(): Boolean = shouldProcess(GroovyResolveKind.FIELD)
fun PsiScopeProcessor.shouldProcessMethods(): Boolean {
return ResolveUtil.shouldProcessMethods(getHint(ElementClassHint.KEY))
}