public Expression transformVariableExpression(VariableExpression expr) { // we need to transform variable expressions that go to a delegate // to a property expression, as ACG would loose the information // in processClassVariable before it reaches any makeCall, that could // handle it Object val = expr.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER); if (val == null) return expr; VariableExpression implicitThis = new VariableExpression("this"); // GRECLIPSE start // Expressions positions should be added to make it possible to recognize correct AST nodes // later ConstantExpression ce = new ConstantExpression(expr.getName()); ce.setStart(expr.getStart()); ce.setEnd(expr.getEnd()); PropertyExpression pexp = new PropertyExpression(implicitThis, ce); pexp.setStart(expr.getStart()); pexp.setEnd(expr.getEnd()); // GRECLIPSE end pexp.copyNodeMetaData(expr); pexp.setImplicitThis(true); ClassNode owner = expr.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER); if (owner != null) { implicitThis.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, owner); implicitThis.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, val); } return pexp; }
public void visitVariableExpression(VariableExpression expression) { String name = expression.getName(); Variable v = checkVariableNameForDeclaration(name, expression); if (v == null) return; expression.setAccessedVariable(v); checkVariableContextAccess(v, expression); }
private List<PropertyNode> findTags(ClassNode classNode) { List<PropertyNode> tags = new ArrayList<PropertyNode>(); List<PropertyNode> properties = classNode.getProperties(); List<PropertyNode> potentialAliases = new ArrayList<PropertyNode>(); for (PropertyNode property : properties) { if (property.isPublic()) { Expression initialExpression = property.getInitialExpression(); if (initialExpression instanceof ClosureExpression) { ClosureExpression ce = (ClosureExpression) initialExpression; Parameter[] parameters = ce.getParameters(); if (parameters.length <= 2) { tags.add(property); // force Closure type for DefaultGrailsTagLibClass property.setType(CLOSURE_CLASS_NODE); } } else if (initialExpression instanceof VariableExpression) { potentialAliases.add(property); } } } for (PropertyNode potentialAlias : potentialAliases) { VariableExpression pe = (VariableExpression) potentialAlias.getInitialExpression(); String propertyName = pe.getName(); PropertyNode property = classNode.getProperty(propertyName); if (property != null && tags.contains(property)) { potentialAlias.setType(CLOSURE_CLASS_NODE); tags.add(potentialAlias); } } return tags; }
// Return false if the inference is illegal. Currently this only happens if the var is reassigned // to incompatible // type inside the loop. public boolean add(VariableExpression ve, ClassNode type) { if (defVars == null) defVars = FHashMap.emptyMap; if (ve.getAccessedVariable() != null) { defVars = defVars.put(ve.getAccessedVariable(), type); // dumpMap(ve); } else { boolean done = false; for (Map.Entry<Variable, ClassNode> variable : defVars.entrySet()) { if (variable.getKey().getName().equals(ve.getName())) { defVars = defVars.put(variable.getKey(), type); // dumpMap(ve); done = true; break; } } if (!done) { defVars = defVars.put(ve, type); // dumpMap(ve); } } if (parentScopeInference != null && parentScopeInference.defVars != null) { final ClassNode oldType = parentScopeInference.defVars.get(ve.getAccessedVariable()); if (oldType != null) { if (!TypeUtil.isDirectlyAssignableFrom(oldType, type)) { return false; } } } return true; }
private ClassNode getConstructorArgumentType(Expression arg, ConstructorNode node) { if (!(arg instanceof VariableExpression)) return arg.getType(); VariableExpression vexp = (VariableExpression) arg; String name = vexp.getName(); for (Parameter param : node.getParameters()) { if (param.getName().equals(name)) { return param.getType(); } } return vexp.getType(); }
/** * a property on "this", like this.x is transformed to a direct field access, so we need to check * the static context here * * @param pe the property expression to check */ private void checkPropertyOnExplicitThis(PropertyExpression pe) { if (!currentScope.isInStaticContext()) return; Expression object = pe.getObjectExpression(); if (!(object instanceof VariableExpression)) return; VariableExpression ve = (VariableExpression) object; if (!ve.getName().equals("this")) return; String name = pe.getPropertyAsString(); if (name == null || name.equals("class")) return; Variable member = findClassMember(currentClass, name); if (member == null) return; checkVariableContextAccess(member, pe); }
private void dumpMap(VariableExpression ve) { System.out.print(ve.getName()); System.out.print(" "); System.out.print(defVars.size()); System.out.print(" "); for (Map.Entry<Variable, ClassNode> variable : defVars.entrySet()) { System.out.print(variable.getKey().getName()); System.out.print("->"); System.out.print(variable.getValue().getNameWithoutPackage()); System.out.print(","); } System.out.println(); }
public ClassNode get(VariableExpression ve) { if (defVars == null) return ClassHelper.OBJECT_TYPE; else { final Variable accessed = ve.getAccessedVariable(); if (accessed != null) return defVars.get(accessed); else { for (Map.Entry<Variable, ClassNode> variable : defVars.entrySet()) { if (variable.getKey().getName().equals(ve.getName())) { return variable.getValue(); } } return null; } } }
private boolean isThisTraitReceiver(final VariableExpression var) { return Traits.THIS_OBJECT.equals(var.getName()); }
private boolean isStaticTraitReceiver(final ClassNode receiver, final VariableExpression var) { return Traits.STATIC_THIS_OBJECT.equals(var.getName()) && isClassClassNodeWrappingConcreteType(receiver); }
@Override public List<ICompletionProposal> computeCompletionProposals( final ContentAssistInvocationContext context, final IProgressMonitor monitor) { final List<ICompletionProposal> list = new ArrayList<ICompletionProposal>(); boolean extendContext = false; try { if (context instanceof JavaContentAssistInvocationContext) { final ITextViewer viewer = context.getViewer(); final List<ScriptVariable> scriptVariables = getScriptVariables(viewer); if (scriptVariables.isEmpty()) { return list; } final CompletionContext coreContext = ((JavaContentAssistInvocationContext) context).getCoreContext(); if (coreContext != null && !coreContext.isExtended()) { // must use reflection to set the fields ReflectionUtils.setPrivateField( InternalCompletionContext.class, "isExtended", coreContext, true); extendContext = true; } final ICompilationUnit unit = ((JavaContentAssistInvocationContext) context).getCompilationUnit(); if (unit instanceof GroovyCompilationUnit) { if (((GroovyCompilationUnit) unit).getModuleNode() == null) { return Collections.emptyList(); } final ContentAssistContext assistContext = new GroovyCompletionProposalComputer() .createContentAssistContext( (GroovyCompilationUnit) unit, context.getInvocationOffset(), context.getDocument()); CharSequence prefix = null; try { prefix = context.computeIdentifierPrefix(); } catch (final BadLocationException e) { BonitaStudioLog.error(e); } if (assistContext != null && assistContext.completionNode instanceof VariableExpression) { try { final VariableExpression expr = (VariableExpression) assistContext.completionNode; if (scriptVariables != null) { for (final ScriptVariable f : scriptVariables) { if (expr.getName().equals(f.getName())) { final IType type = javaProject.findType(f.getType()); if (type == null) { return list; } for (final IMethod m : type.getMethods()) { if (m.getElementName().startsWith(prefix.toString())) { final GroovyCompletionProposal proposal = new GroovyCompletionProposal( CompletionProposal.METHOD_REF, context.getInvocationOffset()); proposal.setName(m.getElementName().toCharArray()); proposal.setCompletion( m.getElementName().substring(prefix.length()).toCharArray()); proposal.setFlags(m.getFlags()); if (prefix.length() == m.getElementName().length()) { proposal.setReplaceRange( context.getInvocationOffset(), context.getInvocationOffset()); proposal.setReceiverRange(0, 0); } else { proposal.setReplaceRange( context.getInvocationOffset() - prefix.length(), context.getInvocationOffset()); proposal.setReceiverRange(prefix.length(), prefix.length()); } final char[][] parametersArray = new char[m.getParameterNames().length][256]; final List<Parameter> parameters = new ArrayList<Parameter>(); for (int i = 0; i < m.getParameterNames().length; i++) { parametersArray[i] = m.getParameterNames()[i].toCharArray(); parameters.add( new Parameter( ClassHelper.make( Signature.getSignatureSimpleName(m.getParameterTypes()[i])), m.getParameterNames()[i])); } final ClassNode classNode = ClassHelper.make(m.getDeclaringType().getFullyQualifiedName()); proposal.setDeclarationSignature( ProposalUtils.createTypeSignature(classNode)); proposal.setParameterNames(parametersArray); if (m.getDeclaringType().getFullyQualifiedName().equals(f.getType())) { proposal.setRelevance(100); } final MethodNode methodNode = new MethodNode( m.getElementName(), m.getFlags(), ClassHelper.make( Signature.getSignatureSimpleName(m.getReturnType())), parameters.toArray(new Parameter[parameters.size()]), new ClassNode[0], null); final char[] methodSignature = ProposalUtils.createMethodSignature(methodNode); proposal.setSignature(methodSignature); final GroovyJavaGuessingCompletionProposal groovyProposal = GroovyJavaGuessingCompletionProposal.createProposal( proposal, (JavaContentAssistInvocationContext) context, true, "Groovy", ProposalFormattingOptions.newFromOptions()); if (groovyProposal != null) { list.add(groovyProposal); } } } } } } } catch (final JavaModelException e) { BonitaStudioLog.error(e); } } } return list; } } finally { final CompletionContext coreContext = ((JavaContentAssistInvocationContext) context).getCoreContext(); if (extendContext && coreContext != null && coreContext.isExtended()) { // must use reflection to set the fields ReflectionUtils.setPrivateField( InternalCompletionContext.class, "isExtended", coreContext, false); } } return Collections.emptyList(); }
protected Expression transformMethodCallExpression(MethodCallExpression mce) { Expression args = transform(mce.getArguments()); Expression method = transform(mce.getMethod()); Expression object = transform(mce.getObjectExpression()); boolean isExplicitThisOrSuper = false; if (object instanceof VariableExpression) { VariableExpression ve = (VariableExpression) object; isExplicitThisOrSuper = !mce.isImplicitThis() && (ve.getName().equals("this") || ve.getName().equals("super")); } if (mce.isImplicitThis() || isExplicitThisOrSuper) { if (mce.isImplicitThis()) { Expression ret = findStaticMethodImportFromModule(method, args); if (ret != null) { // GRECLIPSE add if (!((StaticMethodCallExpression) ret).getMethod().equals(method.getText())) { // store the identifier to facilitate organizing static imports ret.setNodeMetaData("static.import.alias", method.getText()); } // GRECLIPSE end setSourcePosition(ret, mce); return ret; } if (method instanceof ConstantExpression && !inLeftExpression) { // could be a closure field String methodName = (String) ((ConstantExpression) method).getValue(); ret = findStaticFieldOrPropAccessorImportFromModule(methodName); if (ret != null) { ret = new MethodCallExpression(ret, "call", args); setSourcePosition(ret, mce); return ret; } } } if (method instanceof ConstantExpression) { ConstantExpression ce = (ConstantExpression) method; Object value = ce.getValue(); if (value instanceof String) { String methodName = (String) value; boolean lookForPossibleStaticMethod = !methodName.equals("call"); if (currentMethod != null && !currentMethod.isStatic()) { if (currentClass.hasPossibleMethod(methodName, args)) { lookForPossibleStaticMethod = false; } } if (inSpecialConstructorCall || (lookForPossibleStaticMethod && currentClass.hasPossibleStaticMethod(methodName, args))) { StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass, methodName, args); setSourcePosition(smce, mce); return smce; } } } } MethodCallExpression result = new MethodCallExpression(object, method, args); result.setSafe(mce.isSafe()); result.setImplicitThis(mce.isImplicitThis()); result.setSpreadSafe(mce.isSpreadSafe()); result.setMethodTarget(mce.getMethodTarget()); // GROOVY-6757 result.setGenericsTypes(mce.getGenericsTypes()); setSourcePosition(result, mce); return result; }