static TypeBinding getFirstParameterType(TypeDeclaration decl, CompletionProposalCollector completionProposalCollector) { TypeBinding firstParameterType = null; ASTNode node = getAssistNode(completionProposalCollector); if (node == null) return null; if (!(node instanceof CompletionOnQualifiedNameReference) && !(node instanceof CompletionOnSingleNameReference) && !(node instanceof CompletionOnMemberAccess)) return null; // Never offer on 'super.<autocomplete>'. if (node instanceof FieldReference && ((FieldReference)node).receiver instanceof SuperReference) return null; if (node instanceof NameReference) { Binding binding = ((NameReference) node).binding; // Unremark next block to allow a 'blank' autocomplete to list any extensions that apply to the current scope, but make sure we're not in a static context first, which this doesn't do. // Lacking good use cases, and having this particular concept be a little tricky on javac, means for now we don't support extension methods like this. this.X() will be fine, though. /* if ((node instanceof SingleNameReference) && (((SingleNameReference) node).token.length == 0)) { firstParameterType = decl.binding; } else */if (binding instanceof VariableBinding) { firstParameterType = ((VariableBinding) binding).type; } } else if (node instanceof FieldReference) { firstParameterType = ((FieldReference) node).actualReceiverType; } return firstParameterType; }
private static NameReference createNameRef(TypeBinding typeBinding, ASTNode source) { long p = ((long) source.sourceStart << 32) | source.sourceEnd; char[] pkg = typeBinding.qualifiedPackageName(); char[] basename = typeBinding.qualifiedSourceName(); StringBuilder sb = new StringBuilder(); if (pkg != null) sb.append(pkg); if (sb.length() > 0) sb.append("."); sb.append(basename); String tName = sb.toString(); if (tName.indexOf('.') == -1) { return new SingleNameReference(basename, p); } else { char[][] sources; String[] in = tName.split("\\."); sources = new char[in.length][]; for (int i = 0; i < in.length; i++) sources[i] = in[i].toCharArray(); long[] poss = new long[in.length]; Arrays.fill(poss, p); return new QualifiedNameReference(sources, poss, source.sourceStart, source.sourceEnd); } }
public void unqualifiedFieldAccess(NameReference reference, FieldBinding field) { int sourceStart = reference.sourceStart; int sourceEnd = reference.sourceEnd; if (reference instanceof SingleNameReference) { int numberOfParens = (reference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; if (numberOfParens != 0) { sourceStart = retrieveStartingPositionAfterOpeningParenthesis(sourceStart, sourceEnd, numberOfParens); sourceEnd = retrieveEndingPositionAfterOpeningParenthesis(sourceStart, sourceEnd, numberOfParens); } else { sourceStart = nodeSourceStart(field, reference); sourceEnd = nodeSourceEnd(field, reference); } } else { sourceStart = nodeSourceStart(field, reference); sourceEnd = nodeSourceEnd(field, reference); } this.handle( IProblem.UnqualifiedFieldAccess, new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, sourceStart, sourceEnd); }
public static NameReference createNameReference(String name, Annotation source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; char[][] nameTokens = fromQualifiedName(name); long[] pos = new long[nameTokens.length]; Arrays.fill(pos, p); QualifiedNameReference nameReference = new QualifiedNameReference(nameTokens, pos, pS, pE); nameReference.statementEnd = pE; setGeneratedBy(nameReference, source); return nameReference; }
@Override @Nullable public ResolvedNode resolve(@NonNull JavaContext context, @NonNull Node node) { Object nativeNode = getNativeNode(node); if (nativeNode == null) { return null; } if (nativeNode instanceof NameReference) { return resolve(((NameReference) nativeNode).binding); } else if (nativeNode instanceof TypeReference) { return resolve(((TypeReference) nativeNode).resolvedType); } else if (nativeNode instanceof MessageSend) { return resolve(((MessageSend) nativeNode).binding); } else if (nativeNode instanceof AllocationExpression) { return resolve(((AllocationExpression) nativeNode).binding); } else if (nativeNode instanceof TypeDeclaration) { return resolve(((TypeDeclaration) nativeNode).binding); } else if (nativeNode instanceof ExplicitConstructorCall) { return resolve(((ExplicitConstructorCall) nativeNode).binding); } else if (nativeNode instanceof Annotation) { return resolve(((Annotation) nativeNode).resolvedType); } else if (nativeNode instanceof AbstractMethodDeclaration) { return resolve(((AbstractMethodDeclaration) nativeNode).binding); } else if (nativeNode instanceof AbstractVariableDeclaration) { if (nativeNode instanceof LocalDeclaration) { return resolve(((LocalDeclaration) nativeNode).binding); } else if (nativeNode instanceof FieldDeclaration) { return resolve(((FieldDeclaration) nativeNode).binding); } } // TODO: Handle org.eclipse.jdt.internal.compiler.ast.SuperReference. It // doesn't contain an actual method binding; the parent node call should contain // it, but is missing a native node reference; investigate the ECJ bridge's super // handling. return null; }
protected NameReference getUnspecifiedReferenceOptimized() { int index = indexOfAssistIdentifier(); NameReference reference = super.getUnspecifiedReferenceOptimized(); if (index >= 0){ if (!this.diet){ this.restartRecovery = true; // force to restart in recovery mode this.lastIgnoredToken = -1; } this.isOrphanCompletionNode = true; } return reference; }
public Name convert(org.eclipse.jdt.internal.compiler.ast.NameReference reference) { if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) { return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) reference); } else { return convert((org.eclipse.jdt.internal.compiler.ast.SingleNameReference) reference); } }
public Expression convert(org.eclipse.jdt.internal.compiler.ast.Reference reference) { if (reference instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) { return convert((org.eclipse.jdt.internal.compiler.ast.NameReference) reference); } if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ThisReference) { return convert((org.eclipse.jdt.internal.compiler.ast.ThisReference) reference); } if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ArrayReference) { return convert((org.eclipse.jdt.internal.compiler.ast.ArrayReference) reference); } if (reference instanceof org.eclipse.jdt.internal.compiler.ast.FieldReference) { return convert((org.eclipse.jdt.internal.compiler.ast.FieldReference) reference); } return null; // cannot be reached }
protected void consumeExplicitThisParameter(boolean isQualified) { // VariableDeclaratorIdOrThis ::= 'this' // VariableDeclaratorIdOrThis ::= UnannotatableName '.' 'this' // VariableDeclaratorIdOrThis ::= VariableDeclaratorId NameReference qualifyingNameReference = null; if (isQualified) { qualifyingNameReference = getUnspecifiedReference(false); // By construction the qualified name is unannotated here, so we should not meddle with the type annotation stack } pushOnExpressionStack(qualifyingNameReference); int thisStart = this.intStack[this.intPtr--]; pushIdentifier(ConstantPool.This, (((long) thisStart << 32)) + (thisStart + 3)); pushOnIntStack(0); // extended dimensions ... pushOnIntStack(0); // signal explicit this }
public void duplicateTargetInTargetAnnotation(TypeBinding annotationType, NameReference reference) { FieldBinding field = reference.fieldBinding(); String name = new String(field.name); this.handle( IProblem.DuplicateTargetInTargetAnnotation, new String[] { name, new String(annotationType.readableName())}, new String[] { name, new String(annotationType.shortReadableName())}, nodeSourceStart(field, reference), nodeSourceEnd(field, reference)); }
/** * Calculates the beginning position of a given {@link ASTNode} * @param node * @return */ protected int getNodeBegin(ASTNode node) { if (node instanceof NameReference) { return ((NameReference) node).sourceStart; } else if (node instanceof FieldReference) { return ((FieldReference) node).receiver.sourceStart; } else if (node instanceof MessageSend) { return ((MessageSend) node).receiver.sourceStart; } return node.sourceStart; }
protected Binding resolveNodeToBinding(ASTNode node) { if (node instanceof NameReference) { NameReference nr = (NameReference) node; if (nr.binding instanceof VariableBinding) { VariableBinding vb = (VariableBinding) nr.binding; return vb.type; } } else if (node instanceof FieldReference) { FieldReference fr = (FieldReference) node; return fr.receiver.resolvedType; } return null; }
@Override public void endVisit(CastExpression x, BlockScope scope) { try { SourceInfo info = makeSourceInfo(x); JType type = typeMap.get(x.resolvedType); JExpression expression = pop(x.expression); if (x.type instanceof NameReference) { pop(x.type); } push(new JCastOperation(info, type, expression)); } catch (Throwable e) { throw translateException(x, e); } }
static Expression createFieldAccessor(String field, ASTNode source, char[] receiver) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; char[][] tokens = new char[2][]; tokens[0] = receiver; tokens[1] = field.toCharArray(); long[] poss = {p, p}; NameReference ref = new QualifiedNameReference(tokens, poss, pS, pE); setGeneratedBy(ref, source); return ref; }
static NameReference createNameReference(String name, Annotation source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; char[][] nameTokens = fromQualifiedName(name); long[] pos = new long[nameTokens.length]; Arrays.fill(pos, p); QualifiedNameReference nameReference = new QualifiedNameReference(nameTokens, pos, pS, pE); nameReference.statementEnd = pE; setGeneratedBy(nameReference, source); return nameReference; }
static MethodDeclaration createSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, boolean shouldReturnThis, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); ASTNode source = sourceNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; MethodDeclaration method = new MethodDeclaration(parent.compilationResult); method.modifiers = modifier; if (shouldReturnThis) { method.returnType = cloneSelfType(fieldNode, source); } if (method.returnType == null) { method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); method.returnType.sourceStart = pS; method.returnType.sourceEnd = pE; shouldReturnThis = false; } Annotation[] deprecated = null; if (isFieldDeprecated(fieldNode)) { deprecated = new Annotation[] { generateDeprecatedAnnotation(source) }; } method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated); Argument param = new Argument(field.name, p, copyType(field.type, source), Modifier.FINAL); param.sourceStart = pS; param.sourceEnd = pE; method.arguments = new Argument[] { param }; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source); NameReference fieldNameRef = new SingleNameReference(field.name, p); Assignment assignment = new Assignment(fieldRef, fieldNameRef, (int)p); assignment.sourceStart = pS; assignment.sourceEnd = assignment.statementEnd = pE; method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); List<Statement> statements = new ArrayList<Statement>(5); if (nonNulls.length == 0) { statements.add(assignment); } else { Statement nullCheck = generateNullCheck(field, sourceNode); if (nullCheck != null) statements.add(nullCheck); statements.add(assignment); } if (shouldReturnThis) { ThisReference thisRef = new ThisReference(pS, pE); ReturnStatement returnThis = new ReturnStatement(thisRef, pS, pE); statements.add(returnThis); } method.statements = statements.toArray(new Statement[0]); param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; }
public NameReference createQualifiedAssistNameReference(char[][] previousIdentifiers, char[] assistName, long[] positions){ return new SelectionOnQualifiedNameReference( previousIdentifiers, assistName, positions); }
public NameReference createSingleAssistNameReference(char[] assistName, long position) { return new SelectionOnSingleNameReference(assistName, position); }
protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) { /* build a (unspecified) NameReference which may be qualified*/ int completionIndex; /* no need to take action if not inside completed identifiers */ if ((completionIndex = indexOfAssistIdentifier()) < 0) { return super.getUnspecifiedReference(rejectTypeAnnotations); } if (rejectTypeAnnotations) { consumeNonTypeUseName(); } int length = this.identifierLengthStack[this.identifierLengthPtr]; if (CharOperation.equals(assistIdentifier(), SUPER)){ Reference reference; if (completionIndex > 0){ // qualified super // discard 'super' from identifier stacks // There is some voodoo going on here in combination with SelectionScanne#scanIdentifierOrKeyword, do in Rome as Romans do and leave the stacks at the right depth. this.identifierLengthStack[this.identifierLengthPtr] = completionIndex; int ptr = this.identifierPtr -= (length - completionIndex); pushOnGenericsLengthStack(0); pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); for (int i = 0; i < completionIndex; i++) { pushOnTypeAnnotationLengthStack(0); } reference = new SelectionOnQualifiedSuperReference( getTypeReference(0), (int)(this.identifierPositionStack[ptr+1] >>> 32), (int) this.identifierPositionStack[ptr+1]); } else { // standard super this.identifierPtr -= length; this.identifierLengthPtr--; reference = new SelectionOnSuperReference((int)(this.identifierPositionStack[this.identifierPtr+1] >>> 32), (int) this.identifierPositionStack[this.identifierPtr+1]); } pushOnAstStack(reference); this.assistNode = reference; this.lastCheckPoint = reference.sourceEnd + 1; if (!this.diet || this.dietInt != 0){ this.restartRecovery = true; // force to restart in recovery mode this.lastIgnoredToken = -1; } this.isOrphanCompletionNode = true; return new SingleNameReference(CharOperation.NO_CHAR, 0); // dummy reference } NameReference nameReference; /* retrieve identifiers subset and whole positions, the completion node positions should include the entire replaced source. */ char[][] subset = identifierSubSet(completionIndex); this.identifierLengthPtr--; this.identifierPtr -= length; long[] positions = new long[length]; System.arraycopy( this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); /* build specific completion on name reference */ if (completionIndex == 0) { /* completion inside first identifier */ nameReference = createSingleAssistNameReference(assistIdentifier(), positions[0]); } else { /* completion inside subsequent identifier */ nameReference = createQualifiedAssistNameReference(subset, assistIdentifier(), positions); } this.assistNode = nameReference; this.lastCheckPoint = nameReference.sourceEnd + 1; if (!this.diet){ this.restartRecovery = true; // force to restart in recovery mode this.lastIgnoredToken = -1; } this.isOrphanCompletionNode = true; return nameReference; }
protected NameReference getUnspecifiedReferenceOptimized() { int completionIndex; /* no need to take action if not inside completed identifiers */ if ((completionIndex = indexOfAssistIdentifier()) < 0) { return super.getUnspecifiedReferenceOptimized(); } consumeNonTypeUseName(); /* retrieve identifiers subset and whole positions, the completion node positions should include the entire replaced source. */ int length = this.identifierLengthStack[this.identifierLengthPtr]; char[][] subset = identifierSubSet(completionIndex); this.identifierLengthPtr--; this.identifierPtr -= length; long[] positions = new long[length]; System.arraycopy( this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); /* build specific completion on name reference */ NameReference reference; if (completionIndex == 0) { /* completion inside first identifier */ reference = createSingleAssistNameReference(assistIdentifier(), positions[0]); } else { /* completion inside subsequent identifier */ reference = createQualifiedAssistNameReference(subset, assistIdentifier(), positions); } reference.bits &= ~ASTNode.RestrictiveFlagMASK; reference.bits |= Binding.LOCAL | Binding.FIELD; this.assistNode = reference; this.lastCheckPoint = reference.sourceEnd + 1; return reference; }
/** * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.BlockScope) */ public boolean visit(Argument argument, BlockScope scope) { if (argument.modifiers != NO_MODIFIERS || argument.annotations != null) { this.scribe.printComment(); this.scribe.printModifiers(argument.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_PARAMETER, !hasNonAnnotationModifiers()); this.scribe.space(); } /* * Argument type */ TypeReference argumentType = argument.type; if (argumentType != null) { if (argumentType instanceof UnionTypeReference) { formatMultiCatchArguments( argument, this.preferences.insert_space_before_binary_operator, this.preferences.insert_space_after_binary_operator, this.preferences.alignment_for_union_type_in_multicatch, scope); } else { argumentType.traverse(this, scope); } } if (argument.isVarArgs()) { Annotation [][] annotationsOnDimensions = argumentType.getAnnotationsOnDimensions(true); if (annotationsOnDimensions != null) { Annotation [] varargAnnotations = annotationsOnDimensions[annotationsOnDimensions.length - 1]; if (varargAnnotations != null) { formatInlineAnnotations(varargAnnotations, true); } } this.scribe.printNextToken(TerminalTokens.TokenNameELLIPSIS, this.preferences.insert_space_before_ellipsis); if (this.preferences.insert_space_after_ellipsis) { this.scribe.space(); } this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); } else { if (argument.isReceiver()) { this.scribe.space(); NameReference qualifyingName = ((Receiver) argument).qualifyingName; if (qualifyingName != null) { qualifyingName.traverse(this, scope); this.scribe.printNextToken(TerminalTokens.TokenNameDOT, false); } this.scribe.printNextToken(TerminalTokens.TokenNamethis, false); } else { /* * Print the argument name */ this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, argument.type != null); } } formatExtraDimensions(argumentType); return false; }
protected NameReference getUnspecifiedReference() { return getUnspecifiedReference(true); }
private JExpression resolveNameReference(NameReference x, BlockScope scope) { SourceInfo info = makeSourceInfo(x); if (x.constant != Constant.NotAConstant) { return getConstant(info, x.constant); } Binding binding = x.binding; JExpression result = null; if (binding instanceof LocalVariableBinding) { LocalVariableBinding b = (LocalVariableBinding) binding; if ((x.bits & ASTNode.DepthMASK) != 0) { VariableBinding[] path = scope.getEmulationPath(b); if (path == null) { /* * Don't like this, but in rare cases (e.g. the variable is only * ever used as an unnecessary qualifier) JDT provides no emulation * to the desired variable. */ // throw new InternalCompilerException("No emulation path."); return null; } assert path.length == 1; if (curMethod.scope.isInsideInitializer() && path[0] instanceof SyntheticArgumentBinding) { SyntheticArgumentBinding sb = (SyntheticArgumentBinding) path[0]; JField field = curClass.syntheticFields.get(sb); assert field != null; result = makeInstanceFieldRef(info, field); } else if (path[0] instanceof LocalVariableBinding) { result = makeLocalRef(info, (LocalVariableBinding) path[0]); } else if (path[0] instanceof FieldBinding) { FieldBinding fb = (FieldBinding) path[0]; assert curClass.typeDecl.binding.isCompatibleWith(x.actualReceiverType.erasure()); JField field = typeMap.get(fb); assert field != null; result = makeInstanceFieldRef(info, field); } else { throw new InternalCompilerException("Unknown emulation path."); } } else { result = makeLocalRef(info, b); } } else if (binding instanceof FieldBinding) { FieldBinding b = ((FieldBinding) x.binding).original(); JField field = typeMap.get(b); assert field != null; JExpression thisRef = null; if (!b.isStatic()) { thisRef = makeThisReference(info, (ReferenceBinding) x.actualReceiverType, false, scope); } result = new JFieldRef(info, thisRef, field, curClass.type); } else { return null; } assert result != null; return result; }
public abstract NameReference createQualifiedAssistNameReference(char[][] previousIdentifiers, char[] assistName, long[] positions);
public abstract NameReference createSingleAssistNameReference(char[] assistName, long position);