eQuantic.UIeQuantic.UI
Docs
Playground
GitHub
DocsCompilação
Diagnósticos
Editar esta página
27 min de leitura
Todo erro e aviso de build que o eqc pode imprimir, com o que significa e o que fazer. Os códigos são estáveis: são por eles que você busca, e são eles que uma supressão nomeia.
Esta página vem da mesma referência que o repositório confere: docs/DIAGNOSTICS.md, mantida contra o compilador por DiagnosticsDocumentedTests. Um código que o compilador — ou um target MSBuild do próprio SDK — levanta e não tem linha aqui quebra a build, assim como uma linha que nomeia um código que não existe mais — e assim também um código que ganha um novo ponto de emissão, o que não é regra de estilo: o EQ2101 já foi dois erros sem relação (um template resx divergente e System.IO num componente cliente), cada um fixado pelo seu próprio teste verde, porque os dois nunca se encontravam numa mesma compilação.
Os diagnósticos saem no formato canônico do MSBuild, então a IDE e o dotnet build linkam ambos:
1
Pages/Counter.cs(14,9): error EQ2002: C# 'goto' cannot be transpiled to JavaScript …
EQ0xxx — o host de build
O próprio processo eqc, antes ou em volta de uma compilação.
Código
Significado
O que fazer
EQ0000
Um erro de compilação chegou sem código próprio.
Leia a mensagem — o que falta é o código, não o diagnóstico.
EQ0001
O eqc quebrou.
É bug do compilador. A mensagem traz a exceção; reporte com o fonte que a provocou. Um caso não é do compilador: os projetos que o app referencia não puderam ser lidos do fonte, porque a lista que o SDK escreveu para o build não está lá ou não tem nenhum projeto, ou um assembly ou um projeto que ela cita não está lá. A mensagem diz o que não se sustentou, e o build para ali, porque seguir escreveria uma página que cita tipos que nada importa (Desde 0.2.0-preview.62). Faça o build de novo, e reporte se continuar.
EQ0002
A lista de referências do MSBuild está vazia, então o modelo semântico viria de uma compilação incompleta e argumentos nomeados poderiam sair na ordem errada.
Reconstrua (dotnet build). Se persistir, o alvo CompileEQuanticUI rodou sem FindReferenceAssembliesForReferences.
EQ1xxx — a tradução ainda não existe
Uma lacuna do compilador, não do seu código. O construto é C# legal e poderia ser traduzido; hoje nada o faz. São os códigos que encolhem conforme o compilador cresce.
Código
Significado
O que fazer
EQ1001
Um tipo de expressão C# sem estratégia de transpilação.
Reescreva numa forma transpilável, ou adicione uma estratégia de conversão para o construto.
EQ1002
Um tipo de statement C# sem estratégia.
Idem.
EQ1003
Um nó C# (nem expressão nem statement) sem estratégia.
Idem.
EQ1004
Uma estratégia casou com o construto, mas esta forma exata não tem emissão — a tradução sairia silenciosamente errada, então ela para.
Reescreva a forma, ou adicione o caso que falta à estratégia.
EQ1005
Dois tipos dividem o mesmo nome de arquivo do twin — o mesmo nome duas vezes, ou dois nomes que diferem só em maiúsculas (um arquivo só no Windows e no macOS). Os twins seriam UM arquivo e o segundo sobrescreveria o primeiro.
Renomeie um dos tipos.
EQ1006
(aviso) Um tipo está declarado em mais de um lugar e o eqc emite um módulo por declaração, então o twin fica só com os membros da primeira.
Junte numa declaração só, ou mantenha juntos os membros que um componente usa. Inofensivo quando as outras metades são server-only, e é por isso que não para a build.
EQ1007
Um nome de método declarado duas vezes num tipo: duas sobrecargas, ou dois nomes que viram um só (Foo e foo). O C# distingue sobrecargas pelos parâmetros, e uma classe JavaScript tem um membro por nome, então o twin ficaria com uma delas e toda chamada chegaria a ela: uma classe, um record ou uma classe estática ficavam com a ÚLTIMA, um componente com a PRIMEIRA, tudo em silêncio. Um método estático e um de instância podem ter o mesmo nome, as duas metades de um método partial são um método só, e uma implementação explícita de interface leva o nome da interface, que nenhuma renomeação muda, então a checagem de sobrecargas a deixa de fora; ao lado de um padrão de outra interface ela leva o nome do seu membro como qualquer membro, e é checada. Dois padrões que uma classe herda de interfaces diferentes, ou um padrão e um membro que a classe declara, caem num nome só do mesmo jeito, e os mesmos pares ao longo da cadeia de classes também: um membro que uma classe derivada declara com o nome de um padrão que a base herda (a menos que ele implemente o membro de interface desse padrão, com a classe listando a interface de novo), um padrão com o nome de um membro que a base declara, e dois padrões de membros de interface diferentes, um herdado pela base e o outro pela derivada. Um indexador leva dois nomes no seu twin, item para o getter e setItem para o setter, então um segundo indexador, ou qualquer membro que o twin guarde nesses nomes (um método, um campo, uma propriedade, um evento, o parâmetro de um construtor primário que um membro lê) cai no mesmo membro, e a mensagem diz o que renomear. Uma implementação explícita do indexador de uma interface guarda item e setItem, que todo acesso pela interface alcança, e o indexador próprio do tipo ao lado dela ganha nomes próprios; o que um acesso por uma interface não consegue distinguir, duas implementações explícitas ou uma ao lado de um indexador ou de um padrão que responde a outra interface, é recusado. Os membros de instância de um record ou de uma struct que caem num mesmo nome também são recusados: o twin guarda o estado de cada instância como propriedades próprias e os seus métodos e propriedades calculadas no protótipo, então dois deles dividiam um lugar (struct S(int x) { public int X { get; } = x * 2; } respondia 6|6 para 3|6) ou o construtor escrevia um por cima do outro (readonly struct Money(decimal amount) { public decimal Amount => amount; } lançava no new). Um membro que o corpo declara com o nome próprio de um parâmetro posicional é a propriedade desse parâmetro, e o parâmetro de um construtor primário lido só por um inicializador não fica em nenhuma instância (Desde 0.2.0-preview.61). Uma classe comum guarda do mesmo jeito o parâmetro do construtor primário que um membro lê, então um que cai no nome de outro membro é recusado: class Greeter(string name) { public string Name => name.ToUpper(); } responderia o parâmetro para Name (Desde 0.2.0-preview.61). Um CAMPO de instância de uma classe comum que difere de outro membro só pela caixa não é recusado: ele vai para um lugar próprio, value$ ao lado de Value, toda leitura e escrita dele chega a esse lugar, e a propriedade, o método ou o evento fica com o nome (Desde 0.2.0-preview.61). Dois parâmetros de um construtor primário que caem num mesmo nome (x ao lado de X) são recusados numa classe, num record e numa struct igualmente: o construtor do twin os nomeia em camelCase, e uma função não aceita dois parâmetros de um mesmo nome (Desde 0.2.0-preview.61). Um método que OCULTA um membro herdado, com new ou com a mesma assinatura e sem override, não é um segundo método: o twin o guarda sob um nome próprio (name$1), e uma chamada ligada ao membro oculto continua chegando a ele, então ele não é recusado; um que oculta um membro e responde a uma interface é, já que uma chamada pela interface chega ao nome do membro oculto (Desde 0.2.0-preview.61). O mesmo vale para um método ao lado de uma implementação explícita de interface do seu nome, que guarda esse nome: um que também responde a outra interface é recusado, já que uma chamada por essa interface chegaria à explícita (Desde 0.2.0-preview.61). O twin de uma sequência tem uma iteração só e um current só, então um tipo que implementa IEnumerable<T>, ou IEnumerator<T>, sobre dois tipos é recusado, já que o LINQ, um spread e um foreach sobre cada um deles percorreriam uma sequência só, e também um GetEnumerator() não genérico ou um Current que o twin guarda como um só com o membro que mantém, quando responde de outro modo, o que o C# permite. Um que devolve o que esse membro responde (IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();, object IEnumerator.Current => Current;) responde igual, e é guardado como um só (Desde 0.2.0-preview.61).
Dê a cada sobrecarga um nome próprio, e mantenha um indexador só (Compare e CompareLines); renomeie o membro de um record ou de uma struct que encontra outro (um campo privado _amount, o parâmetro de um construtor primário pelo que ele guarda), e o parâmetro do construtor primário de uma classe que encontra um membro, ou guarde-o num campo seu (private readonly string _name = name;). Implemente IEnumerable<T> sobre um tipo só e entregue outra sequência por um membro próprio (public IEnumerable<string> Names => …), e devolva de um GetEnumerator() não genérico ou de um Current o que o membro que o twin mantém devolve, por meio dele. A árvore vinculada diz qual sobrecarga cada chamada liga, então esta é uma lacuna que o compilador pode fechar dando nomes distintos às sobrecargas, como já faz com os operadores definidos pelo usuário.
EQ1008
Uma classe depende de um membro padrão de uma interface compilada num assembly referenciado de fora do SDK. O JavaScript não tem interfaces, então o eqc escreve no twin de cada classe os padrões que ela herda: convertidos do código-fonte da interface quando a compilação o tem, e delegados à cópia do runtime para as interfaces do próprio SDK (IAppTheme, ICodeLanguage, ICodeCompletionProvider), as interfaces públicas dos assemblies que o runtime provê. A interface de qualquer outro assembly não tem nem um nem outro, seja qual for o namespace que ela declara, então o twin fica sem esse membro e uma chamada a ele no browser encontraria undefined. O mesmo vale para um padrão que usa um membro estático de uma interface, que não tem forma no JavaScript para guardá-lo.
Declare o membro na classe, ou mantenha a classe fora do código do cliente.
EQ1009
Um construtor de um record, de uma struct ou de uma classe comum que o twin não alcança (o de uma classe comum Desde 0.2.0-preview.61). Uma classe JavaScript tem um construtor só, então o twin toma um ramo por construtor C# pela quantidade de argumentos que chegaram, contando os parâmetros opcionais: cada construtor que faz o próprio trabalho (o primário, ou um explícito que não encadeia com : this(…)) liga os seus parâmetros, define os membros, chama o construtor da base e roda o seu corpo, e cada um que encadeia roda aquele em que encadeia depois de avaliar os argumentos do encadeamento. Um construtor que aceita uma quantidade de argumentos que outro também aceita não se distingue dele, e um que encadeia num construtor que encadeia por sua vez, ou um : this() para o construtor implícito de uma struct ao lado de construtores próprios, não chega ao trabalho por nada. O construtor de cópia de um record (protected R(R original)) não é um ramo: nenhum new o alcança (Desde 0.2.0-preview.61). Nem o construtor que só a serialização do .NET chama, (SerializationInfo, StreamingContext), que o template de exceção do Visual Studio escreve ao lado de (string, Exception): o browser não tem SerializationInfo, e uma classe de exceção da app é uma classe cujos construtores são verificados como os de qualquer classe (Desde 0.2.0-preview.61). Uma chamada dele que o browser faria, um new, ou o : base(…), o : this(…) ou a cláusula de base de um construtor que o twin escreve, é recusada, já que sem um ramo para ele a chamada rodaria outro construtor de dois argumentos (new Snap(info, context) rodava Snap(string, string)); o do template chama o da base, não é um ramo, e não faz chamada nenhuma (Desde 0.2.0-preview.61).
Dê ao construtor uma quantidade de argumentos só sua, ou encadeie-o num que faz o próprio trabalho. Uma factory estática (static Coded FromText(string text) => new(text.Length)) diz o mesmo sem um segundo construtor. Construa um objeto cujo construtor de serialização uma chamada alcança por outro dos seus construtores.
EQ2001–EQ2014 — o construto não atravessa
Não é lacuna: não há equivalente no browser, ou a tradução teria de ser um palpite. Estes não encolhem com trabalho no compilador — são o formato do alvo.
Código
Significado
O que fazer
EQ2001
Um construto C# sem equivalente em runtime no browser (intrínsecos de typed reference: __makeref, __reftype, __refvalue, stackalloc, ponteiros).
Reestruture sem ele.
EQ2002
goto.
Reestruture com laços e condicionais, ou um break/continue rotulado (esses TRADUZEM).
EQ2003
new T() sobre parâmetro de tipo — argumentos genéricos são apagados em runtime no JavaScript, então o tipo concreto é desconhecido.
Passe uma fábrica (Func<T>) ou o valor já construído.
EQ2004
Um membro sem tradução para JavaScript: um método de extensão cuja classe declarante não faz parte desta compilação, ou uma chamada que o transpilador não mapeia (Stopwatch.StartNew, Roslyn…) dentro de uma classe que ele espelha, escrita qualificada ou alcançada pelo nome simples por um using static (WriteLine sob using static System.Console, desde 0.2.0-preview.60). Também um valor System.Range guardado em vez de usado como índice, ou passado a um indexador que recebe o próprio Range (this[Range r], desde 0.2.0-preview.61).
Use um membro de instância ou traga o fonte declarante; adicione uma estratégia; para um intervalo, indexe com ele diretamente (text[a..b]), ou dê ao tipo um Length (ou um Count) e um Slice(int start, int length), que um intervalo chama; mova a chamada para trás de um [ServerAction]; ou, quando a classe inteira só roda no servidor, marque a CLASSE com [ServerOnly] e nenhum módulo é emitido para ela (0.2.0-preview.46).
EQ2005
Um iterador infinito. Iteradores são MATERIALIZADOS num array, então o laço rodaria para sempre em vez de render preguiçosamente.
Dê um fim ao laço (um limite, um yield break), ou consuma o que precisa dentro do método.
EQ2006
O membro não vincula no modelo semântico, então qualquer tradução seria palpite.
Ou o código não compila, ou faltam referências / fontes gerados ao eqc. Nunca é adivinhado — veja Compilador.
EQ2007
Um comparador que muda o que uma coleção considera igual ou em ordem: um argumento with(…) de collection expression além da dica de capacidade, ou um comparador passado ao construtor de uma coleção (new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase)) ou a um operador LINQ que acha as suas chaves ou os seus elementos por ele (ToHashSet, e ToDictionary, ToLookup, GroupBy e Distinct desde 0.2.0-preview.61). Uma lista, um set ou um dicionário acha um elemento pela igualdade padrão do seu tipo e não aceita outra: os comparadores padrão e o StringComparer.Ordinal passam. Uma ordenação ou uma busca binária aceita o comparador padrão do tipo, um Comparison<T>, os seis do StringComparer, Comparer<T>.Create e um comparador que você escreve, e recusa só um que nenhum twin carrega (um StringComparer feito para uma cultura, um comparador que uma biblioteca compilou).
Remova o comparador, ou normalize as chaves você mesmo (em minúsculas na entrada e em cada busca). Para uma ordenação, passe um Comparison<T>.
EQ2008
Query syntax com join, let, um segundo from ou into — a tradução em C# passa por identificadores transparentes gerados pelo compilador. Também as formas cercadas de inicializador.
Reescreva em method syntax, onde todo operador é suportado.
EQ2009
Um componente declarado mais de uma vez num arquivo (declarações parciais). O eqc emite um módulo por declaração e não sabe fundi-las.
Junte os membros numa declaração só.
EQ2010
Um símbolo que o framework mantém no HOST — um tipo ou um único membro marcado [ServerOnly] — nomeado a partir de código do cliente. O runtime não traz gêmeo, portanto a referência compilaria, seria emitida e falharia na hidratação com "does not provide an export named", enquanto o SSR continuava a responder 200. Um método de extensão chamado sobre um valor que atravessa também nomeia a casa dele: curve.Ease(t) é CurveEvaluator.Ease(curve, t), e falhava na chamada. Um tipo declarado dentro de um que nunca atravessa (uma classe [ServerOnly] ou um atributo) também não tem gêmeo, como o dono não tem, enquanto um declarado dentro de uma classe de exceção da app atravessa como essa classe, então código do cliente que o alcança é recusado da mesma forma, seja como for que o alcance: pelo nome, por um alias, por using static, por um operador ou uma conversão que o seu valor traz, ou por um zero. Um módulo que importaria o seu gêmeo o reporta na declaração que guarda a referência (Desde 0.2.0-preview.61). Um membro marcado [ServerOnly] é recusado onde quer que código do cliente o nomeie, inclusive o código do próprio tipo: um componente deixa um método assim fora do gêmeo, e o Build dele chamando-o era uma chamada a um membro que o gêmeo não tem (Desde 0.2.0-preview.62).
Chame-o de código de servidor: um [ServerAction], uma classe [ServerOnly] ou um realizador. Nunca do Build de um componente. Ao contrário do EQ2004, isto é uma DECISÃO e não uma lacuna — acrescentar uma estratégia não é a resposta.
EQ2011
Um membro que tomaria um nome que o componente do runtime já usa. O C# mantém separados um parâmetro de construtor primário, um campo e uma propriedade, e os escreve diferente do camelCase do runtime; o JavaScript dobra tudo isso em this.<nome>, então a atribuição substitui o membro do runtime e a página falha só no browser. A lista é lida do runtime vivo, nunca digitada.
Renomeie o membro. Um override é isento — o Build de um componente existe para substituir o build do runtime, e substituir membro de base é para isso que serve — mas um método comum não é: public void Mount() { } não sobrescreve nada e mesmo assim emite mount() por cima do do runtime, então o componente nunca monta.
EQ2012
Um [ServerAction] num componente ABSTRATO. O servidor registra uma ação sob o nome do componente CONCRETO que a carrega — ele pula os tipos abstratos e percorre os métodos herdados — então serve Tile/Load enquanto um stub emitido na base invocaria CardBase/Load. Nada serve esse id e a página recebe "action not found", em silêncio dos dois lados.
Declare a ação no componente concreto. Um alias não resolve: o descritor carrega o TIPO do componente em que invocar, então duas filhas herdando uma ação dão duas respostas ao id da base — quem é dono de uma ação herdada é uma decisão, não um remendo.
EQ2013
Um tipo do vocabulário cuja metade no browser revive os valores de um argumento de tipo (ServerTopic<T>) é construído onde esse argumento é, ou contém, um parâmetro de tipo, como em static ServerTopic<T> Topic<T>(string name) => new(name). O JavaScript apaga o tipo ali, então o tópico não levaria spec e todo payload chegaria aos assinantes sem ser revivido: um decimal ou um long como o texto que o fio escreve, um record sem os seus membros.
Construa o tópico onde o tipo do payload é concreto, como um membro estático do tipo que declara os tópicos do app: static ServerTopic<RoomEvent> Room(string id) => new($"room:{id}"). Veja Eventos do servidor.
EQ2014
Um tipo de exceção é construído ou testado onde um argumento de tipo que ele carrega, o seu ou o de um tipo em que está aninhado, é, ou contém, um parâmetro de tipo, como em static Exception Of<T>() => new Failed<T>(), catch (Failed<T>), ou new Missing() dentro da classe genérica que a declara. Uma exceção carrega os tipos que é, que um catch tipado, um is e o seu nome leem, e o JavaScript apaga um parâmetro de tipo, então a exceção carregaria, ou o teste compararia, o próprio T: catch (Failed<int>) não pegava o que Of<int>() lançava (Desde 0.2.0-preview.61).
Construa e teste uma exceção onde os seus argumentos de tipo são tipos concretos, e declare uma classe de exceção fora de um tipo genérico.
EQ2100–EQ2101 — templates resx
O contrato de localização, conferido na máquina de build em vez de quando um visitante chega.
Código
Significado
O que fazer
EQ2100
Sobre esta chamada: o template precisa ser um composite format válido cujos especificadores estejam dentro do subconjunto suportado, e a chamada precisa passar todos os buracos declarados.
Corrija a contagem de argumentos, ou tire o especificador fora do subconjunto (alinhamento como {0,10} está fora do v1).
EQ2101
Sobre as traduções: o resx de cada cultura é conferido contra o neutro, que é o contrato de aridade.
Corrija o template da cultura — um {n} a mais ou a menos quebra a build, não a página.
EQ2102–EQ2107, EQ2112, EQ2114 — a fronteira cliente/servidor
Um componente cliente buscou uma API que só existe num servidor, ou um valor que só o servidor tem. A ponte é [ServerAction].
Código
Significado
EQ2102
Acesso direto a banco (Microsoft.EntityFrameworkCore, System.Data).
EQ2103
Rede (System.Net.Http, System.Net.Sockets).
EQ2104
Threading e locking do SO (Thread, Monitor, Mutex, Semaphore — não Task).
EQ2105
Criação de processos (System.Diagnostics.Process).
EQ2106
Interop nativo / P-Invoke (System.Runtime.InteropServices).
EQ2107
Geração de IL em runtime (System.Reflection.Emit).
EQ2112
Acesso ao sistema de arquivos (System.IO).
EQ2114
Uma página usa um valor que o container do servidor lhe deu (um parâmetro de construtor de tipo classe, ou um membro onde a página o guarda) de um jeito que o build não consegue seguir: um método chamado nele, o valor passado onde o build não tem o fonte, convertido em texto, comparado, enumerado, guardado numa coleção, lido através de um membro que um tipo do .NET declara num valor que não atravessa inteiro (o Count de uma lista ou de um conjunto de objetos, o Value de um par), lido através de um tipo cujo membro com esse nome o tipo do próprio valor esconde (new), ou lido enquanto a página é construída. Um valor assim atravessa para o browser só como o que o browser lê dele, então um uso que o build não enxerga desenharia outra coisa lá. Reportado pelo source generator, então aparece no editor. Decida no servidor, no PrefetchAsync ou num membro [ServerOnly], e guarde o resultado num campo; ou chame uma [ServerAction] quando o estado do browser é uma entrada.
O EQ2114 chegou na 0.2.0-preview.60, quando um serviço que o container entrega a uma página deixou de atravessar inteiro (veja Integração com o servidor).
O EQ2112 fica separado da família de propósito: System.IO era reportado como EQ2101 até esse código se revelar pertencente à checagem de resx acima, que a wiki já publicava. Não é um deslize de numeração para arrumar de volta.
EQ2108–EQ2111 — um significado por alvo, ou nenhum
O construto traduz, mas seria LIDO de forma diferente no servidor e no browser. Em vez de escolher por você, o eqc pergunta.
Código
Significado
O que fazer
EQ2108
Um CultureInfo que o browser não consegue seguir: a formatação atravessa InvariantCulture e CurrentCulture, e a leitura de um número (Parse/TryParse de qualquer tipo numérico, Convert.ToInt32 e seus irmãos de uma string, Convert.ToDecimal de uma string ou de um valor que pode conter uma, como um object) só InvariantCulture. Convert.ToBoolean nunca consulta o seu provider, mas o C# o avalia, então ele atravessa InvariantCulture, CurrentCulture e um null, que são leituras sem efeito, e qualquer outro provider que a app escreva, enquanto outro CultureInfo (GetCultureInfo(name), new CultureInfo(name)), que pode lançar exceção, não tem twin para avaliá-lo. A cultura é a propriedade a que o provider se liga, seja qual for a grafia: um membro de outro tipo que também se chame InvariantCulture é recusado, porque pode retornar qualquer cultura.
Formate com especificador explícito (ToString("N2") segue a cultura da app nos dois alvos), ou converta e leia com a cultura invariante.
EQ2110
Um número lido de texto (ou de um valor que pode conter texto, como um object) sem cultura nenhuma: o C# lê na cultura da request ("1,5" é 1,5 em pt) e o browser na invariante. Um número escrito como texto não precisa de cultura: os dois alvos escrevem o texto da cultura.
Diga qual você quer: passe CultureInfo.InvariantCulture.
EQ2111
GetService sem argumento de tipo para atravessar — o registro é chaveado pelo NOME da interface, e aqui não há nada para chavear.
Chame a sobrecarga genérica.
EQ2113
O ConfigureAwait é descartado — só existe um contexto onde retomar — e descartá-lo jogaria fora um argumento NÃO-CONSTANTE sem avaliá-lo.
Passe uma constante, ou avalie a expressão numa variável local antes.
EQ3001–EQ3005 — o gerador de app Photon
Código
Significado
EQ3001
Uma app Photon sem programa.
EQ3002
Uma app Photon com mais de um programa.
EQ3003
A razão de uma capacidade precisa ser constante.
EQ3004
A chave de um entitlement precisa ser constante — ela é assinada no app em tempo de build, então uma chave construída em runtime nunca chega à assinatura.
EQ3005
Um fato do bundle precisa ser constante — o Info.plist é escrito em tempo de build, então um argumento construído em runtime nunca chega ao manifesto do app. Qualquer argumento conta, e seja o que for que o método receba: uma string, um bool, um AppCategory.
EQ3006
Um app Photon escreve o próprio entry point. O SDK gera um a partir do CreateApp, então um app que manteve o Main dele (ou as instruções de nível superior) tem dois — o que o compilador reporta como CS0017 contra um arquivo gerado que o app nunca viu. Apague o do app: o que ele fazia primeiro pertence ao CreateApp, que é a única metade que o Android roda.
EQ3101–EQ3105 — os source generators
A superfície de factories gerada e os modelos de formulário.
Código
Significado
EQ3101
Um componente elege mais de um construtor de factory ([UiFactory]).
EQ3102
Dois componentes dividem o mesmo nome.
EQ3103
Uma propriedade de form model tem tipo que nenhuma caixa de texto comporta.
EQ3104
Um atributo de validação sem regra em que virar.
EQ3105
Um [Compare] nomeia uma propriedade que este formulário não tem.
EQ4xxx — o build do SDK
Levantados pelos próprios targets MSBuild do SDK, antes ou depois de o compilador rodar.
Código
Significado
O que fazer
EQ4001
A ferramenta de ícones do eQuantic — eqicon, que escreve os ícones do app, o catálogo de vetores, o manifesto de capacidades e o bundle do macOS — está faltando onde o SDK a procura. Num build a partir da árvore de código do repositório, eQuantic.UI.Native.Build não foi construído antes deste projeto: um grafo de build quebrado. A partir de um pacote, o pacote saiu sem tools/net10.0/eqicon.dll.
Nenhum dos dois se resolve construindo duas vezes. A partir do código, a ferramenta é um ProjectReference de todo projeto de app, então olhe os erros acima deste — o build da própria ferramenta falhou — ou quem removeu a aresta. A partir de um pacote, limpe o cache do eQuantic (dotnet msbuild -t:ClearEQuanticCache), restaure de novo e reporte a versão do pacote se persistir.
EQ4002
O compilador do eQuantic — eqc, que transforma os componentes do app em JavaScript — está faltando onde o SDK o procura: num build a partir da árvore de código do repositório, eQuantic.Build não foi construído antes deste projeto; a partir de um pacote, o pacote saiu sem tools/net10.0/eqc.dll; ou um EqcCliPath explícito nomeia um arquivo que não existe. Isto costumava ser um aviso, e uma página sem JavaScript.
Como o EQ4001: não se resolve construindo duas vezes. A partir do código, leia os erros acima deste ou restaure o ProjectReference; a partir de um pacote, limpe o cache do eQuantic e restaure; com um EqcCliPath explícito, corrija o caminho.
EQ4003
(aviso) O app será assinado com uma exceção do hardened runtime (com.apple.security.cs.* — a família que relaxa uma proteção que o hardened runtime impõe) enquanto o build não é hardened. A chave chega à assinatura e o sistema nunca a consulta. O SDK assina com --options runtime apenas quando EQuanticHardenedRuntime é true, então qualquer outro valor não vazio é um build sem hardening — false, off e o erro de digitação ture igualmente — e a mensagem cita de volta o que foi escrito. Um valor VAZIO é um build de desenvolvimento comum e nunca é reportado.
Defina EQuanticHardenedRuntime=true, ou remova a declaração. Não EQuanticSigningIdentity: essa liga o hardening apenas onde a propriedade está vazia, então não responde a isto. Note o que isto NÃO significa: as permissões do App Sandbox (com.apple.security.network.*, …files.*, …device.*) respondem a PhotonEntitlements.AppSandbox, não ao hardened runtime, e um build de desenvolvimento ad-hoc as honra — por isso nunca são reportadas aqui.
EQ4004
Um programa que o build iniciou terminou com um código de saída diferente de zero e não reportou nenhum erro próprio: eqc, eqicon, o bun, o git ou, no macOS, codesign, ditto, notarytool, stapler ou hdiutil. A mensagem nomeia o programa e os argumentos com que ele foi iniciado, como o Exec do MSBuild nomeava seu comando, exceto numa chamada cuja linha de comando não é ecoada: a do notário, que carrega uma senha. Um programa que reportou seus próprios erros, os códigos EQ do eqc por exemplo, não recebe um EQ4004 depois deles.
Rode o comando que a mensagem nomeia, da pasta do projeto, para ver o que o programa diz. Um programa que nem está na máquina é o MSB6003 do próprio MSBuild.