/* * Copyright 2009-2017 the original author or authors. * * 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.codehaus.groovy.eclipse.dsl.lookup; import java.util.List; import java.util.Set; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.stmt.BlockStatement; import org.codehaus.groovy.eclipse.dsl.DSLDStore; import org.codehaus.groovy.eclipse.dsl.DSLDStoreManager; import org.codehaus.groovy.eclipse.dsl.DSLPreferences; import org.codehaus.groovy.eclipse.dsl.GroovyDSLCoreActivator; import org.codehaus.groovy.eclipse.dsl.contributions.IContributionElement; import org.codehaus.groovy.eclipse.dsl.pointcuts.GroovyDSLDContext; import org.codehaus.jdt.groovy.internal.compiler.ast.JDTResolver; import org.codehaus.jdt.groovy.model.GroovyCompilationUnit; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.groovy.search.AbstractSimplifiedTypeLookup; import org.eclipse.jdt.groovy.search.ITypeLookup; import org.eclipse.jdt.groovy.search.ITypeResolver; import org.eclipse.jdt.groovy.search.TypeLookupResult.TypeConfidence; import org.eclipse.jdt.groovy.search.VariableScope; /** * Uses the current set of DSLDs for this project to look up types. */ public class DSLDTypeLookup extends AbstractSimplifiedTypeLookup implements ITypeLookup, ITypeResolver { private static final String GORM_SIGNATURE = "Provided by Grails ORM DSL"; DSLDStoreManager contextStoreManager = GroovyDSLCoreActivator.getDefault().getContextStoreManager(); private DSLDStore store; private GroovyDSLDContext pattern; private Set<String> disabledScriptsAsSet; private ModuleNode module; private JDTResolver resolver; public void setResolverInformation(ModuleNode module, JDTResolver resolver) { this.module = module; this.resolver = resolver; } public void initialize(GroovyCompilationUnit unit, VariableScope topLevelScope) { if (!GroovyDSLCoreActivator.getDefault().isDSLDDisabled()) { // run referesh dependencies synchronously if DSLD store doesn't exist yet contextStoreManager.ensureInitialized(unit.getJavaProject().getProject(), true); } disabledScriptsAsSet = DSLPreferences.getDisabledScriptsAsSet(); try { pattern = new GroovyDSLDContext(unit, module, resolver); pattern.setCurrentScope(topLevelScope); } catch (CoreException e) { GroovyDSLCoreActivator.logException(e); } store = contextStoreManager.getDSLDStore(unit.getJavaProject()); store = store.createSubStore(pattern); } // FIXADE Should shortcut if we find a solution earlier. @Override protected TypeAndDeclaration lookupTypeAndDeclaration(ClassNode declaringType, String name, VariableScope scope) { pattern.setCurrentScope(scope); pattern.setTargetType(declaringType); pattern.setStatic(isStatic()); List<IContributionElement> elts = store.findContributions(pattern, disabledScriptsAsSet); declaringType = pattern.getCurrentType(); // may have changed via a setDelegateType for (IContributionElement elt : elts) { TypeAndDeclaration td = elt.lookupType(name, declaringType, pattern.getResolverCache()); if (td != null) { return td; } } return null; } /** * setDelegateType must be called even for empty block statements */ @Override public void lookupInBlock(BlockStatement node, VariableScope scope) { pattern.setCurrentScope(scope); ClassNode delegateOrThis = scope.getDelegateOrThis(); if (delegateOrThis != null) { pattern.setTargetType(delegateOrThis); pattern.setStatic(isStatic()); store.findContributions(pattern, disabledScriptsAsSet); } // no need to return anything. setDelegateType is called and evaluated implicitly } @Override protected TypeConfidence confidence() { return TypeConfidence.INFERRED; } /* * Checks explicitly if the confidence decision should be made later. */ @Override protected TypeConfidence checkConfidence(Expression node, TypeConfidence originalConfidence, ASTNode declaration, String extraDoc) { TypeConfidence confidence = originalConfidence == null ? confidence() : originalConfidence; if (declaration instanceof MethodNode && extraDoc != null && extraDoc.contains(GORM_SIGNATURE)) { // Give a chance for TypeLookups called later confidence = TypeConfidence.LOOSELY_INFERRED; } return confidence; } }