/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.tvl.goworks.editor.go.semantics; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.logging.Level; import org.antlr.v4.runtime.tree.TerminalNode; import org.antlr.works.editor.antlr4.classification.DocumentSnapshotToken; import org.tvl.goworks.editor.go.codemodel.CodeElementModel; import org.tvl.goworks.editor.go.codemodel.CodeElementPositionRegion; import org.tvl.goworks.editor.go.codemodel.PackageModel; import org.tvl.goworks.editor.go.codemodel.impl.TypeModelImpl; import org.tvl.goworks.editor.go.codemodel.impl.TypePointerModelImpl; /** * * @author Sam Harwell */ public class ReceiverTypeReference extends CodeElementReference { private final TerminalNode name; private final boolean pointer; public ReceiverTypeReference(TerminalNode name, boolean pointer) { this.name = name; this.pointer = pointer; } @Override public Collection<? extends CodeElementModel> resolve(GoAnnotatedParseTree annotatedParseTree, PackageModel currentPackage, Map<String, Collection<PackageModel>> resolvedPackages) { TerminalNode localTarget = annotatedParseTree.getTreeDecorator().getProperty(name, GoAnnotations.LOCAL_TARGET); Collection<? extends CodeElementModel> types = currentPackage.getTypes(name.getText()); if (localTarget == null) { return types; } if (localTarget.getSymbol() instanceof DocumentSnapshotToken) { DocumentSnapshotToken snapshotToken = (DocumentSnapshotToken)localTarget.getSymbol(); boolean foundCurrentDefinition = false; boolean foundCurrentFile = false; for (CodeElementModel model : types) { CodeElementPositionRegion seek = model.getSeek(); if (seek == null) { continue; } if (!seek.getFileObject().equals(snapshotToken.getSnapshot().getVersionedDocument().getFileObject())) { continue; } foundCurrentFile = true; foundCurrentDefinition |= seek.getOffsetRegion().getStart() == localTarget.getSymbol().getStartIndex(); if (foundCurrentDefinition) { break; } } if (!foundCurrentDefinition) { String reason; if (foundCurrentFile) { reason = "Cached type appears to be out-of-date."; } else { reason = "Type not found in cache."; } LOGGER.log(Level.WARNING, "Unable to verify receiver type for local target type '{0}'. {1}", new Object[] { localTarget.getText(), reason }); } } else if (localTarget != null) { LOGGER.log(Level.WARNING, "Unable to verify receiver type for local target from token class {0}.", localTarget.getClass()); } if (!pointer) { return types; } List<CodeElementModel> pointerTypes = new ArrayList<>(); for (CodeElementModel model : types) { if (!(model instanceof TypeModelImpl)) { continue; } TypeModelImpl typeModel = (TypeModelImpl)model; pointerTypes.add(new TypePointerModelImpl(typeModel)); } return pointerTypes; } }